2012-05-14 31 views
1

好吧,我想要在完成執行後打印子進程的返回狀態。使用系統調用來處理退出狀態

該代碼是基本上能夠使用execl()模仿system()呼叫。

我的問題是,我的主要功能行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; 
} 

解決方案: 感謝戴夫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

首先,除非你的目標是要模仿也sleep(),我只想用這個來代替編寫自己的。

也就是說,您並未初始化sigaction結構的sa_handler字段。因此,我相當肯定你會採取默認行動。 SIGALRM的默認操作是殺死進程。

我會修改wakeup()函數來接受一個整數,然後用它來初始化sa_handler字段,就像註釋掉了一樣。

+0

哦,是的,我忘了提及,我也必須模仿睡眠功能。好的,將嘗試修改處理程序,將信號作爲參數並處理響應。 –

+0

@Abhishek S:爲了讓它喚醒'pause()',所有你需要的是'void wakeup(int){};' –

+0

非常感謝,實現了喚醒功能的竅門! :) –

相關問題