11

My understanding is that in order to block a process signal like SIGHUP, you would need to do so from within the process the signal is being sent to. Yet, a Unix shell like bash can spawn a child process and block the HUP signal for the child from within the parent, using the nohup command. How does this work? Does nohup block the signal and then exec the child process without forking? That's the only way I can think of.

2 Answers 2

11

You can take a look at the source code of an implementation of nohup, e.g. GNU's coreutils version. There's a ton of setup, some of it for internationalisation purposes, the rest to handle the various redirection options; then the actual "nohupping" happens:

  signal (SIGHUP, SIG_IGN);

  char **cmd = argv + optind;
  execvp (*cmd, cmd);

As you surmise, this sets the process up to ignore the HUP signal, then execs the requested command.

12
  • Does that mean that child process inherits signal handler SIG_IGN from parent process? In the end it's the child process that does not exit on SIGHUP, not the nohup process. That was the question. Commented May 18, 2021 at 20:14
  • Maybe this is the answer: stackoverflow.com/a/14852834/815741. It says (in the comment): "The only thing special about signals is that non-default, non-ignore handlers are reset on execve & friends (because the handler's address makes no sense in a new executable), but nothing like this happens on fork" Commented May 18, 2021 at 20:20
  • @VytenisBivainis there’s no child process here, the signal handling is configured in the same process as the “nohupped” command – note the absence of fork between the calls to signal and exec. Ignored signals are preserved across exec, and SIGHUP is ignored here. Commented May 18, 2021 at 21:03
  • As to what the question was, it’s spelt out in the question: “Does nohup block the signal and then exec the child process without forking?” That’s exactly what happens. Commented May 18, 2021 at 21:04
  • 1
    @Vytenis nohup replaces itself with whatever it’s asked to run. Once it’s set the redirections up, and ignored SIGHUP, it has nothing to do apart from executing the command it’s been given; so it does that, without forking, and the kernel replaces it with the new executable, in the same process. As a result you won’t see nohup in ps’s output for example, just the command nohup has set up. Commented May 19, 2021 at 20:48
0

The act of using nohup simply changes the PPID of the spawned process to 1 (init) so that when the shell exits, it is no longer a child process of that shell and so therefor doesn't receive a HUP.

EDIT: Should think more before I post sometimes. Leaving it here to remind me of my shame :-(

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .