Как использовать execv с сгенерированным путем в C? - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть задание, в котором мы должны создать оболочку. Частично это включает использование путей к различным командам 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, но я не уверен, как обойти это.

1 Ответ

0 голосов
/ 09 сентября 2018

Проблема с getline(), так как вы читаете форму stdin, это

getline(&b, &bufferSize, stdin);

сохранить новую строку \n char в конце buffer и когда вы передадите 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 */
}
...