c++ - 使用系统调用处理退出状态

标签 c++ unix operating-system system-calls

好的,我想在我的子进程完成执行后打印它的返回状态。

代码基本上能够使用 execl() 模拟 system() 调用。

我的问题是 printf("The exit status of the process is : %d",status); 在我的 main 函数中甚至没有执行,它等待了 5 秒,因为sleep(5) 并在我运行它时总是在终端上打印 "Alarm clock"。相反,我希望它返回从我的系统函数返回的 child 的退出状态。

我是不是做错了什么?

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<signal.h>
using namespace std;

void wakeup() {};

int sleep(int timer)
{
    struct sigaction action;
    //action.sa_handler = wakeup;
    action.sa_flags=0;
    sigemptyset(&action.sa_mask);

    if (sigaction(SIGALRM, &action, 0)==-1)
    {
        perror("sigaction");
        return -1;
    }
    (void)alarm(timer);
    (void)pause();
    return 0;
}

int system(const char *cmd)
{
        pid_t pid;
        int status;
        pid = fork();
        if (pid==0) //child
        {
            execl("/bin/sh","sh","-c",cmd,0);
            perror("execl");
            exit(errno);
        }
        /*if(sleep(5)==-1)
        {
            perror("sigaction");
        }*/
        sleep(5);
        if(waitpid(pid,&status,0)==pid && WIFEXITED(status))
            return WEXITSTATUS(status);


        return -1;
}
int main(int argc,char *argv[])
{
        int status;
        if(argc!=2)
        {
          cout<<"Usage Error\nCorrect usage:./a.out <cmd>\n";
          exit(0);
        }
        else
        {
            status=system(argv[1]);
            if(status!=0)
            {
                cout<<"The exit status of the process is : %d"<<status;
            }
        }
        return 0;
}

解决方案: 感谢 Dave S 帮助我完成这项作业。

最初的作业问题是: 编写一个程序,它应该接受一个命令(比如日期/时间/查找..或者 任何用户创建的可执行文件)并由其子进程运行它,如果子进程 进程运行命令需要超过五秒, parent 应该 终止子进程,否则如果子进程在 5 秒打印之前终止 child 的退出状态。

完成代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<signal.h>
using namespace std;
bool timeup=false;
void wakeup(int signum) {
    if(signum==SIGALRM)
    {
        timeup=true;
    }
};

int sleeper(int timer)
{
    struct sigaction action;
    action.sa_handler = wakeup;
    action.sa_flags=0;
    sigemptyset(&action.sa_mask);

    if (sigaction(SIGALRM, &action, 0)==-1)
    {
        perror("sigaction");
        return -1;
    }
    (void)alarm(timer);
    //(void)pause();
    return 0;
}

int system(pid_t *pid,const char *cmd)
{

        int status;
        *pid = fork();
        if (*pid==0)    //child
        {
        sleep(6); // remove or modify value to change how long the process will minimally take to execute
            execl("/bin/sh","sh","-c",cmd,0);
            perror("execl");
            exit(errno);
        }

        return 0;
}
int main(int argc,char *argv[])
{
        int status=-999;
    pid_t pid;
        if(argc!=2)
        {
          cout<<"Usage Error\nCorrect usage:./a.out <cmd>\n";
          exit(0);
        }
        else
        {

        system(&pid,argv[1]);

        sleeper(5);// the timer for 5 seconds

        if(waitpid(pid,&status,0)==pid && WIFEXITED(status))
                status = WEXITSTATUS(status);
        if(!timeup)
                cout<<"The exit status of the process is :"<<status<<"\n";
        else
        {
        cout<<"Took more that 5 seconds..Stopping\n";
        kill(pid, SIGTERM);
        //exit(0);
        }

        }
        return 0;
}

最佳答案

首先,除非您的目标也是模仿 sleep(),否则我只会使用它而不是自己编写。

也就是说,您没有初始化 sigaction 结构的 sa_handler 字段。因此,我相当确定您正在执行默认操作。 SIGALRM 的默认操作是终止进程。

我会修改 wakeup() 函数以接受一个整数,然后使用它来初始化 sa_handler 字段,正如您注释掉的那样。

关于c++ - 使用系统调用处理退出状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10588548/

相关文章:

c++ - 我如何从读取二进制文件的 mkv 中提取集群的 timstemp

c++ - 通用成员函数指针作为另一个类中的模板参数

linux - 替代向上箭头 + Enter 运行上一个命令?

Unix 查找缺少文件的目录

c# - .NET Standard 2.0 获取当前操作系统

c++ - 以堆栈状态为条件的 Visual Studio 断点

c++ - 如果类也有非虚方法,模拟纯虚方法?

c - fork() - 在 exec() 之前有什么用?

multithreading - 在什么意义上,每个线程对于操作系统来说都是一个单独的 CPU?

c++ - 如何使用 C++ 代码验证 CPU 缓存行大小?