c - send char from one program to another through pipe does'nt work -


i trying run program following actions:

  1. fork child process launch compiled c program- draw.out
  2. the parent process waits user input keyboard
  3. input passes draw.out program via pipe
  4. draw.out reads pipe , uses input

here 2 programs, draw.out works fine (tetris game) isn't getting input pipe, mistake?

file 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; } 

file 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 = 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 create handler 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;     (i = 0; < 20; i++)     {         (j = 0; j < 20; j++)         {             if (i != 19 && !(j>0 && j < 19))             {                 strcat(str, "*");             }             else if (i == 19)             {                 strcat(str, "*");             }             else             {                  if (flat == 1 && == t && (j == || j == b || j == c))                 {                     strcat(str, "-");                 }                 else if (flat == 0 && j == b && (i == t || == t - 1 || == t + 1))                 {                     strcat(str, "-");                 }                 else                 {                     strcat(str, " ");                 }             }         }         strcat(str, "\n");     }     puts(str); } 

first: cannot read 1 byte fgets. man fgets:

fgets() reads in @ 1 less size characters stream

as sizeof(input) 1 "one less size" 0. fets read nothing. change fgetc example.

second: kill(getpid() + 1, sigusr2); statement wrong, because assume child have pid of process + 1. wrong assumption, , there no need of such construction, since have childpid variable correctly set.

third: not initalizing ncurses initscr(), getch() won't work. reconfigure terminal add "\n\r" @ end of each line instead of "\n". , don't forget de-initialize ncruses calling endwin() before exiting.

fourth: doing more complicated getting/setting simple variables in signal handlers bad idea. should poll input in main loop using select function, this:

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(); } 

fifth: you're missing break statement in case, both d , a keys decrementing variables, while d should incrementing guess.

here code works:

#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 = 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;     (i = 0; < 20; i++) {     (j = 0; j < 20; j++) {         if (i != 19 && !(j>0 && j < 19)) {             strcat(str, "*");         }         else if (i == 19) {             strcat(str, "*");         } else {             if (flat == 1 && == t && (j == || j == b || j == c)) {                 strcat(str, "-");             } else if (flat == 0 && j == b && (i == t || == t - 1 || == t + 1)) {                 strcat(str, "-");             } else {                 strcat(str, " ");             }         }     }     strcat(str, "\n\r");     }     puts(str); } 

second file:

#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; } 

Comments