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

John Kurlak picture John Kurlak · Mar 17, 2011 · Viewed 14.4k times · Source

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!

Answer

John Kurlak picture John Kurlak · Mar 17, 2011

Figured it out. I have to ignore any SIGTTOU signals.

I did that by adding:

signal(SIGTTOU, SIG_IGN);

Before the tcsetpgrp() call.