Process Identification

Processes can be recognized by their Process Identification Number, commonly known as the PID. This is a unique positive integer number that is assigned to the process by the kernel. The system call getpid in C returns the PID associated with the calling process. Every process is also a child of another process. For example, when a user requests to run a program from a shell, the process generated by that program becomes a child of the shell. A process may obtain the PID of its parent process from the system call getppid.

For greater control, related processes belong to a group with a group id. Usually, a process inherits its group and group id from its parent process. However, the parent process may decide to assign a different group to its children. This is what usually happens with commands in shells. For example, if a shell creates a pipe of commands, like ls | sort, two processes are created, one for the ls command and another for the sort command, both with different PIDs. Because these processes are related by working in tandem, the shell makes them both part of a new group and designates the first process (ls) as the group leader. Its own PID also becomes the group id.

In a process, a system call getpgrp is used to obtain its own group id. To identify the group id for any other process, one may use the system call getpgid(pid), where the pid parameter contains the PID of the requested process.

A session is a set of process groups, all of which are assigned to the same session ID. The session ID is the PID of the process that created the session, known as the session leader. For example, when a shell starts running, it creates a session made out of a single group with a single process, the shell itself. This shell process is the session leader. Every command that runs later on the shell will belong to a group that may be different from the shell group, but they all inherit the same session ID, the session ID of the session leader. The system call getsid(pid) returns the session id of a process with the parameter pid. When this system call is given a pid of zero, it returns the session id of the calling process.

The following program demonstrates this concept,

id.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
  pid_t pid = getpid();
  pid_t ppid = getppid();
  pid_t pgrp = getpgrp();
  pid_t pgid = getpgid(ppid);
  pid_t sid = getsid(0);
  pid_t psid = getsid(ppid);

  printf("%-30s %d\n", "My Process ID: ", pid);
  printf("%-30s %d\n", "My Group ID:", pgrp);
  printf("%-30s %d\n", "My Parent Process ID:", ppid);
  printf("%-30s %d\n", "My Parent Group ID:", pgid);
  printf("%-30s %d\n", "My Session ID:", sid);
  printf("%-30s %d\n", "My Parent Session ID:", psid);

  printf("\nOutput of `ps':\n\n");
  fflush(stdout);

  system("ps --forest -o pid,pgrp,ppid,pgid,sid,cmd");
  return 0;
}
id output
My Process ID:                 66673
My Group ID:                   66673
My Parent Process ID:          56072
My Parent Group ID:            56072
My Session ID:                 56072
My Parent Session ID:          56072

Output of `ps':

    PID    PGRP    PPID    PGID     SID CMD
  56072   56072   56058   56072   56072 /bin/bash --posix
  66673   66673   56072   66673   56072  \_ ./id
  66674   66673   66673   66673   56072      \_ ps --forest -o pid,pgrp,ppid,pgid,sid,cmd

The output above also shows how the command ps can be used to display the ID of processes currently running by the shell. Notice that the process called id is made asleep in the background so the ps command can find it and display it. To view all processes in the system the ps -A command can be used.

A session also has a controlling terminal that is determined when the session is created. The terminal is where user interaction happens, where the user may enter commands through the standard input and see results from the standard output (if not redirected). A session may have control of just one terminal and a terminal may be controlled just by one session leader. Every process in the session is associated to the terminal, but only one process group is considered to be on the foreground. This means that this process group is the only one that is able to read messages from the standard input, namely to receive commands from the terminal. All other groups belonging to the same session are considered to be on the background.

The system call setpgid(pid, pgid) is used to change the group id of the process with the parameter pid to a value of pgid. This system call has the following characteristics:

  • If pid is zero, the change happens to the calling process.

  • If pgid is zero, the group id of the process with the parameter pid is changed to pid and becomes that group leader.

  • The parameter pid may only refer to the calling process itself or one of its children and it cannot be a session leader.

  • The calling process, as well as both processes on the parameters (pid and pgid) must belong to the same session.

Similarly, a session id for a process can also be changed with the system call setsid. A process other than the session leader can make this call that creates a separate session with a single group. The PID of this calling process becomes the group id and session id of the new group and the new session. However, this new session will have no controlling terminal.

Every process is also running at the bequest of a user. All users are assigned a user ID, or UID. A process may request the identity of its user with the getuid system call.The user must have the right to run the process either because it is the owner, or because it belongs to a group with the right to run that process or because that process is available for everyone to run.

On occasions, the owner of a program may grant its right to run it as a process to another user which cannot. To do that, the program must set its set-user-id and/or set-group-id bits. The following figure shows how this can be done and the effect it causes in the program. Notice in the figure how the privileges for identify are changed

$ ls -l identify
-rwxr-xr-x. 1 master master 17824 Jun 14 21:46 identify
$ chmod u+s identify
$ chmod g+s identify
$ ls -l identify
-rwsr-sr-x. 1 master master 17824 Jun 14 21:46 identify

If a user other than master, its owner, may run identify as a process, it will run as if it were the owner. To do that, the kernel uses what is called the effective user ID, or EUID and its associated effective group ID, or EGID instead of its own uid and gid. A process may identify its EUID and EGID with the geteuid and getegid system calls, respectively. To make multiple uses of this program, the EUID and EGID are stored as set-user-ID, or SUID, and the set-group-ID, or SGID.

We invite you to read more about credentials for process in the credentials page of the man pages.

The init Process

We mentioned that every process is a child of another process, for this to be possible, there must be a process that was the first. This process is known as the init process and it is created by the kernel when the operating system is at booting stage. This process is the first one to appear and it is the last one to go. It remains active from start-up to system shutdown. It cannot be destroyed, not even by a superuser, because it keeps control of other important processes that allow the correct running of the operating system. In particular it is in charge of taking care of “orphaned” processes as we will later see. Every process in the system is a descendant of init. The process ID for the init process is the number 1 and it has the highest privileges, as if it were run by the superuser.