c - 输出文件描述符重定向到管道的进程正在屏幕而不是管道上写入

标签 c linux pipe

所以这是我的代码,socket、nameExecutable和commandLineArgs都是函数接收的参数。

我的问题是新进程没有写入其管道,而是写入终端。

此代码的目标是让子进程将其输出写入父进程,然后父进程通过套接字发送它,当通过套接字接收到内容时,父进程将其发送给子进程进行处理。

char bufferWriteToClient[BUFFER_WRITE_SIZE],bufferReadFromClient[BUFFER_READ_SIZE];
pid_t pid;
fd_set readSet;
FD_ZERO(&readSet);
struct timeval timeVal;
int pipeDad[2],pipeSon[2],returnState;
if (pipe(pipeDad) < 0)
    return -1;
if (pipe(pipeSon) < 0){
    close(pipeDad[0]);
    close(pipeDad[1]);
    return -1;
} // End of pipe initialization


switch ((pid = fork())){
case -1:
    close(pipeDad[0]);
    close(pipeDad[1]);
    close(pipeSon[0]);
    close(pipeSon[1]);
    return -1;
case 0:
    // Duplicate new process stdin and stdout to be the parents pipe received end and childs pipe writing end

    dup2(STDIN_FILENO,pipeDad[0]);
    dup2(STDOUT_FILENO,pipeSon[1]);

    // Close the ends we don't need
    close(pipeSon[0]);
    close(pipeDad[1]);
    execv(nameExecutable,commandLineArgs);
    break;
default:
    // Close the ends attributed to the child process
    close(pipeDad[0]);
    close(pipeSon[1]);
    // --------------------------------
    while (!waitpid(pid,&returnState,WNOHANG)){
        int retValSelect;
        FD_SET(pipeSon[0],&readSet);
        FD_SET(socket,&readSet);
        timeVal.tv_sec = 3;
        timeVal.tv_usec = 0;
        retValSelect = select(pipeSon[0] > socket ? pipeSon[0]+1:socket+1,&readSet,NULL,NULL,&timeVal);
        if (retValSelect == -1){
            return -1;
        }
        if (FD_ISSET(pipeSon[0],&readSet)){
            int receivedBytes = readUpToData(socket,bufferWriteToClient,sizeof(bufferWriteToClient)-1);
            if (receivedBytes == -1)
                return -1;
            if (bufferWriteToClient[receivedBytes] != '\0')
                bufferWriteToClient[receivedBytes+1] = '\0';
            sendData(socket,bufferWriteToClient,strlen(bufferWriteToClient)+1);
        }
        if (FD_ISSET(socket,&readSet)){
            int receivedBytes = readUpToData(socket,bufferReadFromClient,sizeof(bufferReadFromClient)-1);
            if (receivedBytes == -1)
                return -1;
            if (bufferReadFromClient[receivedBytes] != '\0')
                bufferReadFromClient[receivedBytes+1] = '\0';
            sendData(pipeDad[1],bufferReadFromClient,strlen(bufferReadFromClient)+1);
        }
    }
    break;
}

所以在我进入 switch 中的默认情况之前,子进程已经写入终端,谁能告诉我我做错了什么?

最佳答案

看起来你颠倒了 dup2() 的参数。来自 dup(2) 手册页:

NAME dup, dup2, dup3 - duplicate a file descriptor

SYNOPSIS

   #include <unistd.h>

   int dup(int oldfd);
   int dup2(int oldfd, int newfd);

关于c - 输出文件描述符重定向到管道的进程正在屏幕而不是管道上写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28182823/

相关文章:

c - 如何读取用户在 C 中输入的字符串?

python - 如何使 Python 模块可共享?

r - dplyr 。和 _no 全局变量 '.' 的可见绑定(bind) _ 包检查中的注意事项

c - Linux。 C 中的管道。将数据发送到另一个进程。写作和阅读

c - 使用 NASM 构建 KMP 前缀

特定 ISR 后上下文切换到特定进程

c++ - Makefile vpath 不适用于头文件

linux - 在wayland 中设置虚拟分辨率

linux - Bash Last Carriage 字符,换行符剥离

Bash:欺骗程序认为 stdout 是一个交互式终端