【问题标题】:process exit status using system calls使用系统调用处理退出状态
【发布时间】:2012-05-22 05:53:23
【问题描述】:

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

代码是能够基本上模仿使用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 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;
}

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 哦,是的,我忘了提到我还必须模仿睡眠功能。 Ok 将尝试修改处理程序以将信号作为 arg 并处理响应。
    • @Abhishek S:要让它唤醒pause(),你只需要void wakeup(int) {};
    • 非常感谢,实现唤醒功能成功了! :)
    猜你喜欢
    • 2011-10-24
    • 2023-04-07
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    相关资源
    最近更新 更多