在已经重定向到 /dev/null 时重定向守护程序输出

redirecting daemon output when already redirected to /dev/null

我创建了一个程序,它可以选择作为守护进程启动,也可以选择将输出重定向到文件。一切都按预期工作,除非应用程序启动时它的输出已经定向到 /dev/null。这是一个问题,因为该应用程序正在由另一个应用程序启动,其中输出被重定向到 /dev/null.

像这样启动应用程序将按预期工作,并将所有输出写入文件。

./my_daemon -d -f/tmp/logfile

但是,像这样启动应用程序会创建日志文件,但它是空的。

./my_daemon -d -f/tmp/logfile &> /dev/null

节目是:

sintn main(sintn osn_argc, charn *opacn_argv[])
{
  sintn sn_i;
  charn *pcn_log_file = NULL;
  boolean q_daemonize;
  sintn sn_log_file = -1;
  pid_t t_pid = 0;
  pid_t t_sid = 0;

  printf("Enter Main\n");

  //check for parameters
  for (sn_i = 1; sn_i < osn_argc; sn_i++)
  {
     if (opacn_argv[sn_i][0] == '-')
     {
        switch(opacn_argv[sn_i][1])
        {
           case 'd':
           case 'D':
              q_daemonize = TRUE;
              break;

           case 'f':
           case 'F':
              pcn_log_file = &opacn_argv[sn_i][2];
              break;

           default:
              printf("Unknown parameter '%s'\n", opacn_argv[sn_i]);
        }
     }
  }

  if (q_daemonize == TRUE)
  {
     t_pid = fork();// fork a new child process

     if (t_pid < 0)
     {
        printf("Fork failed!\n");
        exit(1);
     }

     if (t_pid > 0)// its the parent process
     {
        printf("Forked: pid of child process %d \n", t_pid);
        exit(0); //terminate the parent process succesfully
     }

     umask(0);//unmasking the file mode

     t_sid = setsid();//set new session
     if(t_sid < 0)
     {
        exit(1);
     }

     close(STDIN_FILENO);

     if (pcn_log_file != NULL)
     {
        sn_log_file = open(pcn_log_file, O_CREAT | O_APPEND | O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO );
     }

     if (sn_log_file >= 0)
     {
        dup2(sn_log_file, STDOUT_FILENO);
        dup2(sn_log_file, STDERR_FILENO);
     }
     else
     {
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
     }
  }


  printf("Starting Application\n");
  v_BRIDGE_process();
  printf("Application Exit\n");

  printf("Exit Main\n");

  if (q_daemonize == TRUE)
  {
     if (sn_log_file >= 0)
     {
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        close(sn_log_file);
     }
  }

  return EXIT_SUCCESS;
}

在守护进程和执行 dup2 位并正确设置 stdoutstderr 之后,您 运行 进入这段代码:

if (q_daemonize == TRUE)
  {
     if (sn_log_file >= 0)
     {
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        close(sn_log_file);
     }
  }

它会立即关闭您非常小心地使用 dup2 附加到您的日志文件的文件描述符。

我假设这里的目的是清理。首先,您可以直接删除它,因为退出的进程会清理自己的 FD。其次,这导致了一个问题,因为你上面的 printf 语句不会被刷新到 stdout 的文件描述符,因为 stdio 被缓冲了。如果你 fflush stdout,它可能会工作,但更好的策略是简单地退出并让 stdio 自己的退出处理程序关闭文件。