A child forked process in Linux inherits most of parent process attributes, such as file descriptors. Basically a child process basically represents a copy of the parent. setsid() function may help to break this inherency. “man 2 setsid” gives us the following information about this function:
setsid() creates a new session if the calling process is not a process group leader. The
calling process is the leader of the new session (i.e., its session ID is made the same as
its process ID). The calling process also becomes the process group leader of a new process
group in the session (i.e., its process group ID is made the same as its process ID).
The example below how code work without or with setsed:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void securetail(); int main(int n, char ** s) { pid_t pID = fork(); if (pID == 0) { if (n>1) { printf("PID[%d], setsid ret value: %d\n" , getpid(), setsid()); printf("Next printf after setsid\n"); } securetail(); } else { printf("Parend pID: %d, child PID: %d\n\n", getpid(), pID); securetail(); } return 0; } void securetail() { char cmd[] = "tail -f /var/log/secure"; FILE *fp = NULL; int pid = getpid(); fp = popen(cmd, "r"); if (fp != NULL) { int bufSize = 255; char *bufdata = (char *) malloc(bufSize); while (!feof(fp)) { memset(bufdata, 0, bufSize); fgets(bufdata, bufSize, fp); // if(strlen(bufdata) > 0) // printf("PID[%d]: %s\n", pid, bufdata); } delete[] bufdata; pclose(fp); } return; } |
Start program without arguments (setsid is not called), press ctrl/C and check how many processes are running:
# ./popen1 Parend pID: 1584233, child PID: 1584234 ^C |
ctrl/C terminate both parent and child processes.
Now Start program without with argument (setsid is called), after pressing ctrl/C and we see that child process continues to run:
# ./popen1 arg1 Parend pID: 1584535, child PID: 1584536 PID[1584536], setsid ret value: 1584536 |