Pat Murray
Pat Murray

Reputation: 4265

Segmentation fault in shell program

I have been trying to create my own shell program and the tutorials I have been looking at advise the use of the strtok() function. Although, I am unable to get past simply parsing my command line and I am not sure what I am doing wrong. I keep getting a Segmentation Fault during the first use of strtok() within the parseCmd() function.

Here is my code so far:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#define MAXSIZE 512

int parseCmd(char *cmd, char *args[])
{
    printf("LOGGER: parseCmd(cmd=%s, args=%p)\n", cmd, args);

    char cmdDelims[] = " >";

    char *cmdReader;
    cmdReader = strtok(cmd, cmdDelims);

    printf("LOGGER: cmdReader=%s\n", cmdReader);

    int i = 0;
    while (cmd != NULL)
    {
        printf("LOGGER: %d counter", i);

        args[i] = strdup(cmdReader);
        cmdReader = strtok(NULL, " >");
        i++;
    }
}

int main() 
{   
    char *in;
    in = malloc(MAXSIZE);

    char *args[10];
    char *cmd = NULL;

    int errorBit = 0;
    int terminationBit = 1;

    char inDelims[] = "\n";

    while (terminationBit)
    {
        printf("mysh>");
        fgets(in, MAXSIZE, stdin);

        cmd = strtok(in, inDelims);

        errorBit = parseCmd(cmd, args);
        if (errorBit)
        {
            fprintf(stderr, "Error: Cannot parse command %s\n", cmd);
            exit(1);
        }

        if (*args == "exit")
        {
            terminationBit = 0;
        }
    }
    return 0;
}

Any help or advise on this topic would be greatly appreciated.

EDIT: Based on the output the segfault actual may NOT be strtok().

Here is some output:

mysh>hi sup
LOGGER: parseCmd(cmd=hi sup, args=0x7fff50ec0b80)
LOGGER: cmdReader=hi
Segmentation fault: 11

Upvotes: 0

Views: 937

Answers (1)

netcoder
netcoder

Reputation: 67695

Seems like a simple mistake:

while (cmd != NULL)
{
    // ...
}

...should probably be:

while (cmdReader != NULL)
{
    // ...
}

...since cmd will most likely never become NULL. Also, this:

if (*args == "exit")
{
    terminationBit = 0;
}

...probably is not going to do what you think. To compare strings, use:

if (strcmp(*args, "exit") == 0)
{
    terminationBit = 0;
}

You must make sure that parseCmd returns something as well, otherwise in this:

errorBit = parseCmd(cmd, args);

...parseCmd yields undefined behavior, so the value of errorBit is also completely undefined, as is your subsequent conditional that checks for its value.

Lastly, your program, as it is, will be leaking memory since you strdup and malloc and never free. Don't forget to free after you're done with args.

Upvotes: 1

Related Questions