3

I'm reading Nginx Open Source and I wonder why would someone kill the parent process and let child process handle the rest of the program? Why not just let parent process handle it? Your help is very much appreciated.

I use Eclipse CDT to debug the program and this causes my debug come to a dead end since it continues debugging the parent process, not the child process (which actually handle the rest of program).

Here is a snippet of the code:

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);

    }
/* Do stuff*/
}

EDIT: I understand that procedure is for deamonizing a program but I'm still wondering why should we do that in the beginning?

Toan Tran
  • 476
  • 6
  • 28
  • 7
    It's a way to disconnect the daemon from the execution environment of the parent process. It's also a way to let the program continue run in the background while the user can continue working separately, which is not strictly needed in todays shells with background jobs, leaving only the first reason. – Some programmer dude Jun 01 '17 at 04:32
  • 2
    If you fork for every query, when you change the configuration you want to leave the fork finish their job and kill the parent to launch a new one with the new configuration – Ôrel Jun 01 '17 at 05:21
  • @Someprogrammerdude , thanks for your reply. However, Would you mind explaining why should we `disconnect the daemon from the execution environment of the parent process`? I've read about daemon in linux but I still haven't understood it clearly. Many thanks :) – Toan Tran Jun 01 '17 at 06:09
  • @Ôrel ah I see, It makes sense in the Nginx context now. – Toan Tran Jun 01 '17 at 06:10

1 Answers1

2

The main part of deamonizing a program is in disconnecting it from its controlling terminal.

To do that, you call setsid().

setsid() requires that the caller is not a process group leader (a process run directly from a shell with job control).

If you fork and then continue in the child, the child most definitely will not be a process group leader, which allows the setsid() call to succeed.

Afterwards, you should repeat the fork+exit procedure, to make sure the continuing grandchild is not a session leader either, ensuring it remains without a controlling terminal (a session leader (set by setsid()) has the ability to acquire a controlling terminal, perhaps even accidentally by opening a terminal file).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • So I assume that the purpose of deamonize a program is to make it stay running in the background and wait for requests. To do that, instead of using a loop in code, we deamonize it by `fork()` and `exit()` the parent process on every loop, is that correct? – Toan Tran Jun 01 '17 at 07:59
  • 2
    Deamonizing a program is really mainly just about disconnecting it from its controlling terminal. What the daemon does (whether it just prints hello world to a log and exits or whether it enters a server loop) is irrelevant to its deamon status (no controlling terminal + some other minor details). Check out https://stackoverflow.com/questions/3095566/linux-daemonize – Petr Skocik Jun 01 '17 at 08:43
  • Hi @PSkocik , I understand the procedure of deamonizing a program now. However, I'm still confused about the purpose of deamonizing it in the beginning. According to your reply, I assume that my 1st assumption was wrong. So why do we need to "disconnect a program from its controlling terminal"? – Toan Tran Jun 01 '17 at 09:17
  • 2
    @ToanTran That's a really good question. AFAIK, to prevent it from receiving SIGHUP when the original terminal dies. That could be also done by ignoring the SIGHUP signal, but deamons generally repurpose that signals to cause configuration to be reloaded. Also, controlling terminals get inherited and can be accessed via `/dev/tty`. Deamonization prevents that. – Petr Skocik Jun 01 '17 at 09:58
  • Hi @PSkocik, Just to clarify: - The daemons will receive SIGHUP even if we ignored it (which we don't want because we want the program keep running in the background) . =======> We need to: 1/deamonize current progress to prevent that, 2/replace current progress with its child progress. And we will do the same thing with child progress, replace it with grandchild procress next time and so on. Do I understand it correctly now? – Toan Tran Jun 01 '17 at 10:16