void goto_background(const char *prgname)
{
int i, maxfiles;
switch (fork())
{
default: //родительский процесс
exit(0);
case -1: //ошибка создания процесса
perror(prgname);
exit(1);
case 0: //порожденный процесс
setsid();
if ((maxfiles = sysconf(_SC_OPEN_MAX)) < 3) maxfiles = 3;
for (i = 0; i < maxfiles; i++) close(i);
chdir("/");
}
}
По завершении функции порожденный процесс не имеет управляющего
терминала и открытых файлов. Его рабочим каталогом является
корневой.
Описание по шагам:
1) Сначала вызовом fork(2) создается еще один процесс.
После этого родитель завершает работу.
Теперь юзер может продолжить работу с оболочкой.
2) Порожденный процесс вызовом setsid(2) становится лидером новой
группы и сеанса.
Он не имеет управляющего терминала.
При выходе юзера из системы процесс не получит SIGHUP.
3) Порожденный процесс вызовом close(2) закрывает все открытые
файлы.
Стандартные потоки ввода/вывода должны быть закрыты однозначно,
потому что они могут быть связаны с терминалом.
Для перестраховки в приведенном примере закрываются все файлы.
Максимальное количество открытых файлов возвращает sysconf(3).
4) Порожденный процесс вызовом chdir(2) изменяет свой рабочий
каталог на корневой.
Если этого не сделать, и текущий каталог является
подмонтированной файловой системой, то размонтировать ее не
удастся, пока не умрет данный демон.
anonymous (*) (2002-12-09 11:57:04.03):
> Как сделать так чтобы пограмма при запуске отправлялась в фон?
> Т.е. также как это делает wget с ключиком -b.
Никак не соберусь вякнуть ;)
Короче, wget с ключиком -b делает это несколько иначе, и - не совсем
корректно.
Понятие basckground/foreground в Юнихе относится к поведению процесса,
контролируемого оболочкой, по отношению к управляющему терминалу - все
это называется jobs control и несколько различается в разных Юнихах.
То, что описАл nobody (*) (2002-12-12 20:04:25.548), называется демоном -
он вообще не имеет управляющего терминала.
Полезность basckground процесса во многом определяется возможностью
сделать его foreground (командой fg из оболочки), что невозможно в случае
с wget -b, поэтому я употребил выражение "не совсем корректно". wget -b
просто передает себя init'у через fork, примерно, как
nobody (*) (2002-12-12 20:04:25.548) описАл, только безо всяких там setsid'ов.