好的,我想在我的子进程完成执行后打印它的返回状态。
代码基本上能够使用 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/