Что находится в функции daemon()
? В частности, закрывает ли он открытые файлы, кроме стандартного ввода, стандартного вывода и стандартной ошибки? Если это так, то последующие операторы fprintf()
завершатся ошибкой, потому что файл, который был открыт до того, как вы вызвали daemon()
, впоследствии закрывается.
Если бы ваш код проверял возвращаемые значения из функций печати, вы могли бы это выяснить (хотя вам, вероятно, придется открыть файл журнала с абсолютным путем, чтобы иметь возможность сообщить об этом из демонизированного процесса).
Самый быстрый способ проверить эту гипотезу — открыть файл журнала после демонизации.
Обратите внимание, что некоторые подпрограммы daemon()
также меняют каталог - обычно в корневой каталог. Это вызовет у вас головную боль с относительным путем к файлу журнала.
В MacOS X функция daemon(3)
предоставляется с объявлением в <stdlib.h>
; он был представлен в BSD 4.4, кажется:
СИНТАКСИС
#include <stdlib.h>
int
daemon(int nochdir, int noclose);
ОПИСАНИЕ
Функция daemon() предназначена для программ, желающих отсоединиться от управляющего терминала и работать в фоновом режиме как системные демоны. [...]
Если аргумент nochdir не равен нулю, daemon() изменяет текущий рабочий каталог на корень (/).
Если аргумент noclose не равен нулю, daemon() будет перенаправлять стандартный ввод, стандартный вывод и стандартную ошибку в /dev/null.
Вы можете проверить Исходный код FreeBSD 8.
Поскольку вызов daemon()
дважды передает 0, код делает chdir("/")
и повторно подключает файловые дескрипторы 0, 1, 2 к '/dev/null'. Страница руководства продолжает обсуждение fork(2)
и setsid(2)
. Таким образом, мы можем быть умеренно уверены в том, что стандартные каналы ввода-вывода вашей программы переподключены к /dev/null, а текущий каталог изменен на корневой.
На справочной странице упоминается, что вы должны быть осторожны, чтобы все открытые файлы имели файловый дескриптор больше 2, чтобы избежать проблем. Можете ли вы где-нибудь напечатать 'fileno(f)' - это целое число - и убедиться, что оно больше 2. Если оно недостаточно велико, то это и есть причина вашей проблемы; не запускайте свою программу, если какой-либо из stdin, stdout или stderr уже закрыт.
Это еще не объясняет ни отсутствие данных в файле, ни то, почему sleep()
влияет на результат. Конечно, классическая реализация sleep()
возится с сигналами и SIGALRM; справочная страница для daemon(3)
упоминает SIGHUP. Однако реализация sleep(3)
во FreeBSD 8 использует системный вызов nanosleep(2)
.
Итак, я собираюсь согласиться с предложением Джея — файл будет полностью буферизован, и вам придется ждать большого количества 5-секундных циклов, чтобы напечатать достаточно данных для очистки буфера (для этого может потребоваться 4096 байтов при 6 байтах). за 5 секунд, потребуется около часа, чтобы создать что-либо в файле). Добавление fflush()
, скорее всего, решит проблему «неотображения сообщения». В качестве альтернативы используйте setvbuf(f, 0, _IONBF, 0);
, чтобы отключить всю буферизацию, или setvbuf(f, 0, _IOLBF, BUFSIZ);
, чтобы включить буферизацию строк. И sleep()
является фактором просто потому, что он сильно замедляет обработку.
01.09.2010