gpt4 book ai didi

c - Unix execv 调用仅在首次运行时发生

转载 作者:太空宇宙 更新时间:2023-11-04 01:30:21 24 4
gpt4 key购买 nike

我正在编写一个 C 程序,它应该获取其命令行参数,打印它们,删除末尾的两个参数,然后重复直到没有参数。例如调用

a.out alpha beta gamma delta epsilon zeta eta

应该打印以下内容:

alpha beta gamma delta epsilon zeta eta
beta gamma delta epsilon zeta
gamma delta epsilon
delta

我想出的代码是这样的:

int main(int argc, char **argv) {
char **ptr;

for (ptr = argv+1; *ptr; ptr++)
printf("%s ", *ptr);
printf("\n");

if (argc > 3) {
*(ptr-1)=NULL;
execv(*argv, argv+1);
}
printf("Done!");

return 0;
}

这对于第一次 exec 调用工作正常,但没有进一步的 execs 结果,给定示例的输出是

alpha beta gamma delta epsilon zeta eta
beta gamma delta epsilon zeta
Done!

我不知道为什么。谁能看到我做错了什么?谢谢!

最佳答案

所有关于在 execv 之前调用 fork 的评论都是胡说八道。在您的情况下,您不希望原始进程继续超出调用 execv 的点,因此绝对没有理由调用 fork

您的代码不起作用的原因是 argv 数组在调用 execv 之前设置正确。因为 argv 数组不正确,execv 返回错误。通常,execv 不会返回,但在发生错误的情况下,execv 会返回并设置 errno,您可以使用 显示>错误。所以你应该像这样在 execv 后面加上一个 perror

 execv(*argv, argv+1);
perror( "execv returned" );

那么程序的输出是

alpha beta gamma delta epsilon zeta eta 
beta gamma delta epsilon zeta
execv returned: No such file or directory
Done!

那么为什么会这样呢?因为 argv 列表中的第一个参数是程序本身的名称。这可以通过打印整个 argv 列表来证明。替换这一行

for (ptr = argv+1; *ptr; ptr++)

有了这个

for (ptr = argv; *ptr; ptr++)

打印所有参数,然后输出为

./a.out alpha beta gamma delta epsilon zeta eta 
alpha beta gamma delta epsilon zeta
execv returned: No such file or directory
Done!

注意第一次运行程序时,argv[0]./a.out,因此./a.out 作为程序名传递给 execv。但是,第二次调用 execv 时,您传递的是 alpha 作为程序的名称。由于 alpha 不是有效的命令名称(幸运的是你),execv 失败并返回错误。

要解决此问题,您需要确保 argv[0] 始终是程序的名称。这是更正后的代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

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

for ( i = 1; i < argc; i++ )
printf( "%s ", argv[i] );
printf( "\n" );

if ( argc <= 2 )
{
printf( "Done!\n" );
return( EXIT_SUCCESS );
}

argv[argc-1] = NULL; // drop the last argument
argv[1] = argv[0]; // preserve the program name as the first argument

execv( argv[0], &argv[1] );
perror( "execv returned" ); // should never happen

return EXIT_FAILURE; // exec failed, return error
}

关于c - Unix execv 调用仅在首次运行时发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23796693/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com