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

时间:2015-01-30 19:31:53

标签: c linux daemon io-redirection

我创建了一个程序,可以选择作为守护程序启动,以及将输出重定向到文件的选项。一切都按预期工作,除非应用程序启动它的输出已经定向到/ 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;
}

1 个答案:

答案 0 :(得分:1)

在进行守护并执行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自己的退出处理程序关闭文件。