在C中编写小型UNIX实用程序时,我有时希望获取提供给main()的argv
副本,以便在调用exec()之前调整参数。以下内容基于BSD的xargs(1)的实现:
void run_script(char *argv[]) {
char **tmp, **new_argv;
int argc;
for (argc=0; argv[argc] != 0; argc++);
new_argv = malloc((argc + 1) * sizeof(char *));
for (tmp=new_argv; *argv != 0; tmp++) {
*tmp = *argv++;
*tmp = strdup(*tmp);
}
/* call execvp(3) using new_argv */
for (i=0; i<=argc; i++)
free(new_argv[i]);
free(new_argv);
}
这感觉比它需要的更复杂。有没有更好的方法在C中写这个? (也许填写使用_POSIX_ARG_MAX分配的单个缓冲区。)
答案 0 :(得分:1)
我的C有点生疏,但是......
假设argv []在脚本的持续时间内可用,如果不打算更改字符串,则无需删除字符串。分配内存后(如果要添加额外的参数,请记住要向argc添加更多内容),您应该能够memcpy。你的new_argv将指向与原始argv相同的字符串,因此在更改之前需要进行strdup(如果你想将其设置为其他字符串则不需要)。
我认为你需要密切关注你的循环,for (m=0, tmp..
- 首先,我不认为m会在其他任何地方使用;第二,你正在测试*argv != 0
,但是没有在循环中更改* argv,所以它将永远运行或根本不运行,第三,在这个循环开始时,所有new_argv都是空指针,所以{{ 1}}会尝试复制内存地址为0的字符串,与argv无关。
答案 1 :(得分:1)
我想出了另一个复制argv的过程。以下示例不短,但我认为更容易阅读:
void run_script(char *argv[]) {
int i;
char **new_argv;
char *p, *arg_buf;
int argc;
for (argc=0; argv[argc]; argc++);
arg_buf = malloc(ARG_MAX);
new_argv = calloc(argc+1, sizeof(char *));
for (i=0, p=arg_buf; i<argc; i++) {
p += strlcpy(p, argv[i], ARG_MAX - (p - arg_buf));
p++;
}
/* call execvp(3) using new_argv */
free(arg_buf);
free(new_argv);
}
在Linux上ARG_MAX
应替换为sysconf(_SC_ARG_MAX)