C - 使用exec()代替system()

时间:2014-10-21 23:52:57

标签: c exec fork system

在以下代码中:

int main ( int argc, char *argv[] ) {
    int i, pid, status;

    for(i = 0; i < atoi(argv[1]); i++) {
        pid = fork();
        if(pid < 0) {
            printf("Error occured");
            exit(1);
        } else if (pid == 0) {
            status = system("./frun test.txt 1");
            if (status != 0)
                printf("ERROR, exited with %d\n", status);
            else
                printf("SUCCESS, exited with %d\n", status); // 0
            exit(0); 
        } else  {
            wait(NULL);
        }
    }
    return 0;
}

我正在使用system()来运行一个名为&#39; frun&#39; 我的问题是 - 如何更改代码以使用其中一个exec()系列函数?

我的主要问题是我需要获取程序的退出代码,而我无法找到使用exec()的方法,而system()只返回退出状态。

1 个答案:

答案 0 :(得分:2)

阅读wait和exec的手册页。

你等待从分叉和执行创建的进程(回想一下exec替换当前进程,所以你必须fork来获取它的退出代码)。这是等待的手册页:

  

无论其价值如何,都可以使用以下方法解释此信息              宏,在<sys/wait.h>中定义并计算为整数表达式;该              stat_val参数是stat_loc指向的整数值。

     
      
  • WIFEXITED(stat_val)
      如果为子进程返回状态,则求值为非零值                正常终止。
  •   
  • WEXITSTATUS(stat_val)
      如果WIFEXITED(stat_val)的值不为零,则此宏将计算为                子进程传递给_exit()的状态参数的低位8位                或exit(),或子进程从main()返回的值。
  •   
  • WIFSIGNALED(stat_val)
      如果为子进程返回状态,则求值为非零值                由于收到未捕获的信号而终止(参见<signal.h>)。
  •   
  • WTERMSIG(stat_val)
      如果WIFSIGNALED(stat_val)的值不为零,则此宏将计算为                导致子进程终止的信号编号。
  •   
  • WIFSTOPPED(stat_val)
      如果为子进程返回状态,则求值为非零值                目前停了。
  •   
  • WSTOPSIG(stat_val)
      如果WIFSTOPPED(stat_val)的值不为零,则此宏将计算为                导致子进程停止的信号编号。
  •   
  • WIFCONTINUED(stat_val)
      如果为子进程返回状态,则求值为非零值                从工作控制站继续。
  •   

在您的情况下,您可能希望使用WEXITSTATUS(stat_val)来获取8位退出代码。

您调用waitpid(pid, stat_loc, options),您将传递从pid返回的fork(),指向本地int(存储状态的位置)的指针,以及您的选项标记(或0)。你会这样做是在pid != 0的分支,因为这是原始过程。原始流程调用fork()(其中pid == 0)会调用exec,因此会被exec&#39; d命令替换。

这是一个伪示例,您可以适应您的代码:

pid_t pid;
int status;
pid = fork();
if (pid == 0)
{
        exec(/*look up the different functions in the exec family and how to use them*/);
}
else if (pid < 0)
{
        //uh oh
}
else
{
        waitpid(pid, &status, 0);
        printf("Exited with %d\n", WEXITSTATUS(status));
}

虽然你应该检查waitpid的结果。