In this program I change group id of child process.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void) {
int status;
char b[4];
pid_t pid, ch_pid;
switch(pid=fork()) {
case -1:
perror("Fork failed");
exit(1);
case 0:
printf("\nCHILD: This is child process!\n");
printf("CHILD: My PID is-- %d\n", getpid());
printf("CHILD: My parent PID -- %d\n", getppid());
printf("CHILD: My GID is -- %d\n", getpgid(getpid()));
printf("CHILD: My SID is -- %d\n", getsid(getpid()));
int k = setpgid(getpid(),getpid()); /*Modifies group id. Therefore, when user press
Cn+C, ChPr can't die*/
printf("BEFORE SETPGRP CHILD: My GID is -- %d\n", getpgid(getpid()));
printf("BEFORE SETPGRP CHILD: My SID is -- %d\n", getsid(getpid()));
//read(0,b,4);
//printf("b: %s\n",b);
pause();
exit(0);
default:
printf("PARENT: This is parent process!\n");
printf("PARENT: My PID -- %d\n", getpid());
printf("PARENT: My child PID %d\n",pid);
printf("PARENT: My parent PID %d\n",getppid());
printf("PARENT: My GID %d\n",getpgid(getpid()));
printf("PARENT: My SID %d\n",getsid(getpid()));
pause();
exit(0);
}
return 0;
}
But when I attempt to call "read" (commented strings), bash terminal doesn't read and doesn't output. However, parent process are reading successful. Why? Parent and child process have similar session ID. It's mean that they are controlled from common tty. I noted, if I change GID for child process and press Cntrl+C, parent process interrupted only and child process becomes an orphan. So, if I uncomment "read" in my program and press Cntrl+C it kills both process . May be unsuccessful read-call sends some signal to bash? Thank you!
The terminal has a foreground process group setting. When the shell runs commands, it runs foreground jobs in the terminal's foreground process group, but background jobs are put in their own process group. Only the foreground process group is allowed to read from the terminal. If a background process tries to read, it's suspended; when the user moves it to the foreground, the terminal process group is changed to that group, the process is resumed, and then it will be able to read. There's a stty
mode tostop
that can be used to control whether a background process can write to the terminal, but there's no similar option for reading, it's always prohibited.
If you want the process to be able to read from the terminal after you change its process group, you need to change the terminal's foreground process group. This is done using the tcsetpgrp()
function.
tcsetpgrp(0, getpgid(getpid()));