[cs631apue] questions for our last class

Jan Schaumann jschauma at stevens.edu
Tue Dec 3 10:45:31 EST 2019


Elliot Wasem <ewasem at stevens.edu> wrote:

> When a child process creates its own session, it
> becomes its own session leader, disconnects from
> parent terminal, and becomes ownership of... the
> user owning the initial parent process? init?
> Additionally, can the parent then listen for the
> child to exit using waitpid() still?

The best way to answer such questions is of course to
write yourself a program to see what happens:

----
#include <sys/wait.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main(int argc, char **argv) {
	pid_t p;
	int status;

	if ((p = fork()) < 0) {
		fprintf(stderr, "Unable to fork: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
		/* NOTREACHED */
	} else if (p == 0) {
		if ((p = setsid()) < 0) {
			fprintf(stderr, "Child %d failed to setsid(2): %s\n",
						getpid(), strerror(errno));
			exit(EXIT_FAILURE);
			/* NOTREACHED */
		}
		pause();
	} else {
		printf("Parent %d waiting for my child with pid %d...\n", getpid(), p);
		if (wait(&status) < 0) {
			fprintf(stderr, "Failed to wait: %s\n", strerror(errno));
			exit(EXIT_FAILURE);
			/* NOTREACHED */
		}
		if (WIFSIGNALED(status)) {
			printf("Child %d terminated after receiving signal %d.\n",
				p, WTERMSIG(status));
		}
	}
}
----

Run this program and you should see output like this:

$ ./a.out
Parent 1075 waiting for my child with pid 841...

Now PID 1075 is waiting.  In another terminal window,
run:

$ ps -xo pid,ppid,pgid,sess,command
 PID PPID PGID   SESS COMMAND
 144  145  145 10ef90 sshd: jschauma at pts/0 (sshd)
 488 1158 1158 df3b28 sshd: jschauma at pts/1 (sshd)
 841 1075  841 df3888 ./a.out 
 991  144  991 10ecf0 -sh 
1075  991 1075 10ecf0 ./a.out 
 692  919  692  34000 ps -xo pid,ppid,pgid,sess,command 
 919  488  919  34000 -sh 
$ 

Here, you see the parent process 1075 with the
interactive shell PID 991 with the parent SSH process
PID 144; the shell and the command it runs (a.out with
the parent curently waiting) are in the same session
(10ecf0).

You also see the second interactive shell (PID 919)
from which you are running the ps(1) command (PID
692), both of which are in session 34000.

The other a.out process (PID 841) is the child, which
called setsid(2) and is now suspended waiting for a
signal.  PID 841 has PGID 841 (and thus is process
group leader of PGID 841) and session ID df3888 --
the only process in this session, as promised by
setsid(2).

That is, the child process did exactly as promised:
- created a new session (df3888)
- created a new process group (841) that it is a
  leader of
- detached from the controlling terminal

As you can tell, the parent process can still wait(2)
for the child, so go ahead and send a signal to it:

$ kill -USR1 841
$ 

In the other terminal window where your parent was
still waiting, you should now see:

$ ./a.out
Parent 1075 waiting for my child with pid 841...
Child 841 terminated after receiving signal 30.
$ 

As you can also tell from inspection of the processes
above, the detached a.out session is still running
with the privileges of the user invoking the initial
command.  Any change in that would require a call to
setuid(2)/seteuid(2) and would require super-user
privileges.  Allowing a regular user to change EUID
simply by calling setsid(2) would probably not be a
good idea for overall system security...

-Jan


More information about the cs631apue mailing list