2013-08-19 4 views
6

Несколько месяцев назад я пишу приложение CGI для Linux, которое использует popen() для чтения вывода команды, а затем я закрываю трубку с помощью fclose().Использование fclose для трубы попена является серьезной ошибкой?

Теперь я читал, что для закрытых труб необходимо использовать pclose().

Руководство говорит:

Возвращаемое значение popen() нормальный поток стандартный I/O во всех отношениях кроме того, что она должна быть закрыта с pclose(), а не fclose(3).

Мой код выглядит так:

if ((NULL != (f = popen(command.value, "r")))) { 
    //do something 
    fclose(f); 
} 

Мой вопрос:

Моя ошибка есть проблемы безопасности? Эта программа в настоящее время находится в производстве. В тестах это ничего не делает. Действительно необходимо, исправить его, используя pclose() вместо fclose()? Примечание. Я только открываю PIPE один раз в программе.

Сегодня, в моем местном доме, я делаю некоторые испытания и fclose() и pclose() не возвращает EOF, указывающий сбой.

+2

Вы Неопределенное поведение : Прочитайте ['pclose()' vs 'fclose()'?] (Http://cboard.cprogramming.com/cplusplus-programming/97147-pclose-vs-fclose.html): Функция '_pclose' просматривает ИД процесса командного процессора (CMD.EXE), запущенный связанным вызовом '_popen', выполняет вызов' _cwait' в новом командном процессоре и закрывает поток на связанном канале. ' –

+0

. Есть несколько сообщений SO, связанных с вашим вопросом: 1. [' fclose ()/pclose() 'может блокировать некоторые указатели на файлы] (http://stackoverflow.com/questions/1736983/fclose-pclose-may-block-on-some-file-pointers) и [Как закрыть дескриптор трубы в unix ? '(fclose() of pclose())'?] (http://stackoverflow.com/questions/5548364/how-close-pipe-handle-in-unix-fclose-of-pclose) –

+0

спасибо, я исправлю потому что это действительно важно. Теперь я смотрю на удар. – carlos

ответ

5

Если вы используете fclose на трубе, у вас будет утечка дескриптора файла, так как fclose не освободит указатель файла в ядре (который создается при создании канала с момента его создания).

Пока ваше тестирование пока не показало каких-либо проблем, запустите программу 3000 раз (или как можно разрешить многие файловые дескрипторы, по сравнению с встроенным ядром) и наблюдайте, когда вы больше не сможете создавать каналы ,

+2

Обычно 'fclose' на потоке stdio фактически * делает * закрывает базовый дескриптор канала (он заключен в' fp -> _ fileno' или как бы там ни называлось поле), поэтому это скорее утечка зомби-proc, чем утечка fd. – torek

10

Согласно this thread, с использованием fclose вместо pclose означает, что процесс на другом конце трубы не получает, поэтому он остается зомбированным.

+0

очень спасибо, тогда я не закрываю трубку, это плохо, спасибо. – carlos

0

Я только что узнал (через 10 лет), что я ошибочно использовал fclose для некоторых popen звонков, работающих на серверах Windows 2008. Он работал (т. Е. Не разбился), и я все равно не интересовался кодом возврата на эти вызовы.

Но мне нужен код возврата последних popen поток, а закрытие было сделано правильно с pclose.

Это странный эффект возврата кода ошибки 0 (возможно, сбор кода возврата ранее не pclosed), даже если команда не удалась, создав очень странную ошибку в коде, что могло привести к катастрофическим ошибкам потому что вызывающий считает, что команда работала.

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

+0

BTW, это очень специфичная операционная система. OP явно задал вопрос о Linux. И в обычных дистрибутивах Linux есть свободное программное обеспечение libc, поэтому OP должен изучить исходный код его конкретной реализации libc. –

+0

ОК, но то, что случилось со мной в окнах, могло случиться и на других системах. –

+0

За исключением того, что аспект бесплатного программного обеспечения сильно меняется, как решить эту проблему. Если ваш libc (и ядро) был свободным программным обеспечением, вы могли бы изучить и изучить его исходный код (и понять, что происходит). –