0

I am trying to figure out how to get my array of strings from get_arguments to NULL terminate, or if that isn't the issue to function in my execv call.

char ** get_arguments(const char * string) {
    char * copy = strdup(string);
    char * remove_newline = "";
    for(;;) {
        remove_newline = strpbrk(copy, "\n\t");
        if (remove_newline) {
            strcpy(remove_newline, "");
        }
        else {
            break;
        }
    }   
    char (* temp)[16] = (char *) malloc(256 * sizeof(char));
    char * token = strtok(copy, " ");
    strcpy(temp[0], token); 
    int i = 1;
    while (token && (token = strtok(NULL, " "))) {
        strcpy(temp[i], token);
        i++;
    }
    char * new_null;
    //new_null = NULL; 
    //strcpy(temp[i], new_null);
    if(!temp[i]) printf("yup\n");
    int c = 0;
    for ( ; c <= i; c++) {
        printf("%s ", temp[c]);
    }
    return temp;
}

I am trying to read in a string, space separated, similar to find ./ -name *.h. I am trying to input them into execv.

char (* arguments)[16] = (char **) malloc(256 * sizeof(char));

//...numerous lines of unrelated code

pid = fork();
if (pid == 0) {
    arguments = get_arguments(input_string);
    char * para[] = {"find", "./","-name", "*.h", NULL};
    execv("/usr/bin/find", (char * const *) arguments);
    //printf("%s\n", arguments[0]);
    printf("\nexec failed: %s\n", strerror(errno)); //ls -l -R
    exit(-1);
}

When I swap arguments in the execv call for para it works as intended, but trying to call with arguments returns exec failed: Bad address. If I remove the NULL from para I get the same issue. I've tried strcpy(temp, (char *) NULL), the version you see commented out in get_arguments, and a number of other things that I can't recall in their entirety, and my program ranges from Segmentation fault to failure to compile from attempting to strcpy NULL.

Changing the declarations of arguments and temp to char ** arguments = (char *) malloc(256 * sizeof(char)); ``char ** temp = (char *) malloc(256 * sizeof(char));clears upwarning: initialization from incompatible pointer typebut causes segfault on all calls toget_arguments`.

Kebtiz
  • 63
  • 6
  • I am most confused because most places I read say that unused space in a declared array space is defaulted to null, but it fails the `if(!temp[i]) printf("yup\n");` test under all conditions I have attempted. – Kebtiz Oct 05 '16 at 01:33
  • 1
    You can remove the `(char *)` cast in front of that `malloc()`, for one thing. – ad absurdum Oct 05 '16 at 01:41
  • Thank you, that cleared up `warning: initialization from incompatible pointer type`. Odd that is a convention I've seen used repeatedly. Are there situations where that explicit type is required? – Kebtiz Oct 05 '16 at 01:54
  • 1
    Not in C. Some people are very adamant that you should never cast a `malloc()`, others think that it is OK when it makes your code clearer. You were getting a warning because you were casting the return value of `malloc()` to `char *`, but assigning that value to `char **`. Check out this link: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – ad absurdum Oct 05 '16 at 02:01

1 Answers1

1

You want this:

char* temp[256]; // an array of 256 char*'s
char * token = strtok(copy, " ");
temp[0] = strdup(token);
int i = 1;
while (token && (token = strtok(NULL, " "))) {
    temp[i] = strdup(token);
    i++;
}
temp[i] = NULL;
David Schwartz
  • 179,497
  • 17
  • 214
  • 278