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

时间:2012-05-14 17:55:50

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

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

代码可以使用system()基本上模仿execl()来电。

我的问题是我的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 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帮助我完成这项任务。

原始作业问题是: 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 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;
}

1 个答案:

答案 0 :(得分:1)

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

那就是说,你没有初始化sigaction结构的sa_handler字段。因此,我很确定你会采取默认行动。 SIGALRM的默认操作是终止进程。

我会修改wakeup()函数来接受一个整数,然后用它来初始化sa_handler字段,就像你已注释掉一样。