2009-12-06 109 views
1

我似乎遇到了管道和選擇的問題。管道故障和選擇()

環境:必須編程東西,將這樣被殼執行:
LOGN [--tick N] CMD [參數] [,在cmd [參數] ...

基本上,它是一個程序多個節目同時進行。

限制條件:每個輸出線具有開始與在格式的printf前它的命令號碼「%d:%S」
即:

0: first line of first command. 
0: second line of first command. 
1: first line of second command. 
0: third line of first command. 
1: second line of second command. 

如果已經指定記號,系統將打印期間,如果沒有輸出已經發送了n秒。 必須使用select() 如果最後一個輸出是一個句點,系統不會打印另一個句點。

問題:

  1. 看來第二個命令的輸出變爲所述第一管道的所述p [0]。
    當我讀入p [0] [0]時,我得到了發送給p [1] [0]的內容。在p [1] [0]中似乎沒有任何東西。

  2. 每當我的選擇發生超時,它似乎卡在那裏。

我之前問過一個問題,所以它可能看起來很熟悉。由於問題不同,我發了一篇新文章。舊帖子幫助我很好地弄清了分岔。

這裏是我的代碼:

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/time.h> 
#include "readline.h" 

/* Fetches the number of commands in parameters. Number of Commas + 1 */ 
int getNbCmd(char ** argv) 
{ 
    int nbCmd = 1; 
    int i = 0;  
    while(argv[i] != '\0') 
    { 
     if(strcmp(argv[i], ",") == 0) 
      nbCmd++; 
     i++; 
    } 
    return nbCmd; 
} 


/* Fills the Command Array */ 
void getCommandes(char *** tbCmd, int argc, char ** argv) 
{  
    int indexArgv = 1; 
    int indexCmd = 0; 
    int indexTbCmd = 0;   

    char ** cmd = (char **)malloc(argc*sizeof(char *)); 
    if(indexArgv < argc) 
    { 
     if(strcmp(argv[indexArgv], "--tick") == 0) 
      indexArgv = 3; 
    } 

    while (indexArgv < argc) 
    { 
     if(strcmp(argv[indexArgv], ",") == 0) 
     {  
      cmd[indexCmd] = (char *) 0; 
      tbCmd[indexTbCmd] = cmd; 
      free(cmd); 
      cmd = (char **)malloc(argc*sizeof(char *)); 

      indexTbCmd++; 
      indexCmd = 0; 
     } 
     else 
     { 
      char * arg; 
      arg = argv[indexArgv]; 
      cmd[indexCmd] = arg;   

      indexCmd++; 
     } 
     indexArgv++; 
    } 

    cmd[indexCmd] = (char *) 0; 
    tbCmd[indexTbCmd] = cmd; 
    free(cmd);   
} 

int main (int argc, char ** argv) 
{ 
    int nbCmds = getNbCmd(argv);  
    int tick = -1;  

    char *** tbCmd = (char ***) malloc (nbCmds*sizeof(char **)); 

    if(argc > 3) 
    { 
     if(strcmp(argv[1], "--tick") == 0) 
      tick = atoi(argv[2]); 
    } 

    getCommandes(tbCmd, argc, argv); 

    int i,j; 

    pid_t pidM[nbCmds];  
    int p[nbCmds][2]; 

    for (i = 0;i < nbCmds;i++) 
    {    
     if (pipe(p[i]) != 0){ perror("pipe()"); exit(1); } 
    } 

    for (i = 0;i < nbCmds;i++) 
    {  
     // fork() to get child process   
     pidM[i] = fork();  

     if (pidM[i] < 0){ perror("fork()"); exit(1); } 
     //Child Processing 
     else if (pidM[i] == 0) 
     { 
      close(p[i][0]); 
      dup2(p[i][1], STDOUT_FILENO); 

      int ret; 
      ret = execvp(tbCmd[i][0], tbCmd[i]); 
      perror("execvp()"); 
     } 
    } 

    // Parent Processing 
    for (i = 0;i < nbCmds;i++) 
    { 
     close(p[i][1]); 
    } 

    char * buffer; 
    int retval = 1; 
    int boolAfficher = 0; 
    int nbNull = 0;   

    fd_set set; 
    struct timeval timeout; 

    /* Initialize the file descriptor set. */ 
    FD_ZERO (&set); 
    for (i = 0;i < nbCmds;i++) 
    { 
     FD_SET (p[i][0], &set);    
    } 

    while(nbNull < nbCmds) 
    { 
     if(tick >= 0) 
     { 
      timeout.tv_sec = (unsigned int)tick; 
      timeout.tv_usec = 0; 
      retval = select (FD_SETSIZE,&set, NULL, NULL, &timeout);     
     } 
     else 
      retval = select (FD_SETSIZE,&set, NULL, NULL, NULL); 

     if(retval == 0) 
     { 
      if(boolAfficher == 0 && tick >= 0) 
      { 
       printf(".\n"); 
       boolAfficher = 1; 
      }     
     } 
     else if(retval > 0) 
     {    
      for (i = 0;i < nbCmds;i++) 
      { 
       if(FD_ISSET(p[i][0], &set)) 
       { 
        buffer = readline(p[i][0]); 
        if(buffer[0] != '\0') 
        { 
         printf("%d: %s", i, buffer); 
        } 
        else 
        { 
         FD_CLR(p[i][0], &set);        
         nbNull++; 
        } 
       } 
       else 
        printf("Not ISSET[%d]\n", i); 

       free(buffer); 
      }     
     } 
     else 
      perror("select()"); 
    } 

    wait(NULL); 
    free(tbCmd); 
    exit(0); 
} 

回答

1

我能搞清楚!

儘管如此手推車時recursivly主叫LOGN

即:./logn --tick 2 ./logn --tick 2 ./cmd1 0未6德塞夫勒,./logn --tick 2個./cmd1 1三河6世嘉

代碼./cmd1

while test "x$#" != "x0"; do 
    sleep $1 
    shift 
    test "x$#" != "x0" || exit 
    echo $1 
    shift 
done 

這裏是我的情況下,固定的代碼它感興趣的人:

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/time.h> 
#include "readline.h" 

/* Fetches the number of commands in parameters. Number of Commas + 1 */ 
int getNbCmd(char ** argv) 
{ 
    int nbCmd = 1; 
    int i = 0;  
    while(argv[i] != '\0') 
    { 
     if(strcmp(argv[i], ",") == 0) 
      nbCmd++; 
     i++; 
    } 

    return nbCmd; 
} 


/* Fills the Command Array */ 
void getCommandes(char *** tbCmd, int argc, char ** argv) 
{  
    int indexArgv = 1; 
    int indexCmd = 0; 
    int indexTbCmd = 0;   

    char ** cmd = (char **)malloc(argc*sizeof(char *)); 
    if(indexArgv < argc) 
    { 
     if(strcmp(argv[indexArgv], "--tick") == 0) 
      indexArgv = 3; 
    } 

    while (argv[indexArgv] != '\0') 
    { 
     if(strcmp(argv[indexArgv], ",") == 0) 
     { 

      cmd[indexCmd] = (char *) 0; 
      tbCmd[indexTbCmd] = cmd;     
      cmd = (char **)malloc(argc*sizeof(char *));     

      indexTbCmd++; 
      indexCmd = 0; 
     } 
     else 
     { 

      char * arg; 
      arg = argv[indexArgv]; 
      cmd[indexCmd] = arg;   

      indexCmd++; 
     } 
     indexArgv++; 
    } 


    cmd[indexCmd] = (char *) 0; 
    tbCmd[indexTbCmd] = cmd; 
    free(cmd);   
} 


int main (int argc, char ** argv) 
{ 
    int nbCmds = getNbCmd(argv); 

    int tick = -1;  

    char *** tbCmd = (char ***) malloc (nbCmds*sizeof(char **)); 

    if(argc > 3) 
    { 
     if(strcmp(argv[1], "--tick") == 0) 
      tick = atoi(argv[2]); 
    } 

    getCommandes(tbCmd, argc, argv); 

    int i,j;   

    pid_t pidM[nbCmds];  
    int p[nbCmds][2]; 

    for (i = 0;i < nbCmds;i++) 
    {    
     if (pipe(p[i]) != 0){ perror("pipe()"); exit(1); } 
    } 

    for (i = 0;i < nbCmds;i++) 
    {  
     // fork() to get child process   
     pidM[i] = fork();  

     if (pidM[i] < 0){ perror("fork()"); exit(1); } 
     //Child Processing 
     else if (pidM[i] == 0) 
     { 
      close(p[i][0]);        
      dup2(p[i][1], STDOUT_FILENO);     
      int ret; 

      ret = execvp(tbCmd[i][0], tbCmd[i]); 
      perror("execvp()"); 
      _exit(1); 
     } 
    } 

    // Parent Processing 

    for (i = 0;i < nbCmds;i++) 
    { 
     close(p[i][1]); 
    } 

    char * buffer = NULL;   
    int retval = 1; 
    int boolAfficher = 0; 

    int nbNull = 0; 
    int isOk[nbCmds]; 

    for (i = 0;i < nbCmds;i++) 
    { 
     isOk[i] = 1; 
    } 

    fd_set set; 
    struct timeval timeout; 

    while(nbNull < nbCmds) 
    { 
     FD_ZERO (&set); 
     for (i = 0;i < nbCmds;i++) 
     {  
      if(isOk[i] == 1) 
       FD_SET (p[i][0], &set); 
     } 

     if(tick > 0) 
     { 
      timeout.tv_sec = (unsigned int)tick; 
      timeout.tv_usec = 0; 
      retval = select (FD_SETSIZE,&set, NULL, NULL, &timeout);     
     } 
     else 
     { 
      timeout.tv_sec = 0; 
      timeout.tv_usec = 0; 
      retval = select (FD_SETSIZE,&set, NULL, NULL, &timeout);  
     } 

     if(retval == 0) 
     { 
      if(boolAfficher == 0 && tick >= 0) 
      { 
       printf(".\n"); 
       boolAfficher = 1; 
      }      
     } 
     else 
     { 
      for (i = 0;i < nbCmds;i++) 
      { 
       if(FD_ISSET(p[i][0], &set)) 
       {        
        buffer = readline(p[i][0]); 
        if(buffer[0] != '\0') 
        { 
         printf("%d: %s", i, buffer); 
         boolAfficher = 0; 
        } 
        else 
        { 
         isOk[i] = 0; 
         nbNull++; 
        } 
        free(buffer); 
       } 
      } 
     } 
    } 

    wait(NULL); 
    free(tbCmd); 
    exit(0); 
} 
+0

我會記住這爲answe河它將它從未答覆的Q列表中刪除,如果它得到3個upvotes,就會獲得徽章。 (不知道你是否也得到了代表。 – Edd 2010-02-22 13:14:11