2013-02-13 13 views
9

Çalıştığım bir görevim var ve bunu bitirmekte zorlanıyorum. Buradaki fikir, bir programı yürüten bir program yazmaktır ve eğer başarılı olursa ikinci programı yürütür. İlk programın standart çıktısını ve ikinci için de standart olmayan çıktıyı bastırmam gerekiyordu. Birden çok testte hata mesajı alıyorum. Örneğin: "./if echo hayır o zaman echo evet" "echo: write error: Bad file descriptor" ifadesini döndürür. İnternette yanlış yaptığımı bulmaya çalıştım ama şans yok. Bu yazmak için açılmalıdırC'de, STDOUT_FILENO'yu dup2'yi kullanarak/dev/null'a nasıl yönlendiririm ve daha sonra yeniden özgün değerine yeniden yönlendiririm?

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

STDOUT_FILENO olarak devNull kullanmak için:

#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 [ 4]; strcpy (sonra "o zaman"); 'bir arabellek taşmasıdır. Neden sadece '' (0 == strcmp (argv [x], "sonra")) 'veya' (0 == strncmp (argv [x], "o zaman", 4)) 'yi kullanmıyorsunuz? – nneonneo

+0

Sanırım bunu ilk kez uyguladım ve bir çeşit hata yaptım. Bunu hatırlayacağım ve bir dahaki sefere aynı şeyle karşılaştığımda tekrar göstereceğim. Teşekkür ederim! Henüz C'ye alışkın değil, bunun gibi herhangi bir girdi harika. – Frank

cevap

15

Sizin hata buradadır: Burada

benim kod sonra

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

Teşekkürler! Aynı çözümü sadece cevap vermeden önce anları buldum. Seni kışkırtmaya çalıştım ama görünüşe göre bunu yapamam. Gelecekte yığın taşmasını daha fazla kullanmaktan heyecan duyuyorum! Bu harika bir kaynak. – Frank

İlgili konular