C/Daemonize
From Attie's Wiki
(Difference between revisions)
m |
m |
||
Line 1: | Line 1: | ||
<source lang="c"> | <source lang="c"> | ||
− | int pipefd | + | int pipefd; |
+ | /* call this function to deamonize */ | ||
int daemonize(void) { | int daemonize(void) { | ||
+ | int pipefds[2]; | ||
int i; | int i; | ||
+ | unsigned char c; | ||
− | if (pipe( | + | if (pipe(pipefds) == -1) { |
perror("pipe()"); | perror("pipe()"); | ||
return 1; | return 1; | ||
Line 16: | Line 19: | ||
} | } | ||
if (i > 0) { | if (i > 0) { | ||
− | + | close(pipefds[1]); | |
− | close( | + | if (read(pipefds[0],&c,1) <= 0) { |
− | + | ||
− | if (read( | + | |
printf("An error occured, unable to determine if started successfully...\n"); | printf("An error occured, unable to determine if started successfully...\n"); | ||
exit(1); | exit(1); | ||
} | } | ||
− | if (c) { | + | if (c == 1) { |
printf("An error occured while starting...\n"); | printf("An error occured while starting...\n"); | ||
+ | exit(1); | ||
+ | } else if (c == 2) { | ||
+ | printf("An error occured while deamonizing...\n"); | ||
+ | return 2; | ||
+ | } else { | ||
+ | printf("An unknown return status was given (%d)...\n", c); | ||
exit(1); | exit(1); | ||
} | } | ||
Line 31: | Line 38: | ||
} | } | ||
− | close( | + | close(pipefds[0]); |
+ | pipefd = pipefds[1]; | ||
if (setsid() < 0) { | if (setsid() < 0) { | ||
perror("setsid()"); | perror("setsid()"); | ||
− | + | goto killChild; | |
} | } | ||
Line 42: | Line 50: | ||
if ((chdir("/")) < 0) { | if ((chdir("/")) < 0) { | ||
perror("chdir()"); | perror("chdir()"); | ||
− | + | goto killChild; | |
} | } | ||
return 0; | return 0; | ||
+ | |||
+ | killChild: | ||
+ | c = 2; | ||
+ | write(pipefds[1],&c,2); | ||
+ | close(pipefds[1]); | ||
+ | exit(1); | ||
} | } | ||
+ | /* call this to indicate success, and detach from the terminal */ | ||
void daemonize_success(void) { | void daemonize_success(void) { | ||
int i; | int i; | ||
Line 64: | Line 79: | ||
i = 0; | i = 0; | ||
− | write(pipefd | + | write(pipefd,&i,1); |
− | close(pipefd | + | close(pipefd); |
} | } | ||
+ | /* call this to indicate failure in the parent... you must still kill yourself - try exit(1) */ | ||
void daemonize_failure(void) { | void daemonize_failure(void) { | ||
− | + | unsigned char c; | |
− | + | c = 1; | |
− | write(pipefd | + | write(pipefd,&c,1); |
− | close(pipefd | + | close(pipefd); |
} | } | ||
</source> | </source> |
Revision as of 17:16, 15 March 2012
int pipefd; /* call this function to deamonize */ int daemonize(void) { int pipefds[2]; int i; unsigned char c; if (pipe(pipefds) == -1) { perror("pipe()"); return 1; } i = fork(); if (i < 0) { perror("fork()"); return 1; } if (i > 0) { close(pipefds[1]); if (read(pipefds[0],&c,1) <= 0) { printf("An error occured, unable to determine if started successfully...\n"); exit(1); } if (c == 1) { printf("An error occured while starting...\n"); exit(1); } else if (c == 2) { printf("An error occured while deamonizing...\n"); return 2; } else { printf("An unknown return status was given (%d)...\n", c); exit(1); } printf("Started successfully!\n"); exit(0); } close(pipefds[0]); pipefd = pipefds[1]; if (setsid() < 0) { perror("setsid()"); goto killChild; } umask(0); if ((chdir("/")) < 0) { perror("chdir()"); goto killChild; } return 0; killChild: c = 2; write(pipefds[1],&c,2); close(pipefds[1]); exit(1); } /* call this to indicate success, and detach from the terminal */ void daemonize_success(void) { int i; i = open("/dev/null",O_RDWR); if (i < 0) { close(fileno(stderr)); close(fileno(stdout)); close(fileno(stdin)); } else { dup2(i,fileno(stderr)); /* 2 = stderr */ dup2(i,fileno(stdout)); /* 1 = stdout */ dup2(i,fileno(stdin)); /* 0 = stdin */ close(i); } i = 0; write(pipefd,&i,1); close(pipefd); } /* call this to indicate failure in the parent... you must still kill yourself - try exit(1) */ void daemonize_failure(void) { unsigned char c; c = 1; write(pipefd,&c,1); close(pipefd); }