使用bin / time时execv不工作

时间:2017-04-19 02:48:49

标签: c fork exec execv

当我尝试执行/bin/time /bin/echo Hello world时,我的程序出现问题,我没有输出。我知道这个示例代码有效 例如使用/ bin / date或/ bin / echo,我认为它也应该与时间一起工作但不是

int main(int argc, char * argv []) {    
    int err = 1;
    char *array[3] = {"/bin/time", "/bin/echo", "Hello World"};
    pid_t childPIorZero = fork();

    if (childPIorZero < 0){
        perror("fork() error");
        exit(-1);                        
    }
    if (childPIorZero != 0){
        printf("I'm the parent %d, my child %d\n",getpid(),childPIorZero);
        wait(NULL); 
    }           
    else{
         printf("I'm the child %d, my parent %d\n",getpid(), getppid());
         err = execv(array[0], array);
         printf("error = %d\n", err);
         printf("%s\n", strerror(err));
    }

    return 0;
}

我虽然问题是我以错误的方式传递了execv的参数,但它适用于回音箱和日期箱,所以我不知道什么是错的。输出如下:

I'm the parent 28001, my child 28011
I'm the child 28011, my parent 28001
error = -1
Unknown error -1

1 个答案:

答案 0 :(得分:1)

这个代码在运行macOS Sierra 10.12.4的Mac上托管的Ubuntu 16.04 LTS VM上运行正常(并且在macOS上也运行正常)。

#define _XOPEN_SOURCE 700
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    char *array[] = { "/usr/bin/time", "/bin/echo", "Hello World", 0 };
    pid_t childPIorZero = fork();

    if (childPIorZero < 0)
    {
        perror("fork() error");
        exit(-1);
    }
    if (childPIorZero != 0)
    {
        printf("I'm the parent %d, my child %d\n", getpid(), childPIorZero);
        int status;
        int corpse;
        while ((corpse = wait(&status)) != -1)
            printf("PID %d exited with status 0x%.4X\n", corpse, status);
    }
    else
    {
        printf("I'm the child %d, my parent %d\n", getpid(), getppid());
        execv(array[0], array);
        int errnum = errno;
        fprintf(stderr, "(%d) %s\n", errnum, strerror(errnum));
        exit(1);
    }

    return 0;
}

问题代码的主要变化包括:

  • 更改time可执行文件的位置。
  • 将空指针添加到array
  • 的末尾
  • stderr失败后报告stdout而非execv()的错误。
  • 报告来自errno的错误,而不是来自execv()的返回值,如果它返回则始终为-1
  • 如果execv()失败,则退出并显示错误状态。
  • 循环直到没有孩子离开(在有趣的情况下,一个过程可以继承孩子,以前的同一过程的化身分叉 - 大多数情况下,你不必担心它,但我总是使用一个循环等待)。
  • 报告孩子的退出状态。

在Ubuntu上,我编译了:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
>     -Wstrict-prototypes -Wold-style-definition ev11.c -o ev11
$ ./ev11
I'm the parent 25129, my child 25130
I'm the child 25130, my parent 25129
Hello World
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 1620maxresident)k
8inputs+0outputs (1major+66minor)pagefaults 0swaps
PID 25130 exited with status 0x0000
$

我在macOS上使用了相同的编译命令行(当然是一个不同的编译器)并得到了:

$ ./ev11
I'm the parent 3220, my child 3221
I'm the child 3221, my parent 3220
Hello World
        0.00 real         0.00 user         0.00 sys
PID 3221 exited with status 0x0000
$