首页 > 解决方案 > 即使我在 Linux(Mint 18.3)上使用 kill 命令发送信号,WIFSIGNALED 也会返回 false

问题描述

问题:我需要打印进程收到的终止信号,

例如:_

如果我发送一个*kill -15 1245* 1245 是我的进程的 pid,我的程序应该打印类似的东西"Process killed by signal 15",但即使我发送一个*kill -15*到一个进程,WIFSIGNALED macro returns false and obviously WTERMSIG returns 0.

系统:我使用的是基于 Ubuntu 的发行版 Linux Mint 18.3,我在其他 Ubuntu 发行版中测试了我的程序,但仍然无法正常工作,但在 Fedora 和 OpenSUSE 中运行良好。任何想法?

编码:

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

//Macros
#define MAX_LIMIT 50

//Function where i create a child process and execute a shell over it.
void run(char comando[])
{
    int status;
    pid_t pid;
    if((pid = fork()) == 0)
        execlp("sh", "sh", "-c", comando, NULL);
    pid = waitpid(pid, &status, 0);
    //The problem begins here, the WIFEXITED returns *true* even is the process was killed by a signal.
    if(WIFEXITED(status))
        printf("Process ended with status %d\n", 
WEXITSTATUS(status));
    //Is here when i need to print the signal, but WIFSIGNALED returns *false* even if a signal was sended by the *kill* command.
    else if(WIFSIGNALED(status))
        printf("Process killed by signal %d\n", 
WTERMSIG(status));
    else if(WIFSTOPPED(status))
        printf("Process stopped by signal %d\n", 
WSTOPSIG(status));
    else if(WIFCONTINUED(status))
        printf("Process continued...\n");
} 
//Function that simulates a shell by repeating prompt.
void shell()
{
    run("clear");
    printf("\t\t\t\t\tMINI_SHELL\n");
    char comando[MAX_LIMIT];
    do
    {
        printf("$> ");
        fgets(comando, MAX_LIMIT, stdin);
        char *cp = strchr(comando,'\n'); if (cp != NULL) *cp =  0;
        if(strcmp(comando, "ext") != 0)
            run(comando);
    } while(strcmp(comando, "ext") != 0);
}

int main(int argc, char *argv[])
{
    shell();
    return 0;
}

标签: clinuxwaitpidsigterm

解决方案


这一切都归结为基于 debian 的发行版 ( /bin/dash) 和基于 redhat 的发行版 ( ) 上的默认 shell 之间的区别/bin/bash

当你打电话时

execlp("sh", "sh", "-c", comando, NULL);

使用commandolike"cat""echo 1; cat", if shis /bin/dash(如在 debian 上),shell 将在退出前调用waitpid()自身的状态;cat如果sh/bin/bash,它将直接exec执行到脚本中的最后一个命令。

echo pid=$$; cat尝试在你的 mini-shell 中输入一个命令,然后kill是 echo 打印的 pid,而不是 pid cat,你会得到预期的“进程被信号杀死......”


推荐阅读