0

This is my input function:

    int i,j,n,len,c;
    char *buffer = 0;
    size_t bufsize = 0;
    ssize_t characters;

    characters = getline(&buffer, &bufsize, stdin);

    len = strlen(buffer);
    buffer[len-1]='\0';

    if (characters > 0)
    {
        char *end_str1;
        char *token1 = strtok_r(buffer, ";", &end_str1);
        int count = 0, wordcnt;
        while (token1 != NULL)
        {
            char cmd[10][101];
            memset(cmd,0,sizeof(cmd));
            wordcnt = 0;
            char *end_str2;
            count++;
            char *token2 = strtok_r(token1, " ", &end_str2);
            while (token2 != NULL)
            {
                n = strlen(token2);
                strncpy(cmd[wordcnt],token2,n);
                wordcnt++;
                token2 = strtok_r(NULL, " ", &end_str2);
            }
            cmd[wordcnt+1][0]='\0';
            execvp(cmd[0],cmd);
            token1 = strtok_r(NULL, ";", &end_str1);
        }
    }
    free(buffer);

The only warning is incompatible pointer type, but my cmd array is a **ptr, so I don't understand what is wrong.

I tried equating it to **k, and then passing that into execvp. Didn't work. I tried changing cmd into a **cmd, I think I did something wrong there, because it should have worked but it didn't.

2
  • what are you passing to buffer? Commented Sep 24, 2016 at 9:24
  • whatever commands I enter into the program like cd ..; pwd are stored in buffer. Commented Sep 24, 2016 at 9:36

2 Answers 2

1

my cmd array is a [char] **ptr

No, it isn't.

It's a char[10][100] and when being passed to execvp() it decays to a pointer to its first element, which is char(*)[101].

Also you have an "off-by-one" error here:

cmd[wordcnt+1][0]='\0';

wordcnt had already been incremented inside the tokenising loop.

What you want is:

#define MAX_NO_OF_CMD_ELEMENTS (10)

...

        char * cmd[MAX_NO_OF_CMD_ELEMENTS + 1]; /* 1+ for the NULL-terminator */
        size_t wordcnt = 0;
        char *end_str2;
        count++;
        token2 = strtok_r(token1, " ", &end_str2);
        while ((NULL != token2)
               && (MAX_NO_OF_CMD_ELEMENTS > wordcnt)) /* Prevent writing
                                                         out of `cmd`'s bounds. */
        {
            cmd[wordcnt] = token2;
            wordcnt++;
            token2 = strtok_r(NULL, " ", &end_str2)
        }
        cmd[wordcnt] = NULL;

        execvp(cmd[0], cmd);

Also^2 getline() returns a 0-terminated char-array (a "string") already. No need for this

    len = strlen(buffer);
    buffer[len-1]='\0';
Sign up to request clarification or add additional context in comments.

9 Comments

What about doing the token2 = strtok_r(NULL, " ", &end_str2);? Is that included in the while loop?
When I use this loop for input, the program only reads the first word into all the places in the array. Did I make a mistake? ideone.com/fRxv5z (relevant code at the end)
No problem. However I think I have integrated your code into mine wrong, because pwd works, but echo doesn't. ideone.com/fRxv5z [relevant code at end]
Oh no... That means the progam will end there. I need to fork there, don't I?
@RosieRed: Make sure you call token1 = strtok_r(NULL, ";", &end_str1); after fork/exec inside the parent.'s outer while-loop.
|
0

Its because you are passing wrong parameters to function execvp.

execvp(cmd[0],cmd); //this line

Its declaration is like this:

extern int execvp (const char *__file, char *const __argv[])

and you are passing argument of type char (*)[101] where it is expecting char *, const* hence throwing incompatible error.

1 Comment

How do I fix it? Shall I create a **cmd array and then malloc to it and write to it and then pass it to exec??

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.