|  | 
 | /* | 
 |  * Copyright (C) Igor Sysoev | 
 |  */ | 
 |  | 
 |  | 
 | #include <ngx_config.h> | 
 | #include <ngx_core.h> | 
 |  | 
 |  | 
 | ngx_int_t ngx_daemon(ngx_log_t *log) | 
 | { | 
 |     int  fd; | 
 |  | 
 |     switch (fork()) { | 
 |     case -1: | 
 |         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed"); | 
 |         return NGX_ERROR; | 
 |  | 
 |     case 0: | 
 |         break; | 
 |  | 
 |     default: | 
 |         exit(0); | 
 |     } | 
 |  | 
 |     ngx_pid = ngx_getpid(); | 
 |  | 
 |     if (setsid() == -1) { | 
 |         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed"); | 
 |         return NGX_ERROR; | 
 |     } | 
 |  | 
 |     umask(0); | 
 |  | 
 |     fd = open("/dev/null", O_RDWR); | 
 |     if (fd == -1) { | 
 |         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, | 
 |                       "open(\"/dev/null\") failed"); | 
 |         return NGX_ERROR; | 
 |     } | 
 |  | 
 |     if (dup2(fd, STDIN_FILENO) == -1) { | 
 |         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed"); | 
 |         return NGX_ERROR; | 
 |     } | 
 |  | 
 |     if (dup2(fd, STDOUT_FILENO) == -1) { | 
 |         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed"); | 
 |         return NGX_ERROR; | 
 |     } | 
 |  | 
 | #if 0 | 
 |     if (dup2(fd, STDERR_FILENO) == -1) { | 
 |         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed"); | 
 |         return NGX_ERROR; | 
 |     } | 
 | #endif | 
 |  | 
 |     if (fd > STDERR_FILENO) { | 
 |         if (close(fd) == -1) { | 
 |             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed"); | 
 |             return NGX_ERROR; | 
 |         } | 
 |     } | 
 |  | 
 |     return NGX_OK; | 
 | } |