Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C write()将输入打印到标准输出而不是管道_C_Pipe - Fatal编程技术网

C 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

我有一个关于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->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被缓冲区溢出覆盖。