1

Consider the following situation:

  1. I use fork() to create a child process from my program
  2. Parent process receives the PID as 1234.
  3. Child process then calls execvp("myotherprogram", some_args);

myotherprogram is expected to run indefinitely until it receives SIGTERM (or higher), but, under some circumstances (e.g. missing file) it will just print an error and abort.

When the parent process receives an event, it wants to kill the child process again by calling:

const int kill_result = kill(1234, SIGTERM);

If myotherprogram exited early, is kill(1234, SIGTERM) going to be safe, or can the OS recycle the PID and I potentially kill a random process?

Karl Nicoll
  • 16,090
  • 3
  • 51
  • 65

1 Answers1

5

The PID can't be reused until the parent calls one of the wait functions to get its exit status; until this happens, the process stays around as a "zombie". So you should have a SIGCHLD handler that calls waitpid() to get the exit status. This handler should disable the code that calls kill(), since it no longer necessary and could kill a different process.

Make sure you're not ignoring SIGCHLD; this prevents zombies and causes the exiting process to disappear immediately.

Note that except for the root user, you can only kill processes that are under your same userid. So the chance that the PID will be reused by a process that you can kill is very low (unless your program runs as root).

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    One *could* have a `SIGCHLD` handler that calls `waitpid()` to get the exit status. But whether the OP in particular or anyone in general *should* do that is situational. In the OP's case in particular, doing so might well be counterproductive, as it would introduce exactly the risk they ask about: that the parent kills a process that it did not intend to kill on account of the intended target having already terminated and its pid having been recycled. – John Bollinger Feb 28 '23 at 16:38
  • 2
    That's why the handler has to disable the `kill()` code. The process has already exited, there's nothing to kill. – Barmar Feb 28 '23 at 16:41
  • Or, simpler, you just don't register such a handler in the first place, and let the zombie persist as a placeholder until the time comes to kill that process. If the number of such children is bounded by a small number, then the reduction in code complexity is probably worth it. Again, situational. – John Bollinger Feb 28 '23 at 16:45
  • Yeah, that's reasonable if they don't proliferate. Feel free to post as another answer. – Barmar Feb 28 '23 at 16:46
  • @JohnBollinger What will happen if the user does `kill -9 `? – Eugene Sh. Feb 28 '23 at 16:53
  • 1
    @EugeneSh. It stays a zombie. Try it and see. – Barmar Feb 28 '23 at 16:54
  • @Barmar Ok, so no way to get rid of the zombie without parent handling it. – Eugene Sh. Feb 28 '23 at 16:54
  • 1
    @EugeneSh. No, other than killing the parent. https://stackoverflow.com/questions/16944886/how-to-kill-zombie-process – Barmar Feb 28 '23 at 16:56
  • Awesome, exactly the information I was looking for. Thanks folks! – Karl Nicoll Feb 28 '23 at 18:28