使用 bin/time 时 Execv 不工作
Execv not working when using bin/time
当我尝试执行 /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,但它适用于 echo bin 和 date bin,所以我不知道哪里出了问题。输出如下:
I'm the parent 28001, my child 28011
I'm the child 28011, my parent 28001
error = -1
Unknown error -1
此代码 运行 在 Ubuntu 16.04 LTS VM 上运行 Mac 运行 macOS Sierra 10.12.4(以及 运行 在 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
的末尾。
- 在
execv()
失败后报告 stderr
上的错误,而不是 stdout
。
- 报告来自
errno
的错误,而不是来自 execv()
的 return 值,如果 return 根本没有,它总是 -1
。
- 如果
execv()
失败,将以错误状态退出。
- 循环直到没有 children 剩余(在有趣的情况下,一个进程可以继承 children 同一进程的前一个化身分叉 - 大多数情况下,你没有担心它,但我总是使用循环等待)。
- 报告 child 的退出状态。
在 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
$
当我尝试执行 /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,但它适用于 echo bin 和 date bin,所以我不知道哪里出了问题。输出如下:
I'm the parent 28001, my child 28011
I'm the child 28011, my parent 28001
error = -1
Unknown error -1
此代码 运行 在 Ubuntu 16.04 LTS VM 上运行 Mac 运行 macOS Sierra 10.12.4(以及 运行 在 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
的末尾。 - 在
execv()
失败后报告stderr
上的错误,而不是stdout
。 - 报告来自
errno
的错误,而不是来自execv()
的 return 值,如果 return 根本没有,它总是-1
。 - 如果
execv()
失败,将以错误状态退出。 - 循环直到没有 children 剩余(在有趣的情况下,一个进程可以继承 children 同一进程的前一个化身分叉 - 大多数情况下,你没有担心它,但我总是使用循环等待)。
- 报告 child 的退出状态。
在 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
$