Search code examples
cprocesssignalsjobsforeground

How do I get tcsetpgrp() to work in C?


I'm trying to give a child process (via fork()) foreground access to the terminal.

After I fork(), I run the following code in the child process:

setpgid(0, 0);

And:

setpgid(child, child);

In the parent process.

This gives the child its own process group. The call to setpgid() works correctly.

Now I want to give the child access to the terminal.

I added the following to the child after the setpgid() call:

if (!tcsetpgrp(STDIN_FILENO, getpid())) {
    perror("tcsetpgrp failed");
}

After that, there is an execv() command to spawn /usr/bin/nano.

However, instead of having nano come up, nothing happens, and the terminal looks as if it's expecting user input.

Further, no code seems to execute after the tcsetpgrp() call.

I read somewhere that I need to send a SIGCONT signal to the child process to get it to work. If the process is stopped, how can I do that? Does the parent have to send the signal?

How do I go about sending the SIGCONT signal if that is the solution?

raise(SIGCONT);

Also, I'm not sure if this helps, but the code works fine and spawns nano if I run my program with:

exec ./program

Instead of:

./program

Any ideas? Thanks so much!


Solution

  • man 3 tcsetpgrp states:

    If tcsetpgrp() is called by a member of a background process group in its session, and the calling process is not blocking or ignoring SIGTTOU, a SIGTTOU signal is sent to all members of this background process group.

    You need to call tcsetpgrp() in your parent process not in child. However if your parent process started and moved into background it will receive SIGTTOU and will be stopped.