使用系统调用处理退出状态

process exit status using system calls

本文关键字:退出 状态 处理 系统调用      更新时间:2023-10-16

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

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

我的

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

我在这里做错了什么吗?

#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 ErrornCorrect 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帮助我完成这项任务。

最初的作业问题是: Write a program which should accept one command(like date/time/find..or any user created executable file) and run it by its child process, if the child process takes more than five seconds to run the command,parent should terminate the child process, else if the child terminates before 5 seconds-print exit status of the 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 ErrornCorrect 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..Stoppingn";
        kill(pid, SIGTERM);
        //exit(0);
        }
        }
        return 0;
}

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

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

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