使用 'execlp' 系统调用递归地调用 运行 当前程序

Using 'execlp' System Call to run current program recursively

我正在尝试使用 execlp 在我的程序(对于一个项目)中调用我的程序,但遇到了问题。我创建了一个示例项目,它应该从 n 倒数到 0(基本上是 运行 n 次)。每次我 运行 它,我得到第一个减量,然后我得到一个段错误。请让我知道我在这里做错了什么。

P.S 对 C 中的系统调用相当陌生,因此请尽可能详尽地解释。提前致谢!

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <time.h>

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

    int n = atoi(argv[1]);

    char newParameters[2];
    sprintf(newParameters, "%d", n - 1);

    if (n != 0)
    {
        execlp("./tmp", newParameters, (char *)NULL);
    }

    printf("The program has finished.\n");

    return 0;
}

C 程序名为 tmp。

来自execlp manual:

The initial argument for these functions is the name of a file that is to be executed.

The const char *arg and subsequent ellipses in the execl(), execlp(), and execle() functions can be thought of as arg0, arg1, ..., argn. Together they describe a list of one or more pointers to null-terminated strings that represent the argument list available to the executed program. The first argument, by convention, should point to the filename associated with the file being executed.

execlp的第一个参数是运行的可执行文件。第二个参数对应传给mainargv[0]。第三个参数是argv[1]等等。所以在这种情况下 execlp 需要是:

execlp("./tmp", "./tmp", newParameters, NULL);

或者最好还是使用 argv[0] 而不是硬编码的可执行文件名称,这样无论程序如何链接它都可以工作:

execlp(argv[0], argv[0], newParameters, NULL);

其他注意事项:

  • newParameters只能容纳单个字符串(包括NUL终止符)。因此任何大于 9 的命令行都会导致未定义的行为。
  • 其他良好做法:在使用 argv 值之前始终检查 argc 并始终检查所有函数调用的 return 值,在这种情况下特别是 execlp

execlp(2) 不能递归地用于 运行 程序,因为没有创建新进程。当前上下文(进程地址space、数据等)加载(​​覆盖)新的映射以再次执行相同的程序,并且数据段、堆栈和内存段被分离并丢弃以创建新的。当这个实例最终 exit(2)s 时,没有进程备份到 return 到。要创建新进程,您需要使用 fork(2),而不是 execlp(2)