pid_t s_pid;
s_pid = fork();
if(s_pid == ((pid_t)(-1))) {
/* ERROR: fork failed */
}
else if(s_pid == ((pid_t)0)) {
/* daemon main loop */
}
else {
/* 모든 자원을 반환하도록 구현 (종료시 기본적으로 자원이 반환되지 않는 자원들의 경우 반드시 필요) */
exit(EXIT_SUCCESS);
}
umask(0);
pid_t s_new_session_id;
s_new_session_id = setsid();
if(s_new_session_id == ((pid_t)(-1))) {
perror("create session and sets the process group id FAILED");
}
if(chdir("/") == (-1)) {
perror("could not change to root directory");
}
int s_fd_null;
for(;;) {
s_fd_null = open("/dev/null", O_RDWR | O_NOCTTY);
if(s_fd_null != (-1)) {
if(dup2(s_fd_null, STDIN_FILENO) == (-1)) {
perror("dup stdin failed");
}
if(dup2(s_fd_null, STDOUT_FILENO) == (-1)) {
perror("dup stdout failed");
}
if(dup2(s_fd_null, STDERR_FILENO) == (-1)) {
perror("dup stderr failed");
}
TEMP_FAILURE_RETRY(close(s_fd_null));
break;
}
if(errno == EINTR) { continue; }
perror("could not open null !");
break;
}
pid_t s_pid;
s_pid = daemon(0 /* nochdir */, 0 /* noclose */);
if(s_pid == ((pid_t)(-1))) {
perror("daemonize failed");
}
#define def_my_pidfile "/var/run/myprocessname.pid"
int main(...)
{
int s_pid_fd;
pid_t s_pid;
s_pid_fd = open_pidfile(def_my_pidfile);
if(s_pid_fd == (-1)) {
perror("could not create pidfile");
return(EXIT_FAILURE);
}
#if 0L
s_pid = daemon(0, 0);
if(s_pid == ((pid_t)(-1)) {
perror("daemonize failed");
remove_pidfile(s_pid_fd);
return(EXIT_FAILURE);
}
#else
s_pid = fork();
if(s_pid == ((pid_t)(-1))) {
perror("fork failed");
remove_pidfile(s_pid_fd);
return(EXIT_FAILURE);
}
else if(s_pid == ((pid_t)0)) {
/* daemon main loop */
}
else {
/* 모든 자원을 반환하도록 구현 (종료시 기본적으로 자원이 반환되지 않는 자원들의 경우 반드시 필요) */
close_pidfile(s_pid_fd);
exit(EXIT_SUCCESS);
}
(void)umask(0);
s_pid = setsid();
if(s_pid == ((pid_t)(-1))) {
perror("create session and sets the process group id FAILED");
}
/* if(nochdir == 0) */
if(chdir("/") == (-1)) {
perror("could not change to root directory");
}
/* if(noclose == 0) */
for(;;) {
int s_fd_null;
s_fd_null = open("/dev/null", O_RDWR | O_NOCTTY);
if(s_fd_null != (-1)) {
if(dup2(s_fd_null, STDIN_FILENO) == (-1)) {
perror("dup stdin failed");
}
if(dup2(s_fd_null, STDOUT_FILENO) == (-1)) {
perror("dup stdout failed");
}
if(dup2(s_fd_null, STDERR_FILENO) == (-1)) {
perror("dup stderr failed");
}
TEMP_FAILURE_RETRY(close(s_fd_null));
break;
}
if(errno == EINTR) { continue; }
perror("could not open null !");
break;
}
#endif
if(write_pidfile(s_pid_fd, s_pid) == (-1)) {
perror("could not write pidfile");
remove_pidfile(s_pid_fd);
exit(EXIT_FAILURE);
}
/* main-loop */
/* normal exit - daemon의 정상종료 */
remove_pidfile(s_pid_fd);
return(EXIT_SUCCESS);
}
#include <termios.h>
int flow_control(int s_fd, int s_ixon, int s_ixoff, int s_ixany)
{
struct termios s_termios;
if(tcgetattr(s_fd, (struct termios *)(&s_termios)) == (-1)) {
return(-1);
}
if(s_ixon == 0) {
s_termios.c_iflag &= (tcflag_t)(~(IXON));
}
else if(s_ixon != (-1)) {
s_termios.c_iflag |= (tcflag_t)(IXON);
}
if(s_ixoff == 0) {
s_termios.c_iflag &= (tcflag_t)(~(IXOFF));
}
else if(s_ixoff != (-1)) {
s_termios.c_iflag |= (tcflag_t)(IXOFF);
}
#if defined(IXANY) /* This is not POSIX : IXANY */
if(s_ixany == 0) {
s_termios.c_iflag &= (tcflag_t)(~(IXANY));
}
else if(s_ixany != (-1)) {
s_termios.c_iflag |= (tcflag_t)(IXANY);
}
#endif
if(tcsetattr(s_fd, TCSANOW, (struct termios *)(&s_termios)) == (-1)) {
return(-1);
}
return(0);
}
int main(...)
{
(void)flow_control(
STDIN_FILENO,
0 /* s_ixon */,
0 /* s_ixoff */,
0 /* s_ixany */
);
(void)flow_control(
STDOUT_FILENO,
0 /* s_ixon */,
0 /* s_ixoff */,
0 /* s_ixany */
);
(void)flow_control(
STDERR_FILENO,
0 /* s_ixon */,
0 /* s_ixoff */,
0 /* s_ixany */
);
/* ... */
}
make-zombie-source-20181106.tar.gz (1.19 KB)
pid_t s_pid;
s_pid = fork();
if(s_pid == ((pid_t)(-1))) {
perror("fork");
}
else if(s_pid == ((pid_t)0)) {
/*
자식프로세스는 종료.
그러나 이 자식프로세스는 부모프로세스로부터 Process ID 자원의 회수를 위한 처리(waitpid)가 되지 않으면 Zombit process 상태가 됩니다.
만약 부모프로세스가 waitpid호출없이 종료된다면 Process ID 자원의 회수는 init process 가 처리하게 됩니다.
*/
exit(0);
}
else {
printf("make a zombie process (pid=%ld)\n", (long)s_pid);
for(;;) { /* no waitpid call and forever exit */
sleep(10);
}
/* waitpid */
}
Daemon 만들때 알아둘 점
(http://cinsk.github.io/articles/daemon.html)
시그널의 모든것 (All about Linux signals)
(http://tdoodle.tistory.com/entry/%EC%8B%9C%EA%B7%B8%EB%84%90%EC%9D%98-%EB%AA%A8%EB%93%A0%EA%B2%83-All-about-Linux-signals)