LINUX.ORG.RU

[СИ] Стандартный ввод-вывод и автозапуск.

 


0

2

[СИ] Стандартный ввод-вывод и автозапуск.

Язык СИ ОС UNIX

Имеется маленькая стартовая программа предназначенная для авто-запуска
демонов при перезагрузке системы. Сама эта программа запускается
автоматически штатно (FReeBSD /usr/local/etc/rc.d/start.sh).

В обычных программах - не демонах, или демонах запущенных вручную, сначала
есть ввод-вывод. В программы-демоны я включаю такой кусок кода:
close(0);
close(1);
close(2);
При ручном запуске это помогает.
А как при автоматическом? Первое, что приходит в голову - должны бы быть
все три, направленные в никуда, для совместимости.


    Схема
    
программа "старт" (запускается вручную (для теста) или автоматически).
      ....
    if(pid==0){
        k=chdir("демон");
        execle("демон", argv, envp);
        exit(0);
    }
      ....
    
    
программа "демон" (запускается вручную, или автоматически программой "старт").
      ....
    fd=open("file");
      ....
    close(0);
    close(1);
    close(2);
      ....
    fd - должен остаться открытым.

Вопрос-1.
Есть ли у этой стартовой программы ввод-вывод, и если да,
то куда он направлен, и можно ли смело применить close, fclose в демонах?

Вопрос-2.
В демонах есть printf(«Text»); и т. п., которые полезны при ручном запуске
вплоть до демонизации. Куда денутся эти сообщения при автозапуске? Не повредят ли?

Вопрос-3.
Правильный ли close(0); и др., или правильнее опасный fclose(stdin); ?


man 3 freopen.

Суть: переоткрыть stdout и stderr на нужные файлы (типа, логи). stdin можно просто закрыть, если прога не планирует обрабатывать ввод. или создать именованную пайпу и переоткрыть на неё - будет типа контрольная пайпа для приложения.

Slavaz ★★★★★
()
Ответ на: комментарий от Slavaz

Правильно ли я понял, что все эти три есть, существуют?
Коль freopen, значит, должны существовать.
Перенаправлять мне не надо. Ошибки пуска и так дублируются в свои логи.
Мне бы желательно оставить всё как есть. Ввод вообще не используется.
Хорошо бы, чтоб вывод просто пропадал, ничего не повредив. И чтоб
в нужном месте закрыть все эти стандартные. Чтоб всё шло так, как
если бы обычный запуск из терминала.
И вот вопрос-3 еще. Интуитивно догадываюсь, что close вместо fclose
не освобождает память, занятую этими потоками.

oleg_2
() автор топика
Ответ на: комментарий от mi_estas

И пусковая программа и демоны - это Си-программы.
И там внутри них все действия сделаны средствами СИ.
sh-скрипт, упомянутый в теме, содержит единственную строку:
/usr/home/user/start/start.cgi start
Там больше ничего не надо.
«полезны при ручном запуске» - да. Проверяется корректность
настроек, доступность необходимых файлов и др.
При автозапуске не нужно, но всё равно в err-файл пишет Си-программа
(не через стандартные ввод-вывод).
Главный вопрос - точно ли есть там все эти три стандартных канала?
И куда уйдут сообщения? Мне эти сообщения вообще не нужны.
/usr/bin/daemon 2>&1 > /dev/null
Это, как я понимаю, в шелл-скрипте. А если не написать - что случится?

oleg_2
() автор топика
Ответ на: комментарий от oleg_2

Главный вопрос - точно ли есть там все эти три стандартных канала?

точно есть.

А если не написать - что случится?

ничего не случится.

mi_estas
()
Ответ на: комментарий от mi_estas

Спасибо.
Это и надеялся узнать.
А вопрос-3.
close(0); или fclose(stdin);
Работает и close(0);, но как правильнее?

oleg_2
() автор топика

1. Не определено. Если какие-то дексирпторы пре-определены - то это они получили их от парентного процесса. Если init, то, вроде, /dev/console открыт как 0, 1 и 2

2. Сообщения насрутся в дексриптор 1. Если он закрыт - то принтф это обрабатывает и возвращает что напечатал 0 символов. Но если твой демон открыл скажем сокет - то данные попадут туда

3. неправильно ни то ни то. Надо делать так:

int qwe=open("/dev/null", O_RDWR)
if (qwe==-1)
   goto error;
dup2(qwe,0);
dup2(qwe,1);
dup2(qwe,2);
if (qwe > 2)
  close(qwe);
принтф сам разберется. И да, в моём коде (на питоне правда) в качестве 1 и 2 используются пайпы. они ведут в другой (отфорканный) процесс который срёт в сислог.

mmarkk
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.