2016-09-17 5 views
0

Mon code ne fonctionne pas et c'est lorsque j'appelle fgets dans la fonction commandSplit. Je ai compris cela en imprimant "Am I here" dans plusieurs endroits et trouve que l'erreur à fgets il semble. Je peux me tromper, mais je suis assez sûr. J'ai une erreur de segmentation et je n'arrive pas à comprendre pourquoi. Voici mon code.Erreur de segmentation utilisant fgets dans C

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

'char * buildCommands = ""; printf ("Suis-je ici ??? \ n"); while ((fgets (buildCommands, MAX_CHARACTERS, f)! = NULL) &&! Stat) {': vous passez un tampon de 0 octet à fgets: qu'attendez-vous. –

+0

Lorsque je m'initialise en tant que char * buildCommands; J'ai l'erreur que buildCommands ne soit pas défini, donc j'ai pensé que je peux le mettre vide et le transmettre. Comment est-ce que je contourne ceci? – David

+1

chose drôle est: vous faites la bonne chose ailleurs dans votre code: 'char * commandes = (char *) (malloc (MAX_CHARACTERS * sizeof (char))); printf ("tinyshell>"); if (fgets (commandes, MAX_CHARACTERS, stdin) == NULL) {' –

Répondre

1

Comme commenté @Jean-François Fabre, buildCommands points de manque d'espace et le potentiel d'espace const;

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

allouer de l'espace avec une matrice ou 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);