简体   繁体   中英

Segmentation fault using fgets in C

My code is not working and it is when I call fgets in the commandSplit function. I figured this out by printing "Am I here" in multiple places and find that the error at fgets it seems. I may be wrong, but I am pretty sure. I get a segmentation fault and I can not figure out why. Below is my code.

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

#define MAX_CHARACTERS 512

int Execute(char *a[], int t[], int num) {
    int exitShell = 0;
    int l = 0;
    for (int i = 0; i < num; i++) {
        int status;
        if (strcmp(a[0], "quit") == 0) {
            exitShell = 1;
        }

        if (t[i] && ((strcmp(a[l], "quit") == 0))) {
            exitShell = 1;
        }
        char *holder[t[i]+1];
        for (int j = 0; j < t[i]; j++) {
            holder[j] = a[l];
            l++;
        }
        holder[t[i]] = NULL;
        pid_t p = fork();
        pid_t waiting;
        if (p == 0) {
            execvp(holder[0], holder);

            fprintf(stderr, "Child process could not execvp!\n");
            exit(1);
        } else {
            if (p < 0) {
                fprintf(stderr, "Fork FAILED!\n");
            } else {
                waiting = wait(&status);
                printf("Child %d exit with status %d\n", waiting, status);
            }
        }
        for (int g = 0; g < t[i]; g++) {
            a[g] = NULL;
        }
    }
    for (int i = 0; i < num; i++) {
        t[i] = 0;
    }
    return exitShell;
}

int commandSplit(char *c, FILE *f, char *a[], int t[]) {

    int count = 0;
    int emptyfile = 1;
    int stat = 0;
    int total1 = 0;
    char *temp[MAX_CHARACTERS];
    if (c != NULL) {
        char *readCommands = strtok(c, ";");
        while (readCommands != NULL) {
            temp[count] = readCommands;
            count++;
            readCommands = strtok(NULL, ";");
        }
        for (int i = 0; i  < count; i++) {
            char *read = strtok(temp[i], " ");
            int track1 = 0;
            while (read != NULL) {
                a[total1] = read;
                track1++;
                total1++;
                read = strtok(NULL, " ");
            }
            t[i] = track1;
        }
        stat = Execute(a, t, count);
    } else {
        char *buildCommands = "";
        printf("Am I here???\n");
        while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
            printf("Am I here???\n");
            emptyfile = 0;
            commandSplit(buildCommands, NULL, a, t);
            stat = Execute(a, t, count);
        }
        if (emptyfile) {
            printf("File is empty!\n");
            stat = 1;
        }
    }
    printf("Am I here???\n");
    return stat;
}

int main(int argc, char *argv[]) {

    int exitProgram = 0;
    FILE *fileRead = NULL;

    if (argc == 2) {
        fileRead = fopen(argv[1], "r");
        if (fileRead == NULL) {
            printf("No such file exists\n");
            exitProgram = 1;
        }
    }
    if (argc > 2) {
        printf("Incorrect batch mode call\n");
        exitProgram = 1;
    }

    char *args[MAX_CHARACTERS];
    int tracker[MAX_CHARACTERS];

    while (!exitProgram) {
        if (argc == 1) {
            char *commands = (char *)(malloc(MAX_CHARACTERS * sizeof(char)));
            printf("tinyshell>");
            if (fgets(commands, MAX_CHARACTERS, stdin) == NULL) {
                exitProgram = 1;
                printf("\n");
            }
            int len;
            len = strlen(commands);
            if (len > 0 && commands[len-1] == '\n') {
                commands[len-1] = '\0';
            }
            if (len > MAX_CHARACTERS) {
                printf("TOO MANY CHARACTERS - MAX: 512\n");
                continue;
            }

            if (strlen(commands) == 0)
                continue;

            exitProgram = commandSplit(commands, NULL, args, tracker);
        } else {
            exitProgram = commandSplit(NULL, fileRead, args, tracker);
        }
    }   

    fclose(fileRead);
    return 0;
}

As commented @Jean-François Fabre , buildCommands points to insufficient space and potential const space;

    char *buildCommands = "";
    ...
    // bad code
    while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {

Allocate space with an array or malloc()

    char buildCommands[MAX_CHARACTERS];
    ...
    while ((fgets(buildCommands, sizeof buildCommands, f) != NULL) && !stat) {
      ...
    }

    // or 

    char *buildCommands = malloc(MAX_CHARACTERS);
    assert(buildCommands);
    ...
    while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
      ...
    }
    ...
    free(buildCommands);

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