Что входит в функцию daemon()
?В частности, закрывает ли он открытые файлы, кроме стандартного ввода, стандартного вывода и стандартной ошибки?Если это так, то последующие операторы fprintf()
завершатся неудачно, поскольку файл, который был открыт до того, как вы вызвали daemon()
, впоследствии будет закрыт.
Если ваш код проверяет возвращаемые значения из функций печати, вы сможетевыясните это (хотя вам, вероятно, придется открыть файл журнала с абсолютным путем, чтобы иметь возможность сообщить об этом из демонизированного процесса).
Самый быстрый способ проверить эту гипотезу - открыть журналфайл после демонизации.
Обратите внимание, что некоторые подпрограммы daemon()
тоже меняют каталог - обычно на корневой каталог.Это вызвало бы головную боль при относительном пути к файлу журнала.
В MacOS X функция daemon(3)
снабжена объявлением в <stdlib.h>
;Кажется, он был представлен в BSD 4.4:
SYNOPSIS
#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.Однако реализация FreeBSD 8 sleep(3)
использует системный вызов nanosleep(2)
.
Итак, я согласен с предложением Джея - файл будет полностью буферизован, и вам придется ждать большогоколичество 5-секундных циклов для печати достаточного количества данных для очистки буфера (для этого может потребоваться 4096 байт, при 6 байтах за 5 секунд, потребуется около часа для создания чего-либо в файле).Добавление fflush()
, скорее всего, решит проблему отсутствия сообщения.Либо используйте setvbuf(f, 0, _IONBF, 0);
, чтобы отключить всю буферизацию, или setvbuf(f, 0, _IOLBF, BUFSIZ);
, чтобы включить буферизацию строки.И sleep()
является фактором просто потому, что он сильно замедляет обработку.