发送字符从一个程序到另一个通过管道一点儿也不工作

问题描述:

我试图运行一个程序,它采取以下行动:发送字符从一个程序到另一个通过管道一点儿也不工作

  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); “这将处理不是为了角色。也许'读'来镜像'写'? –

第一:你不能用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

哇!非常感谢你的冗长答案,它的工作 –