демон: закрыть stderr и принять(2)

Я написал демон TCP, который принимает клиентские соединения на указанный порт и после этого выполняет команду, используя execv(3). В каждом руководстве по написанию демонов упоминается закрытие stdin, stdout, stderr для успешной демонизации процесса.

Однако я обнаружил, что accept(2) повторно использует номера файловых дескрипторов уже закрытых stdout/stderr, поэтому после вызова fork(2) и execv(3) дочерний процесс записывает вывод в сокет просто потому, что stdout/stderr сопоставляется с файловым дескриптором, теперь связанным с клиентский сокет.

Любые идеи, как я могу избежать этого, не прибегая к перенаправлению вывода оболочки?


person antagon    schedule 09.05.2015    source источник


Ответы (2)


Все!

Если вы не хотите, чтобы файловые дескрипторы для стандартного ввода/вывода повторно использовались accept(2) и, предположительно, любой другой функцией, которая возвращает новый файловый дескриптор, не вызывайте для них close(2)/fclose(3), а перенаправляйте их вместо этого в /dev/null (если доступно). Эта идея исходит из справочной страницы для daemon(3).

freopen ("/dev/null", "r", stdin);
freopen ("/dev/null", "w", stdout);
freopen ("/dev/null", "w", stderr);
person antagon    schedule 10.05.2015

Во-первых, для процесса демона необходимо выйти из его родителя, поэтому он будет перенаправлен в процесс INIT и станет демоном.

Я думаю, что ваш вариант использования: вы получаете команду от других клиентов и выполняете ее в своем демоне, а затем перенаправляете вывод запрашивающему клиенту. Если вы планируете использовать концепцию закрытия STD_ERR и STD_OUT, вам нужно быть осторожным, чтобы получать запросы только последовательно.

Теперь перейдем к вашей проблеме. Чтобы перенаправить STD_ERR и STD_OUT на принятый клиентский FD, вы должны держать STD_ERR и STD_OUT открытыми до тех пор, пока клиент не будет принят, после принятия только клиента, закрыть STD_OUT, а затем использовать DUP с принятым клиент ФД.

обратитесь к ссылке ниже, чтобы получить больше информации об этом виде проблемы. в практических примерах используется dup или dup2

person Pratrick    schedule 09.05.2015