C write()将输入打印到标准输出而不是管道
我有一个关于write()和管道的问题。C write()将输入打印到标准输出而不是管道,c,pipe,C,Pipe,我有一个关于write()和管道的问题。 我已将问题缩小到这两个代码片段,一个用于写入管道,一个用于检查是否发生了任何事情: 父进程: char* reply = malloc(sizeof(char) * 15); addchar(reply); if (shm->nextStone == -1) { sprintf(reply, "PLAY %s", shm->nextField); } else { sprintf(reply, "PLAY %s,%d", shm-&g
我已将问题缩小到这两个代码片段,一个用于写入管道,一个用于检查是否发生了任何事情: 父进程:
char* reply = malloc(sizeof(char) * 15);
addchar(reply);
if (shm->nextStone == -1) {
sprintf(reply, "PLAY %s", shm->nextField);
} else {
sprintf(reply, "PLAY %s,%d", shm->nextField, shm->nextStone);
}
err = write(fd[1], reply, 15);
(...)
rc = select(biggest + 1, &fds, NULL, NULL, &timeout);
(...)
else if (FD_ISSET(pipe, &fds)) {
doMove(sock, buffer, fd); //read is going to be called here
}
子进程:
char* reply = malloc(sizeof(char) * 15);
addchar(reply);
if (shm->nextStone == -1) {
sprintf(reply, "PLAY %s", shm->nextField);
} else {
sprintf(reply, "PLAY %s,%d", shm->nextField, shm->nextStone);
}
err = write(fd[1], reply, 15);
(...)
rc = select(biggest + 1, &fds, NULL, NULL, &timeout);
(...)
else if (FD_ISSET(pipe, &fds)) {
doMove(sock, buffer, fd); //read is going to be called here
}
它在大多数情况下工作正常,但在程序运行一段时间后,write()的行为异常:
它没有将输入写入管道(fd),而是像printf一样将输入打印到控制台
FD_ISSET返回false,因为没有向管道写入任何内容,并且我的程序超时。我就是不明白为什么,也没有找到任何关于write()随机打印的信息。有人知道为什么会这样吗?提前谢谢
编辑:我只是在子进程中分配fd[0],除了关闭和写入之外,不使用fd[1]执行任何操作。这可能是问题所在吗?下面是我的合作伙伴在子进程中分配fd[0]的部分。此外,缓冲区流不是一个问题,我认为,它从来没有超出发挥A3,2例如
int waitforfds(int sock, char* buffer, sharedmem * shm, int fd[]) {
int rc, size, status, biggest;
int pipe = fd[0];
fd_set fds;
struct timeval timeout;
if (pipe > sock) {
biggest = pipe;
} else {
biggest = sock;
}
do {
(...)
FD_SET(sock, &fds);
FD_SET(pipe, &fds);
(...)
rc = select(biggest + 1, &fds, NULL, NULL, &timeout);
if (rc == -1) {
perror("Error, select failed! \n");
return EXIT_FAILURE;
if (rc > 0) {
if (FD_ISSET(sock, &fds)) {
(...)
}
} else if (FD_ISSET(pipe, &fds)) {
doMove(sock, buffer, fd);
}
} else if (rc == 0) {
perror("Select timed out!. \n");
}
}
while (rc != 0);
(...)
第二次编辑:
我想我知道了,我在主函数上面全局声明了fd,出于某种原因导致了未定义的行为。我真的不知道为什么,但在我改变它之后,它似乎又起作用了。还感谢Jonathan告诉我fd的值可能为0
int fd[2];
int main(int argc, char** argv) {
到
你在哪里打开的管子?显示分配的
fd[1]
的位置。某些sprintf(reply,
没有溢出reply
?15看起来很小。发生这种情况的明显方式是如果fd[1]
被1或2覆盖;不太明显的0值也会经常起作用(并且可能更像fd[1]中的值)
)因为终端的连接方式通常意味着标准输入实际上是可写的,标准输出和标准错误实际上是可读的。所以,检查fd[1]
…中的值,如果它被覆盖,你就必须找出原因。有趣的谢谢!我刚刚检查了和fd[1]错误发生时,在我写入之前为0。通常为5。我将尝试找出why@user3215972:在调试器中使用观察点。最好是硬件观察点,通常是这样。其工作原理是,每当写入特定内存位置时,会要求硬件中断。如果该值为g被缓冲区溢出覆盖。