简体   繁体   中英

Heap based char nested array

I want to pass a heap based array that contains sub arrays for arguments to a function that uses execvp , why a heap based array, because I splitting user input into a list of arguments

int split(char * str, const char * token , char *** arr)
{
    int c = 1;
    char * ptr = strtok(str , token);
    (*arr)[0] = malloc(1024);
    strcpy((*arr)[0], "-c");
    while (ptr != NULL) 
    {
        (*arr)[c] = malloc(1024);
        strcpy((*arr)[c], ptr);
        c++;
        *arr = realloc(*arr, sizeof(char*)*(c+1));
        ptr = strtok(NULL, token);
    }
    (*arr)[c] = NULL;
    return c;
}

int  run(char * args[])
{
    int link[2];
    pid_t pid;
    char foo[4096];
    if (pipe(link)==-1)
        return -1;
    if ((pid = fork()) == -1)
        return -1;
    if(pid == 0){
        dup2 (link[1], STDOUT_FILENO);
        close(link[0]);
        close(link[1]);
        execvp("/bin/bash", args);
    } else {
        close(link[1]);
        int nbytes = read(link[0], foo, sizeof(foo));
        printf("Output: (%.*s)\n", nbytes, foo);
        wait(NULL);
  }
  return 0;
}

int main()
{
    char * tmp = malloc(1024);
    /* list of pointers */
    char ** arr = malloc(16);
    /* buffer to hold user input */
    char input[1024];
    scanf("%[^\n]", input);
    //printf("%s\n",input);
    int x = split(input, " ", &arr);
    for (int i=0; i<x;i++)
    {
        printf("%s ",arr[i]);
    }

    run(arr);

    char * arr2[] = {getenv("SHELL"), "-c" ,"ls","-la", NULL};
    run(arr2);
}

split takes the user input and create a list of pointers where the first element is -c and the last is NULL and the user input is in the middle next it is being passed to the run function that attempts to run the command with /bin/bash but throws the error

ls -la
/usr/bin/ls: /usr/bin/ls: cannot execute binary file
-c ls -la Output: ()

where as if I where to create a stack based array of arrays then pass it to the run function everything works fine and I get the directory listings

I used getenv in the split function and then passed the whole array to run this way every thing is in the right order

int split(char * str, const char * token , char *** arr)
{
    int c = 2;
    char * ptr = strtok(str , token);
    (*arr)[0] = malloc(1024);
    /* added this as the first element in the array */
    strcpy((*arr)[0], getenv("SHELL")); 
    (*arr)[1] = malloc(1024);
    /* added this as the second element in the array */
    strcpy((*arr)[1], "-c");            

    while (ptr != NULL) 
    {
        (*arr)[c] = malloc(1024);
        strcpy((*arr)[c], ptr);
        c++;
        *arr = realloc(*arr, sizeof(char*)*(c+1));
        ptr = strtok(NULL, token);
    }
    (*arr)[c] = NULL;
    return c;
}


int  run(char * args[])
{
    int link[2];
    pid_t pid;
    char foo[4096];
    if (pipe(link)==-1)
        return -1;
    if ((pid = fork()) == -1)
        return -1;
    if(pid == 0){
        dup2 (link[1], STDOUT_FILENO);
        close(link[0]);
        close(link[1]);
        /* /bin/bash to args[0] */
        execvp(args[0], args);
    } else {
        close(link[1]);
        int nbytes = read(link[0], foo, sizeof(foo));
        printf("Output: (%.*s)\n", nbytes, foo);
        wait(NULL);
  }
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM