1

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

该代码是能够基本上模仿system()使用execl().

我的问题是printf("The exit status of the process is : %d",status);我的 main 函数中的行甚至没有执行,它等待 5 秒,因为当我运行它时,它sleep(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;
}
4

1 回答 1

1

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

也就是说,您没有初始化sa_handlersigaction 结构的字段。因此,我相当肯定您将采用默认操作。SIGALRM 的默认操作是终止进程。

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

于 2012-05-14T18:09:34.030 回答