发送字符从一个程序到另一个通过管道一点儿也不工作
我试图运行一个程序,它采取以下行动:发送字符从一个程序到另一个通过管道一点儿也不工作
- 叉一个子进程,将推出另一编译的C程序 - draw.out
- 父进程然后从键盘
- 输入用于用户等待输入随后经由管
- 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);
}
第一:你不能用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
声明你的情况,也都d
和a
键递减变量,而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;
}
我什至不能看到信号的价值...... –
理想情况下,两个进程都将关闭所有不使用的管道fds。 –
哇!非常感谢你的冗长答案,它的工作 –
这是什么'杀号(getpid()+ 1,SIGUSR2);'?这里假设 –
'dup(fd [0]);''可能需要'dup2' - http://linux.die.net/man/2/dup2 –
'fgets(&input,sizeof(input),stdin); “这将处理不是为了角色。也许'读'来镜像'写'? –