2016-01-24 19 views
1

我試圖運行一個程序,它採取以下行動:發送字符從一個程序到另一個通過管道一點兒也不工作

  1. 叉一個子進程,將推出另一編譯的C程序 - draw.out
  2. 父進程然後從鍵盤
  3. 輸入用於用戶等待輸入隨後經由管
  4. draw.out從管道中讀取傳遞給draw.out程序,並使用該輸入

這裏有兩個程序,draw.out工作正常(俄羅斯方塊遊戲),但沒有從管道輸入,我的錯誤是什麼?

文件1:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <signal.h> 
#include <sys/wait.h> 
#include <errno.h> 
#include <stdlib.h> 
#include <curses.h> 
#include <string.h> 


int main(void) 
{ 
    int  fd[2], childpid; 
    //pid_t childpid; 
    char input = 'o'; 
    char readbuffer[80]; 

    pipe(fd); 

    if ((childpid = fork()) == -1) 
    { 
     perror("fork"); 
     exit(1); 
    } 

    if (childpid == 0) 
    { 
     close(0); 
     dup(fd[0]); 
     execl("draw.out", NULL); 


    } 
    else 
    { 
     close(fd[0]); 
     while (input != 'q') 
     { 
      input = getch(); 
      if (input == 'a' || input == 's' || input == 'd' || input == 'w' || input == 'q') 
      { 
       write(fd[1], &input, 1); 
       kill(getpid() + 1, SIGUSR2); 
      } 

     } 
     exit(0); 

    } 

    return 1; 
} 

文件2:

#include <signal.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h> 



void print_screen(int a, int b, int c, int t, int flat); 
void my_handler(int signum); 

int a = 9, b = 10, c = 11, t = 0, flat = 1; 
int newfd = 0; 

int main(void) 
{ 


    if (signal(SIGUSR2, my_handler) == SIG_ERR) 
    { 
     printf("Pærent: Unable to create handler for SIGUSR2\n"); 
    } 
    while (t < 20) 
    { 
     system("clear"); 
     print_screen(a, b, c, t, flat); 
     sleep(1); 
     t++; 
    } 



} 

void my_handler(int signum) 
{ 
    if (signum == SIGUSR2) 
    { 
     printf("signal arrived"); 
     char input; 
     fgets(&input, sizeof(input), stdin); 
     switch (input) 
     { 
     case 'a': 
      if (a > 1) 
      { 
       a--; 
       b--; 
       c--; 
      } 
      break; 
     case 's': 
      t++; 
      break; 
     case 'd': 
      if (c < 18) 
      { 
       a--; 
       b--; 
       c--; 
      } 
     case 'w': 
      if (flat == 1) 
      { 
       flat = 0; 
      } 
      else 
      { 
       if (b<18 && b>1) 
       { 
        flat = 1; 
       } 
      } 
      break; 
     case 'q': 
      exit(0); 

     } 
    } 
} 


void print_screen(int a, int b, int c, int t, int flat) 
{ 
    char str[420] = "\n"; 
    int i, j; 
    for (i = 0; i < 20; i++) 
    { 
     for (j = 0; j < 20; j++) 
     { 
      if (i != 19 && !(j>0 && j < 19)) 
      { 
       strcat(str, "*"); 
      } 
      else if (i == 19) 
      { 
       strcat(str, "*"); 
      } 
      else 
      { 

       if (flat == 1 && i == t && (j == a || j == b || j == c)) 
       { 
        strcat(str, "-"); 
       } 
       else if (flat == 0 && j == b && (i == t || i == t - 1 || i == t + 1)) 
       { 
        strcat(str, "-"); 
       } 
       else 
       { 
        strcat(str, " "); 
       } 
      } 
     } 
     strcat(str, "\n"); 
    } 
    puts(str); 
} 
+1

這是什麼'殺號(getpid()+ 1,SIGUSR2);'?這裏假設 –

+1

'dup(fd [0]);''可能需要'dup2' - http://linux.die.net/man/2/dup2 –

+0

'fgets(&input,sizeof(input),stdin); 「這將處理不是爲了角色。也許'讀'來鏡像'寫'? –

回答

2

第一:你不能用fgets讀一個字節。從man fgets

與fgets()從流至多一個小於大小的字符讀取

作爲的sizeof(輸入)「比大小小於一個」 1爲0。因此場效應管將讀取沒什麼。例如,將其更改爲fgetc。

第二個:kill(getpid() + 1, SIGUSR2);聲明顯然是錯誤的,因爲你假設你的孩子會有你的進程+ 1的PID。這是錯誤的假設,並且不需要這樣的構造,因爲你有childpid變量正確設置。

第三:你沒有使用initscr()創建ncurses,所以getch()不起作用。由於這也將重新配置您的終端在每行的末尾添加「\ n \ r」而不是「\ n」。並且不要忘記在退出之前取消初始化調用endwin()的ncruses。第四:做比信號處理程序中獲取/設置簡單變量更復雜的任何事情通常是一個非常糟糕的主意。你應該使用select功能poll在你的主迴路輸入,就像這樣:

struct timeval time; 
time.tv_sec = 0; 
time.tv_usec = 0; 
fd_set set; 
FD_ZERO(&set); 
FD_SET(0, &set); 
if (select(1, &set, NULL, NULL, &time) > 0) { 
    handle_input(); 
} 

第五:你缺少break聲明你的情況,也都da鍵遞減變量,而d應我猜想會遞增。

這裏是工作的代碼:

#include <signal.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h> 

void print_screen(int a, int b, int c, int t, int flat); 
void handle_input(void); 

int a = 9, b = 10, c = 11, t = 0, flat = 1; 
int newfd = 0; 

int main(void) { 
    int t = 0; 
    while (t < 20) { 
     system("clear"); 
     print_screen(a, b, c, t, flat); 
     sleep(1); 
     struct timeval time; 
     time.tv_sec = 0; 
     time.tv_usec = 0; 
     fd_set set; 
     FD_ZERO(&set); 
     FD_SET(0, &set); 
     if (select(1, &set, NULL, NULL, &time) > 0) { 
      handle_input(); 
     } 
     t++; 
    } 
    return 0; 
} 

void handle_input() { 
    char input; 
    input = fgetc(stdin); 
    switch (input) { 
    case 'a': 
     printf("a\n"); 
     if (a > 1) { 
      a--; 
      b--; 
      c--; 
     } 
     break; 
    case 's': 
     t++; 
     break; 
    case 'd': 
     if (c < 18) { 
      a++; 
      b++; 
      c++; 
     } 
     break; 
    case 'w': 
     if (flat == 1) { 
      flat = 0; 
     } else { 
      if (b<18 && b>1) { 
       flat = 1; 
      } 
     } 
     break; 
    case 'q': 
     exit(0); 
    } 
} 


void print_screen(int a, int b, int c, int t, int flat) { 
    char str[4200] = "\n"; 
    int i, j; 
    for (i = 0; i < 20; i++) { 
    for (j = 0; j < 20; j++) { 
     if (i != 19 && !(j>0 && j < 19)) { 
      strcat(str, "*"); 
     } 
     else if (i == 19) { 
      strcat(str, "*"); 
     } else { 
      if (flat == 1 && i == t && (j == a || j == b || j == c)) { 
       strcat(str, "-"); 
      } else if (flat == 0 && j == b && (i == t || i == t - 1 || i == t + 1)) { 
       strcat(str, "-"); 
      } else { 
       strcat(str, " "); 
      } 
     } 
    } 
    strcat(str, "\n\r"); 
    } 
    puts(str); 
} 

第二個文件:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <signal.h> 
#include <sys/wait.h> 
#include <errno.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ncurses.h> 

int main(void) { 
    int  fd[2]; 
    pid_t childpid; 
    char input = 'o'; 

    pipe(fd); 

    if ((childpid = fork()) == -1) { 
     perror("fork"); 
     exit(1); 
    } 

    if (childpid == 0) { 
     close(0); 
     dup(fd[0]); 
     execl("draw.out", "draw.out", NULL); 
    } else { 
     close(fd[0]); 
     initscr(); 
     while (input != 'q') { 
      read(0, &input, 1); 
      if (input == 'a' || input == 's' || input == 'd' || input == 'w' || input == 'q') { 
       write(fd[1], &input, 1); 
      } 
     } 
     endwin(); 
     exit(0); 
    } 

    return 0; 
} 
+0

我什至不能看到信號的價值...... –

+0

理想情況下,兩個進程都將關閉所有不使用的管道fds。 –

+0

哇!非常感謝你的冗長答案,它的工作 –

相關問題