[英]how to forward a signal to child process from parent process
我正在實現我自己的 shell,它要求按 CTRL-Z 暫停前台進程。 為了不暫停我的主進程而只暫停子進程,我必須通過主進程中的處理程序捕獲 SIGTSTP 並將其重定向到我的子進程(需要停止)。 但是殺死 function 永遠不會回來。
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/mman.h>
void handler(){
pid_t pid;
int status;
while((pid = waitpid(-1, &status, 0))>0){
printf("pid: %d has been reaped\n", pid);
}
}
void send_signal(int signum){
kill(pid, signum);
}
void init_signals(){
//signal(SIGINT, send_signal);
signal(SIGCHLD, handler);
signal(SIGTSTP, send_signal);
}
void start_foreground_job(char** argv)
{
if( (fork()) ==0)
{
signal(SIGTSTP, SIG_DFL);
if((execve(argv[0], argv, NULL))<0)//envp
{
fprintf(stderr, "%s: Command not found.\n", argv[0]);
exit(0);
}
}
pause();
return;
}
int main(){
init_signals();
char* argv[] ={"/bin/sleep", "10", NULL};
start_foreground_job(argv);
printf("This line is what I expected after pressing CTRL-Z\n");
return 0;
}
當我在我的環境中嘗試您的代碼時,結果與您相同。 Ctrl+Z后查看子進程的state,
在 Ctrl + Z 之前
ps -aux | grep sleep
16586 0.0 0.0 2016 412 pts/1 S+ 10:42 0:00 /bin/sleep 10
Ctrl + Z 之后
ps -aux | grep sleep
16586 0.0 0.0 2016 412 pts/1 T+ 10:42 0:00 /bin/sleep 10
子進程的 state 由 S -> T 變化,表示父進程已成功向子進程發送信號。
但是子進程沒有退出,所以你的 waitpid(-1, &status, 0) 不能返回。
選項1:給子進程發送kill信號,waitpid會得到一個返回。
void send_signal(int signum)
{
if (pid)
{
printf("kill %d, signum %d\n", pid, signum);
//kill(pid, signum);
kill(pid, SIGKILL );
}
}
選項2:waitpid api 有一個選項可以等待停止 state:
void handler()
{
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WSTOPPED)) > 0) {
printf("pid: %d has been reaped\n", pid);
break;
}
}
請檢查以下 sw 版本,它適用於我的工作站。
int pid = 0;
void handler()
{
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WSTOPPED)) > 0) {
printf("pid: %d has been reaped\n", pid);
break;
}
}
void send_signal(int signum)
{
if (pid)
{
printf("kill %d, signum %d\n", pid, signum);
kill(pid, signum);
//kill(pid, SIGKILL );
}
}
void init_signals()
{
signal(SIGCHLD, handler);
signal(SIGTSTP, send_signal);
}
void start_foreground_job(char** argv)
{
pid = fork();
if (pid == 0) {
signal(SIGTSTP, SIG_DFL);
if ((execve(argv[0], argv, NULL)) < 0) { //envp
fprintf(stderr, "%s: Command not found.\n", argv[0]);
exit(0);
}
}
printf("son process pid is %d\n", pid);
pause();
return;
}
int main()
{
init_signals();
char* argv[] = {"/bin/sleep", "10", NULL};
start_foreground_job(argv);
printf("This line is what I expected after pressing CTRL-Z\n");
return 0;
}
下面是我的測試結果:
./temp
son process pid is 29249
^Zkill 29249, signum 20
pid: 29249 has been reaped
This line is what I expected after pressing CTRL-Z
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.