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

时间:2016-01-24 17:12:30

标签: c linux pipe

I am trying to run a program that does following actions:

  1. Fork a child process that will launch another compiled c program- draw.out
  2. The parent process then waits for user to input from keyboard
  3. Input then passes to the draw.out program via a pipe
  4. draw.out reads from pipe and uses the input

Here are the two programs, draw.out works fine (Tetris game) but isn't getting input from pipe, what is my 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 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 个答案:

答案 0 :(得分:2)

首先:你不能用fgets读取一个字节。来自man fgets

  

fgets()从流

中读取最多一个小于大小的字符

sizeof(输入)是1&#34;比size&#34;是0.因此,足球将不会读。例如,将其更改为fgetc。

第二:kill(getpid() + 1, SIGUSR2);陈述显然是错误的,因为你认为你的孩子将拥有你的过程的pid + 1.这是错误的假设,并且不需要这样的构造,因为你有{{1} }变量正确设置。

第三:你没有childpid使用ncurses,所以initscr()不会工作。因为这也将重新配置您的终端添加&#34; \ n \ r&#34;在每一行的末尾而不是&#34; \ n&#34;。并且在退出之前不要忘记取消初始化调用getch()的ncruses。

第四:做一些比在信号处理程序中获取/设置简单变量更复杂的事情通常是一个非常糟糕的主意。您应该endwin()使用poll函数在主循环中输入,如下所示:

select

第五:您在案例中错过了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(); } 语句,同时breakd键都是递减变量,而a应该递增I {}猜测。

以下是有效的代码:

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