Need process group control. This is not so easy to find if you don't know that job control is implemented using process group control. The shell starts background processes in their own process groups and the bg
and fg
commands toggle which process group is allowed to read from the terminal. All other processes block reading from the terminal.
#include <unistd.h>
sleep(600); /* triggering condition goes here */
pid_t pgid = tcgetpgrp(0);
pid_t pid;
if ((pid = fork()) == 0) { /* Need to fork to safely create a new process group to bind to the terminal -- otherwise we might be in the same process group as we started in */
pid_t npid = getpid();
setpgid(npid, npid); /* create new process group and put us in it */
pid_t pid2;
if ((pid2 = fork() == 0) { /* what? another process */
setpgid(getpid(), pgid);
tcsetpgid(0, getpid()); /* set active process group */
_exit(0);
}
if (pid2 > 0) {
int junk;
waitpid(pid2, &junk, 0);
}
struct termios savedattr;
struct termios newattr;
tcgetattr(0, &savedattr);
newattr = savedattr;
newattr.c_lflag |= ICANON | ECHO;
tcsetattr(0, TCSANOW, &newattr); /* set sane terminal state */
printf("\nHi there. I'm the background process and I want some input:");
char buf[80];
fgets(buf, 80, stdin);
/* Do something with user input here */
tcsetattr(0, TCSANOW, &savedattr); /* restore terminal state */
tcsetpgrp(0, pgid); /* restore terminal owner -- only possible if the existing owner is a live process */
} else {
if (pid > 0) {
int junk;
waitpid(pid, &junk, 0);
}
}