2016-03-25 10 views
1

Ich bin eine Shell implementieren und Umleitung: Schreiben von Ausgaben in eine Datei oder Lesen von Eingaben aus einer Datei. die Probleme, die ich bin vor sind:Umleitung Ausgabe in eine Datei gibt Codierungsproblem in C

  • Der Name der Datei ist „` b“wenn ich Typen dieser Befehl als Eingabe für mein Programm erhalte ich„Art < test.txt“ während es nicht in eine Datei schreiben sollte! und Programm hungs und keine sortierte Ausgabe!

  • Wenn ich tippe: „ls> out.txt“, wird der Ausgang auf beide Terminal geschrieben und out.txt Datei

  • das Programm erwartet wird, eingegeben ewig dauern, bis der Benutzer Schreib "exit", um das Programm zu schließen, aber nach der Eingabe eines Befehls, der Umleitung benötigt, stoppt das Programm, so dass es nur ein cmd mit Umleitung einmal, dann wird es aufhören!

Dies ist mein Code:

int execute(char **args) 
{ 
    int i, in, out; 
    char * inputF; 
    char * outputF; 
    if (args[0] == NULL) { 
     return 1; 
    } 

    int pNum = 0; 
    //char * cwd; 
    //cwd = getcurDirectory(); 
    i = 0; 
    printf("***Testing: Before while loop\n"); 
    while (args[i] != NULL) { 
    printf("***Testing: entered while loop: %d\n", i); 
     if (strcmp(args[i], "<") == 0) { 
      printf("***Testing: found %s in args[%d] \n", args[i], i); 
      in = 1; 
      args[i] = NULL; 
      inputF = args[i+1]; 
      args[i+1] = NULL; 
      ++i; 
      continue; 
     } 

     if (strcmp(args[i], ">") == 0) { 
      printf("***Testing: found %s in args[%d] \n", args[i], i); 
      out = 1; 
      args[i] = NULL; 
      outputF = args[i+1]; 
      args[i+1] = NULL; 
      ++i; 
      continue; 
     } 

     if (strcmp(args[i], "|") == 0) { 
      printf("***Testing: found %s in args[%d] \n", args[i], i); 
      ++pNum; 
     } 
     ++i; 
    } 

    if(in == 1 || out == 1){ 
     int pid = fork(); 
     if (pid == -1) { 
       perror("fork"); 
     } else if (pid == 0) { 
      if (in) { 
       int fd0 = open(inputF, O_RDONLY, 0); 
       dup2(fd0, STDIN_FILENO); 
       close(fd0); 
       in = 0; 
      } 

      if (out) { 
       int fd1 = creat(outputF, 0644); 
       dup2(fd1, STDOUT_FILENO); 
       close(fd1); 
       out = 0; 
      } 
      int r; 
      for(r = 0; r < sizeof(args); ++r) 
       printf("***Testing: args[%d] %s \n", r, args[r]); 
      //setenv("parent",cwd,1); 
      if(execvp(args[0], args) < 0){ 
       perror(*args); 
       exit(EXIT_FAILURE); 
      } 
     } else { 
      waitpid(pid, 0, 0); 
      //free(args); 
     } 
    } 

    if (pNum > 0){ 
     //printf("***Testing: Phew! got a pipe! \n"); 
     return handel_piping(args, pNum); 
    } 

    for (i = 0; i < builtins(); i++) { 
     if (strcmp(args[0], builtin_str[i]) == 0) { 
      return (*builtin_func[i])(args); 
     } 
    } 

    return launch_cmd(args); 
} 
+0

'für (r = 0; r Barmar

+0

Warnung: 'in' und' out' scheinen nicht initialisiert zu sein. – purplepsycho

+0

@purplepsycho Vielen Dank für Ihren Hinweis, ich schätze es, ich habe sie in meiner Lösung berücksichtigt, aber ich habe immer noch die gleichen Probleme, die ich in meinem Beitrag erwähnt habe. irgendwelche anderen Hinweise? – sareem

Antwort

1

Wenn Sie die Verarbeitung < und >, ich bin nicht i genug erhöht wird. Da ihnen ein weiteres Argument folgt, müssen Sie i um 2 erhöhen, nicht um 1, sodass der Dateiname vor der Verarbeitung des nächsten Arguments übersprungen wird.

if (strcmp(args[i], "<") == 0) { 
     printf("***Testing: found %s in args[%d] \n", args[i], i); 
     in = 1; 
     args[i] = NULL; 
     inputF = args[i+1]; 
     args[i+1] = NULL; 
     i += 2; 
     continue; 
    } 

    if (strcmp(args[i], ">") == 0) { 
     printf("***Testing: found %s in args[%d] \n", args[i], i); 
     out = 1; 
     args[i] = NULL; 
     outputF = args[i+1]; 
     args[i+1] = NULL; 
     i += 2; 
     continue; 
    } 

Ein weiteres Problem ist, dass Sie nicht in und out Sie initialisieren. Da sie wahrscheinlich nicht auf 0 initialisiert werden, verhält sich der Code so, als ob Sie eine Umleitung eingegeben hätten, die Sie nicht eingegeben haben, und verwenden Sie dann eine nicht initialisierte Variable als Dateinamen. Diese Schleife ist falsch

int i, in = 0, out = 0; 

: Sie sollten mit initialisiert werden

 for(r = 0; r < sizeof(args); ++r) 
      printf("***Testing: args[%d] %s \n", r, args[r]); 

sizeof(args) die Größe eines Zeigers ist, nicht die Anzahl der Elemente in dem Array args. Und es versucht auch, Argumente zu drucken, die durch NULL durch die frühere Schleife ersetzt wurden. Es sollte sein:

 for(r = 0; args[r] != 0; ++r) 
      printf("***Testing: args[%d] %s \n", r, args[r]); 
+0

das sind tolle Hinweise, vielen Dank! Allerdings habe ich immer noch dieselben Probleme, die oben erwähnt wurden, und ich kann nicht herausfinden, wo das Problem ist: \ – sareem

+0

Ich kann keinen Grund, warum Sie die Ausgabe auf dem Terminal sehen, wenn es in eine Datei umgeleitet wird. – Barmar

+0

Es kann unmöglich passieren, ohne ein Programm wie 'tee' zu ​​verwenden. – Barmar