c - 即使我在 Linux(Mint 18.3)上使用 kill 命令发送信号,WIFSIGNALED 也会返回 false

标签 c linux waitpid sigterm

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

例如:

如果我发送一个 *kill -15 1245*,其中 1245 是我进程的 pid,我的程序应该打印类似 "Process被信号 15" 杀死,但即使我向进程发送 *kill -15* WIFSIGNALED 宏返回 false,显然 WTERMSIG 返回 0。

系统: 我使用的是 Linux Mint 18.3,一个基于 Ubuntu 的发行版,我在其他 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;
}

最佳答案

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

当你打电话的时候

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

如果 sh/bin/dash(与debian一样),shell会在退出前调用waitpid()自身获取cat的状态;如果 sh/bin/bash,它只会exec 直到脚本中的最后一个命令。

尝试输入类似echo pid=$$; 的命令cat 在你的 mini-shell 中,然后 kill echo 打印的 pid,而不是 cat 的 pid,你将得到预期的 'Process killed by信号……”

关于c - 即使我在 Linux(Mint 18.3)上使用 kill 命令发送信号,WIFSIGNALED 也会返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52322832/

相关文章:

c - C 中的微优化,有哪些?真的有人有用吗?

C编程: the cost of passing by value

windows - 对从 DLL 或 SO 导出的符号的写入权限

python - 如何在后台启动服务并使用子进程并将日志存储在文件中

linux - 安排一个 cronjob 每 2 1/2 小时运行一次

c - 确定已终止进程的 pid

chdir() 不影响环境变量 PWD

linux - 子进程互相等待

c - 这个基于 fork 的模式是什么?

c++ - 是否可以直接传递 C 省略号调用?