【问题标题】:How to use execv with a generated path in C?如何在 C 中将 execv 与生成的路径一起使用?
【发布时间】:2019-02-13 20:58:49
【问题描述】:

我有一个任务,我们必须创建一个外壳。其中一部分包括使用生成不同 unix 命令的路径。 (例如:/bash/ls)。使用 execv,如果我硬编码路径,我可以让一切工作,但如果我生成它,则不能。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>

void command(char *args[]);

int main (int argc, char **argv) {
    //get the command and arguments
    char buffer[32];
    char *b = buffer;
    size_t bufferSize = 32;
    int counter = 0;
    char *tokens[10];
    char *delims = " \t\n";

    printf("dash> ");
    getline(&b, &bufferSize, stdin);

    tokens[0] = strtok(buffer, delims);

    while (tokens[counter] != NULL) {
        counter++;
        tokens[counter] = strtok(NULL, delims);
    }
    command(tokens);

}

void command(char *args[]) {
    //create path
    char *path = NULL;
    int length = strlen(args[0]);
    path = malloc(5 + length + 1);
    strcat(path, "/bin/");
    strcat(path, args[0]);

    char *input[2];
    input[0] = malloc(512);
    strcpy(input[0], path);
    printf(input[0]); //the path prints out properly
    //input[0] = "/bin/ls"; <--- this works!
    input[1] = NULL;

    //start execv
    pid_t pid;
    pid = fork();
    if(pid < 0) {
        printf("ERROR: fork failed.");
        exit(0);
    }
    else if (pid == 0) {
        execv(input[0], input);
        printf("error.");
    }

    free(path);
    free(input[0]);

}

有人有什么想法吗?我很确定这是 malloc 的问题,但我不知道如何规避它。

【问题讨论】:

    标签: c bash shell unix malloc


    【解决方案1】:

    getline() 的问题,因为您正在阅读表单 stdin,这个

    getline(&b, &bufferSize, stdin);
    

    buffer 末尾存储新行\n char & 当您将tokens 传递给command() 函数时,args 将是ls\n 而不是ls 这就是execv 失败的原因与

    execv: 没有这样的文件或目录

    所以删除多余的\n 字符以正确解析tokens,例如

    ssize_t read;
    read = getline(&b, &bufferSize, stdin); /* always check the return value */
    if(read != -1 ) {
       b[read-1] = '\0'; /* replace \n with \0 */
    }
    

    【讨论】:

    • 由于原始代码使用strtok(),因此也可以在strtok() 的分隔符列表中添加换行符 - 和制表符。
    • 在将“\t\n”添加到它起作用的分隔符之后。我对原始代码的更改反映了这一点。谢谢大家!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 2020-10-16
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    相关资源
    最近更新 更多