c - 标记一个字符串以作为 char * 传递给 execve()

标签 c pointers tokenize arrays execve

我对 C 的了解非常有限。我正在尝试对从客户端传递给服务器的字符串进行标记化,因为我想使用传递给 execve 的参数。通过buffer 传递的参数需要复制到*argv 并进行标记化,以便buffer 的标记可以通过argv[ 0]argv[1] 等。显然我做错了什么。

n = read(sockfd, buffer, sizeof(buffer));
strcpy(*argv, buffer);
printf("buffer:%s\n", buffer);
printf("argv:%s\n", *argv);
printf("argv[0]:%s\n", argv[0]);
printf("argv[1]:%s\n", argv[1]);
*argv = strtok_r(*argv, " ", argv);
printf("argv:%s\n", *argv);

i = fork();
if (i < 0) {
    //Close socket on fork error.
    perror("fork");
    exit(-1);
} else if (i == 0) {
    //execve on input args
    execve(argv[0], &argv[0], 0);
    exit(0);
} else {
    wait(&status);
    //close(sockfd);
}

将参数“/bin/date -u”与上述代码一起传递会得到以下输出:

buffer:/bin/date -u

argv:/bin/date -u

argv[0]:/bin/date -u

argv[1]:(null)

我的输出是什么:

buffer:/bin/date -u

argv:/bin/date -u

argv[0]:/bin/date

argv[1]:-u

我尝试使用strtok_r(),但它并没有像我预期的那样工作。我插入的片段是:

*argv = strtok_r(*argv, " ", argv);
printf("argv:%s\n", *argv);

输出 argv:/bin/date

提前致谢,SO。

编辑:我不必像上面那样显式标记buffer。从客户端获取传递给服务器的参数的任何方式都可以正常工作。

最佳答案

好吧,您要处理几个问题。第一个是选择 argv 作为您要写入缓冲区的变量。虽然它只是一个指针数组,但您通常将 argv 视为包含传递给 即时过程的参数的数组,而不是要修改的变量。但是,这确实是语义,据我所知,没有禁止这样做的规定。但是,您不能在将标记分配给 *argv 的同时对 *argv 进行标记,因为 strtok_r 修改了 *argv 在此过程中。

除此之外,真正的问题似乎是 strtok_r 的使用。看看 man strtok_r。为了标记字符串,您需要重复调用strtok_r 以提取所有标记。使用第一个参数 (*argv...) 对 strtok_r 的第一次调用仅提取 first 标记。为了完成提取,您必须传递 NULL 作为第一个参数,直到提取完所有标记。此外,您从中提取 token 的字符串已通过调用 strtok_r 进行修改,不应在提取后使用。如果以后需要,通常会制作字符串的副本以保留原始字符串。

在您的代码中,您只调用一次 strtok_r 例如:

*argv = strtok_r(*argv, " ", argv);  // extracts the first token and modifies *argv

如果您的目的是提取所有字符串,那么您将需要重复调​​用 strtok_r,例如:

char *token = malloc (sizeof (token) * 128); // or something large enough to hold the tokens

token = strtok_r(*argv, " ", argv);
if (token)
    printf (" token: %s\n", token);

while ((token = strtok_r (NULL, " ", argv)) != NULL)
{
    printf (" token: %s\n", token);
}

您可以根据需要捕获单个 token ,以便将它们传递给 execve。但是,您将无法在写回 argv 的同时从 argv 中剥离 token 。如上所述,argv 在提取期间由 strtok_r 修改,因此您需要一个单独的数组来保存标记。希望这会有所帮助。

关于c - 标记一个字符串以作为 char * 传递给 execve(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24796266/

相关文章:

在 Ubuntu 上针对 libusb-dev 进行编译

c++ - node, & node 和 node->next in 链表的区别

java - 在java中以2个字符分隔符分割字符串

python - 值错误 : cannot reshape array of size 3800 into shape (1, 200)

c - 使用 strtok 验证用户在 C 中输入的日期的问题

c - for循环无限运行为什么?

c - EXC_BAD_ACCESS,无法定位错误

c++ - 使用 C 风格的字符串有哪些缺点?

c - 代码编译时出错,请解释

c - 使用指向结构的指针在设备内存中设置一个数组;在库达