无法从重定向的io读取数据

时间:2013-03-21 05:15:02

标签: c linux fork pipe stdout

我编写了一段相对简单的代码,用于轮询在子进程中重定向为stdout的管道。但是当poll函数返回并且表示数据准备就绪时,read函数总是返回零。

有什么理由可以说明为什么这不起作用?当我从子进程直接写入管道到父进程时,它工作正常。我想我只是错误地重定向io。

这是父流程代码:

注意:所有宏都会出错并将其打印到错误日志中。

pollData.fd = out.fd[ READ_INDEX ];
pollData.events = POLL_IN;
pollData.revents = 0;

printf( "Polling pipe for data...\n" );

if( poll( &pollData, 1, 5000 ) > 0 )
{
        int bytesRead = 0, trys = TRYS;
        printf( "Data has been received: " );

        Read:

        bytesRead = read( out.fd[ READ_INDEX ] , out.buf, BUF_SIZE );

             if( bytesRead > 0 ) printf( "%s" , out.buf );
        else if( bytesRead < 0 ) printf( "Error receiving data.\n" );
        else
        {
                trys--;
                printf( "No data was read.\n" );
                sleep( SLEEP );
                if( trys > 0 ) goto Read;
        }
}
else LOG( ERR_POLLING, 0 );

这是子进程代码: 注意:FD_REPLACE使用dup2并关闭旧句柄。

FD_CLOSE_PACK(  out.fd[  READ_INDEX ],
                err.fd[  READ_INDEX ],
                 in.fd[ WRITE_INDEX ] );

FD_REPLACE( fileno( stdout ) , out.fd[ WRITE_INDEX ] , Child_Fail );
FD_REPLACE( fileno( stderr ) , err.fd[ WRITE_INDEX ] , Child_Fail );
FD_REPLACE( fileno( stdin  ) ,  in.fd[  READ_INDEX ] , Child_Fail );

printf( "This is a message from the test program!\n Hope it works!\n" );

sleep( 10 );

Child_Fail:

FD_CLOSE_PACK(  out.fd[ WRITE_INDEX  ],
                err.fd[ WRITE_INDEX  ],
                 in.fd[  READ_INDEX  ] );
return -1;

这是其中一个宏:

#define FD_REPLACE( old_fd, fd , addr )        
if( dup2( old_fd, fd ) < 0 )                                          
{ 
        LOG( ERR_DUP2, #old_fd " with " #fd );                 
        goto addr;           
}        

这是终端的输出:

Polling pipe for data...
Data has been received: No data was read.
No data was read.
No data was read.
No data was read.
No data was read.

Now closing...

1 个答案:

答案 0 :(得分:1)

我得到了它的工作。我错误地替换了文件描述符。我替换了错误的描述符,我在关闭旧的描述符之前就这样做了。我上面发布的代码显示了旧的宏。新宏是(没有错误检查):

#define FD_REPLACE( old_fd, fd, addr )
close( old_fd );
dup2( fd, old_fd );