无法在C中向子进程发送信号

JKo*_*sin 5 c signals background

我一直试图弄清楚这是否可行,就像我做的那样.该程序应该派生一个循环打印到STDOUT的子进程,父进程应退出以返回终端提示符.然后孩子应该等待SIGINT告诉它什么时候关闭.但是我记得读过SIGINT只发送到前台的进程,这解释了为什么我的被遗弃的孩子不受CTRL + C的影响.有没有办法让被遗弃的孩子接收从终端发送的信号,或者终端中的某些系统调用将它带到可以接收SIGINT的前台?或者我的搜索无望?

码:

#include  <stdio.h>
#include  <unistd.h>
#include  <stdlib.h>
#include  <signal.h>
#include  <sys/wait.h>
#include  <sys/types.h>

/* signal handler for the child process */
void catchInt (int signum)
{
 printf("\nMy sincerest apologies, master\n");
    exit(0);
}

/* signal handler for the parent process */
void ignoreInt (int signum)
{
 /* prevent any extra output from being printed */
 fflush(stdout); 
 /* wait for child to apologize before replying */
 wait(NULL);
 printf("You're welcome\n");
 exit(0);
}

/* signal handler for the child's alarm */
void catchAlarm (int signum)
{
 printf("It's great to be alive\n");
 /* reset the alarm */
 signal(SIGALRM, catchAlarm);
 alarm(3);
}

int main () {

 pid_t  pid;

 /* fork process */
 pid = fork();
 if (pid < 0) /* error handler */ 
 {   
  fprintf(stderr, "Fork Failed");
  exit(-1);
 }

 /* child */
 else if (pid == 0) 
 { 
  printf("It's great to be alive\n");
  /* catch SIGINT and handle as the child should */
  signal(SIGINT, catchInt);
  /* catch SIGALRM being sent by alarm() */
  signal(SIGALRM, catchAlarm);
  /* set alarm for 3 seconds */
  alarm(3);
  for ( ;; )
  {
   printf("I have 42001 children and not one comes to visit\n");
   usleep(500000);
  }   
 }

 /* parent */
 else 
 {
  /* exit to abandon child process in the background */
  exit(0);
 }

 return(0);
}
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 2

如果您希望您的孩子在控制终端上击中中断字符时收到消息SIGINT,则它需要位于前台进程组中。你可以实现这个:

int ctty = open("/dev/tty", O_RDONLY);
while (tcgetpgrp(ctty) == getpgrp())
    usleep(100000);
setpgid(0, tcgetpgrp(ctty));
close(ctty);
Run Code Online (Sandbox Code Playgroud)

(不过,您必须等到父进程退出后 shell 更改前台进程组 - 我不确定是否有比循环旋转更好的方法,如示例所示。欢迎提出建议...)


PS:请注意,前台进程组可以随时更改 - 例如,当从 shell 运行另一个进程时。我不确定你的最终目标是什么,但也许有更好的方法来做到这一点,无论它是什么。