2013-02-13 3 views
9

Ich habe eine Aufgabe, an der ich arbeite, und ich habe Schwierigkeiten, sie zu beenden. Die Idee ist, ein Programm if.c zu schreiben, das ein Programm ausführt, und wenn dies erfolgreich ist, führt es das zweite Programm aus. Ich soll die Standardausgabe des ersten Programms unterdrücken und die Standardausgabe für das zweite Programm unterdrücken. Ich erhalte die Fehlermeldung bei mehreren Tests. Zum Beispiel: "./if echo nein dann echo ja" gibt "echo: write error: Bad file descriptor" zurück. Ich habe versucht herauszufinden, was ich online falsch mache, aber kein Glück.In C, wie kann ich STDOUT_FILENO mit dup2 nach/dev/null umleiten und dann später wieder auf seinen ursprünglichen Wert umleiten?

Hier ist mein Code:

#include <fcntl.h> 
#include <sys/wait.h> 
#include <stdio.h> 
#include "tlpi_hdr.h" 

int main(int argc, char *argv[]) 
{ 
    if(argc < 4){ 
     fprintf(stderr,"Incorrect number of arguments.\n"); 
     exit(EXIT_FAILURE); 
    } 

    int thenArg = 0; 
    char then[4]; 
    strcpy(then,"then"); 
    for(int x=1; x<argc; x++){ 
     if(strncmp(argv[x], then, 4) == 0) thenArg = x; 
    } 

    if(thenArg == 0){ 
     fprintf(stderr,"No 'then' argument found.\n"); 
     exit(EXIT_FAILURE); 
    } 

    int save_out = dup(STDOUT_FILENO); 
    if(save_out == -1){ 
     fprintf(stderr,"Error in dup(STDOUT_FILENO)\n"); 
     exit(EXIT_FAILURE); 
    } 

    int devNull = open("/dev/null",0); 
    if(devNull == -1){ 
     fprintf(stderr,"Error in open('/dev/null',0)\n"); 
     exit(EXIT_FAILURE); 
    } 

    int dup2Result = dup2(devNull, STDOUT_FILENO); 
    if(dup2Result == -1) { 
     fprintf(stderr,"Error in dup2(devNull, STDOUT_FILENO)\n"); 
     exit(EXIT_FAILURE); 
    } 

    int program1argLocation = 1; 
    int program2argLocation = thenArg + 1; 
    int program1argCount = thenArg-1; 
    int program2argCount = argc-(program2argLocation); 
    char *program1args[program1argCount+1]; 
    char *program2args[program2argCount+1]; 

    for(int i=0; i<program1argCount; i++){ 
     program1args[i]=argv[program1argLocation + i]; 
    } 
    program1args[program1argCount] = NULL; 
    for(int i=0; i<program2argCount; i++){ 
     program2args[i]=argv[program2argLocation + i]; 
    } 
    program2args[program2argCount] = NULL; 

    pid_t pid = fork(); 
    int child_status; 
    switch (pid) { 
    case -1: 
     fprintf(stderr,"Fork failed\n"); 
     exit(EXIT_FAILURE); 

    case 0: //child 
     //child will run program 1 
     if(execvp(program1args[0],&program1args[0]) == -1){ 
      fprintf(stderr,"Program 1 Failed.\n"); 
      exit(EXIT_FAILURE); 
     } 

    default: //parent 
     //parent will run program2 
     pid = wait(&child_status); 

     if(WEXITSTATUS(child_status) == 0){ 
      dup2(save_out, STDOUT_FILENO); 

      int prog2status = execvp(program2args[0],&program2args[0]); 
      if(prog2status == -1) { 
       fprintf(stderr,"Program 2 failed.\n"); 
       exit(EXIT_FAILURE); 
      } 
     } 
    } 

} 
+0

'char dann [ 4]; strcpy (dann, "dann"); 'ist ein Pufferüberlauf. Warum benutzt du nicht einfach 'if (0 == strcmp (argv [x], "dann")) 'oder' if (0 == strncmp (argv [x], dann then, 4)) 'stattdessen? – nneonneo

+0

Ich glaube, ich habe es beim ersten Mal ausprobiert und bin in einen Fehler geraten. Ich werde mich daran erinnern und mich beim nächsten Mal wieder darauf beziehen. Vielen Dank! Noch nicht an C gewöhnt, also ist jede Eingabe wie diese großartig. – Frank

Antwort

15

Ihr Fehler ist hier:

int devNull = open("/dev/null",0); 

devNull als STDOUT_FILENO zu verwenden, müssen sie zum Schreiben geöffnet werden:

int devNull = open("/dev/null", O_WRONLY); 
+0

Danke! Ich habe diese Lösung nur wenige Augenblicke vor der Antwort gefunden. Ich habe versucht, dich zu überreden, aber anscheinend kann ich das noch nicht tun. Ich freue mich darauf, den Stack-Overflow in Zukunft zu nutzen! Dies ist eine erstaunliche Ressource. – Frank

Verwandte Themen