Skip to content
Advertisement

What happens after the execution of a handler function on the SIGCHLD signal in C?

I was wondering what exactly happens after the execution of a handler on a signal in C, more specifically on the SIGCHLD signal.

I’m actually building a shell and I need to do this:

  1. User enters a command with “&” as the last argument
  2. A new process is created with fork
  3. The parent process returns to the main function and wait for a new input from the user
  4. The child process executes in the background
  5. The child process ends and SIGCHLD is triggered
  6. The parent process handles the death of his child

My code do all of these points, but behaves in a strange way at the very end when the handler function returns.

My implementation

Main loop

JavaScript

User’s input processing

JavaScript

Built-in functions (cd and exit)

JavaScript

Link between signal and handler:

JavaScript

Handler:

JavaScript

The problem

My problem occurs when I call something like:

JavaScript

Then when the sudo command terminates (the handler is called and prints “Background job exited with code 0”), even though the command “cd ../” is already executed it gets executed again.

The ouput looks like:

JavaScript

Additional information:

cd is a builtin function which only does: chdir(path) with a path given, and the path is simply output with a printf("%s$",path) at the beginning of every loop in the main (after a command has been called).

The question

In order to understand what the real problem is, I believe that I should understand what happens at the end of my child_handler function.

If I’m at a certain point in the code with the main process, say waiting on the user input, and the background process dies, child_handler is called and then what? Does it change anything for the main process or is it still a the same point in the code, waiting for an input?

Thanks for you help.

Advertisement

Answer

As @ChrisDodd said, the problem was that a system call (fgets), was interrupted by the death of the background process and caused undefined behaviour.

Therefore, I solved my problem by adding the following flag to my handler:

JavaScript

As the documentation says it will:

Provide behavior compatible with BSD signal semantics by making certain system calls restartable across signals.

Thus no more issue with fgets.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement