Como executar um comando e obter o código de retorno stdout e stderr do comando em C ++

Dada a seguinte resposta (primeira resposta c ++ 11):

Como executar um comando e obter saída de comando no C ++ usando POSIX?

Aqui está a implementação para sua conveniência:

#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>

std::string exec(const char* cmd) {
    std::array<char, 128> buffer;
    std::string result;
    std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
    if (!pipe) throw std::runtime_error("popen() failed!");
    while (!feof(pipe.get())) {
        if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
            result += buffer.data();
    }
    return result;
}

Isso funciona muito bem para executar um comando (por exemplo,std::string res = exec("ls");) e coloque o stdout em uma string.

Mas o que ele não faz é obter o código de retorno do comando (número inteiro aprovado / reprovado) ou o stderr. Idealmente, eu gostaria de uma maneira de obter todos os três (código de retorno, stdout, stderr).

Eu aceitaria stdout e stderr. Eu estou pensando que eu preciso adicionar outro canal, mas não consigo ver como o primeiro canal está configurado para ficar stdout, então não consigo pensar em como alterá-lo para obter os dois.

Alguém tem alguma idéia de como fazer isso, ou abordagens alternativas que podem funcionar?

atualizar

Veja meu exemplo completoaqui com a saída:

Start
1 res: /home

2 res: stdout

stderr
3 res: 
End

Você pode ver isso3 res: não imprime stderr da mesma maneira que2 res: stdout mas stderr é despejado na tela em uma linha separada pelo processo (e não pelo meu programa).

Libs externos

Eu realmente não quero usar bibliotecas externas como Qt e boost - principalmente porque quero a portabilidade e também muitos projetos nos quais trabalho não usam o boost. No entanto, marcarei soluções que contêm essas opções, pois são válidas para outros usuários :)

Solução completa usando comentários / resposta

Obrigado a todos por suas respostas / comentários, aqui está a solução modificada (e executável):

solução de trabalho

questionAnswers(3)

yourAnswerToTheQuestion