yash-rs icon indicating copy to clipboard operation
yash-rs copied to clipboard

Allocating a unique process group ID for a job-control shell

Open magicant opened this issue 8 months ago • 0 comments
trafficstars

POSIX.1-2024 job control specifications require the job-control shell to become a process group leader:

if it has a controlling terminal, it shall initially perform the following steps if interactive and may perform them if non-interactive:

  1. If its process group is the foreground process group associated with the terminal, the shell shall set its process group ID to its process ID (if they are not already equal) and set the foreground process group ID associated with the terminal to its process group ID.

This requirement only mentions the initial state of the shell. We should also consider the following cases:

  • If the shell is started with job control disabled and it is enabled later, the shell becomes a process group leader then.
  • Conversely, if job control gets disabled later, the shell resets the process group ID to the original value. This is needed so that the SIGTSTP signal generated by the terminal is sent to the whole process group to which the shell belonged before it became a process group leader.
  • When the suspend built-in (which is not yet implemented) is invoked, the process group ID is temporarily reset to the original value before the shell is suspended and restored when the shell is resumed. This is needed so that the built-in can stop the whole process group to which the shell belonged before it became a process group leader.

Becoming a process group leader makes sure that, when the user hits the suspend key sequence (typically Ctrl-Z), only the shell process receives the SIGTSTP signal, effectively nullifying the signal. If the signal were sent to the original process group, the other processes in the group would also receive the signal and be stopped. This is not desirable because the parent shell may incorrectly consider the job as stopped or the shell may not be able to interact with the other processes in the group.

However, leaving the original process group also has a drawback. If the shell is piped to another command, the command process is left in the background. If the command needs to interact with the terminal, it may receive SIGTTOU or SIGTTIN signals and be stopped. This is not desirable either.

It may be a good compromise to change the process group ID only if the shell's standard input is the terminal. In this case, it is likely that the shell is the only process reading from the terminal, so no other process will try to read from the terminal and be stopped by SIGTTIN. Otherwise, the shell is likely to be piped to another command, so it is better to leave the process group ID unchanged.

In all cases above, the process group ID change only matters when the shell is initially not a process group leader. The shell has to do nothing when it is already a process group leader, which is quite often the case in practice.

magicant avatar Mar 12 '25 13:03 magicant