daemon화 하는 펑션에 대해 질문할게요.

pooshap의 이미지

다음 과 같은 함수는 대몬화 하는 함수입니다.
int daemon_init(void)
{
pid_t pid;

if ( (pid = fork()) < 0)
return (-1);
else if (pid != 0)
exit(0); /* parent goes bye-bye */

/* child continues */
setsid(); /* become session leader */
chdir("."); /* change working directory */
umask(0); /* clear our file mode creation mask */

return (0);
}

함수가 이해가 안되는것이 아니고 왜 이렇게 하는지를 모르겠내요.
자세한 설명 부탁드릴게요.

익명 사용자의 이미지

잘 설명되져 있는데군여....

http://www.joinc.co.kr/modules.php?name=News&file=article&sid=24 :wink:

sangheon의 이미지

Quote:
DAEMON(3) Linux Programmer's Manual DAEMON(3)

NAME
daemon - run in the background

SYNOPSIS
#include <unistd.h>

int daemon(int nochdir, int noclose);

DESCRIPTION
The daemon() function is for programs wishing to detach themselves from
the controlling terminal and run in the background as system daemons.

Unless the argument nochdir is non-zero, daemon() changes the current
working directory to the root ("/").

Unless the argument noclose is non-zero, daemon() will redirect stan-
dard input, standard output and standard error to /dev/null.

RETURN VALUE
(This function forks, and if the fork() succeeds, the father does
_exit(0), so that further errors are seen by the child only.) On suc-
cess zero will be returned. If an error occurs, daemon() returns -1
and sets the global variable errno to any of the errors specified for
the library functions fork(2) and setsid(2).

SEE ALSO
fork(2), setsid(2)

NOTES
The glibc implementation can also return -1 when /dev/null exists but
is not a character device with the expected major and minor numbers. In
this case errno need not be set.

HISTORY
The daemon() function first appeared in BSD4.4.

BSD MANPAGE 1993-06-09 DAEMON(3)

--

Minimalist Programmer

Dr_stein의 이미지

fork()를 하는건 init의 차일드가 되면서, 또한 setsid()를 콜할때 자신이 세션
리더가 아닐수 있게 보장을 한다고 알고 있습니다.
setsid()를 하게 되면 새로운 세션을 만들고 그 세션의 리더가 되는데
그로 인해 현재 로긴한 쉘과다른 세션에 속하고 결국 터미널을 가지지 않게
됩니다.

여러가지 방법이 있을수 있지만, 데몬이 어떤거여야 하는가라는 필요에 의해
이런식으로 구현을 한다고 말할 수 있겠지요.

앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;

xfmulder의 이미지

일단 fork()해서 자신은 죽고 CHILD 를 남기는 이유는 init 의 자식이 되기 위해서이지요.
setsid() 함으로써 자신이 기존의 세션과 분리되면 제어 터미널을 잃습니다.
이때 getpgid() 하면 이전의 프로세스 그룹 으로부터도 독립되어 있게 됩니다.
참고로 프로세스와 관련된 id 는 네가지 입니다. pid, ppid, pgid(프로세스그룹), sid(세션ID) (getpid(), getppid() , getpgid() , getsid() 를 찾아보세요 )

세션id를 독립하면 자동으로 프로세스그룹ID(pgid) 도 sid 값으로 바뀝니다.
기존의 프로세스가 kill(0,SIGTERM); 하면 자신의 프로세스 그룹에 15번 시그널을 날리는데 이 데몬은 이미 프로세스그룹에서 독립했으므로 이 시그널 안받습니다. 물론 기존의 제어터미널에서도 독립했습니다.

chdir("/"); 하는건 현재디렉토리를 변경하는것. (자신이 로그를 기록할 적당한 디렉토리로 가도 됩니다. 상대PATH로 파일명 줄수 있음)

umask(0); umask 를 0 으로 했으므로 파일생성 모드 대로 생성됨.
(예를 들면 umask (022) 이면 파일을 rwxrwxrwx 로 생성해도 umask때문에
rwxr-xr-x 로 만들어 지게 됩니다)

내 자식들도 나처럼 !!