I am trying to add a child process in the foreground process group. After forking I am calling execve()
to spawn a new process(In this case the unix echo program). Before calling execve()
i am creating a new process group using child's pid. So the child is becoming process leader of that process group. After that I am calling tcsetpgrp()
to add the process group in the foreground process group.
When I run the program it hangs in the tcsetpgrp()
call. execve()
never executes. If I remove tcsetpgrp()
call, execve()
executes successfully.
Can't understand why this is happening. Following is the code I wrote:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void pr_ids(char *name){
pid_t pid, ppid, pgid, tpgid;
pid = getpid();
ppid = getppid();
pgid = getpgrp();
tpgid = tcgetpgrp(STDIN_FILENO);
printf("%s: pid = %d ppid = %d"
" pgid = %d tpgid = %d\n", name, pid, ppid, pgid, tpgid);
}
int main(int argc, char *argv[]){
pid_t pid;
int st;
char *args[] = {"/bin/echo", "hello", NULL};
pr_ids("parent");
if((pid = fork()) == 0){
setpgid(0, 0); // creates its own process group and becomes group leader
pr_ids("child");
pid_t cpgrp = getpgrp();
tcsetpgrp(STDIN_FILENO, cpgrp); // add the process group to foreground
pr_ids("child");
execve(args[0], args, NULL);
}
else if(pid > 0){
waitpid(pid, &st, 0);
}
exit(0);
}
tcsetpgrp()
to work, the process group already have to be in the foreground process group then what'stcsetpgrp()
's purpose. What is its use case?Quoting from man "The function
tcsetpgrp()
makes the process group with process group ID pgrp the foreground process group on the terminal associated to fd, which must be the controlling terminal of the calling process"Isn't it saying that it makes a process group foreground process group? Also notices what is man page said about background processes, which is exactly what you said. Aren't these two statements ambiguous?
– Ashfaqur Rahaman May 21 '19 at 19:08tcsetpgrp()
can add any random group to fg group. Now I understood which it can but it have to be called from a process which is in fg group. In that case if I want to achieve something like when a new process spawns it will receive all the I/O and signal. Parent will sit in the background waiting for the child to finish. When the child is finished parent will be back in fg. What should be the procedures? – Ashfaqur Rahaman May 21 '19 at 20:42