2014-01-22 3 views
2

Итак ... Я запускаю другой процесс, который принимает некоторые данные из моей программы (это может пойти наоборот). Что-то в этом роде:Сделайте popen(), поместите указатель FILE * в поток, как насчет pclose()?

FILE *f(popen("sendmail", "w")); 

Теперь я могу положить п в fstream так что, как я могу просто использовать поток

(так как моя программа в C++, это, кажется, быть разумным, что нужно сделать.)
std::ofstream output(fileno(f)); 
... 
output << "To: [email protected]" << std::endl; 
... 

До настоящего момента я хороший. Теперь наступает момент, когда я закончил передачу данных в дочерний процесс. Все, что я хочу, это закрыть трубку. Из того, что я знаю, мы должны использовать pclose(), потому что эта функция гарантирует, что другой процесс получит все данные. В других словах функция pclose() знает, как очистить трубу.

К сожалению, поскольку я помещаю f в поток, я не могу просто закрыть его, не так ли?

pclose(f); // proper way to close a pipe 
... 
ofstream::~ofstream() { ... close(fd); ... } // not the right way to close a pipe 

Есть ли способ, чтобы захватить близко от ofstream и убедиться, что он закрывает, как я хочу, чтобы еь закрыт.

+1

Я полагаю, что это может помочь вам в некотором роде: http://stackoverflow.com/a/1105009/2428958 Кроме того, вы можете захотеть вывести streambuf и реализовать свой собственный класс потока вместо использования std :: ofstream в этом случае - поскольку вы не можете прикреплять к деструктору пользовательское «закрытие». –

+0

Тот же код, который открыл трубку, должен закрыть его. Я бы предложил связать трубу с классом, деструктор которого закрывает трубу. Вам не нужно захватывать закрытие - вы можете закрыть, когда объект будет уничтожен. –

+0

@ MateuszKołodziejski, Это идеальный ответ, можете ли вы написать реальный ответ? (хотя ссылка действительно не помогла, но вывод из streambuf - это то, что мне нужно сделать.) –

ответ

1

Я бы наследовать пользовательский класс от ofstream:

class PipeStream : public std::ofstream 

и перезаписать деструктор

PipeStream::~PipeStream { pclose(f) }; 

так что pclose (е) выполняется до fclose (е)?

+0

Это может быть проблемой, если вы хотите поймать вызов close(), и это не виртуально, не так ли? Поскольку std :: ofstream является шаблоном, я не уверен на 100%, как это работает, но я думаю, что это то же самое, что и обычные классы, поэтому кто-то, использующий только один из потоков, может вызвать неправильную функцию close() ... –