使用C

时间:2016-09-17 20:34:40

标签: c shell fgets

我的代码无效,我在fgets函数中调用commandSplit时就是这样。我通过在多个地方打印"Am I here"并在fgets看到错误来解决这个问题。我可能错了,但我很确定。我得到了一个分段错误,我无法弄清楚原因。以下是我的代码。

#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;
}

1 个答案:

答案 0 :(得分:1)

如评论@Jean-François Fabre buildCommands指的是空间不足和潜在的const空间;

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

使用数组或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);