- 论坛徽章:
- 0
|
由于编写复杂的转发程序,用了传递文件描述符的方式。 可是在编写的过程中出现了一些问题,望高手指点。
程序如下
#include <stdio.h>;
#include <sys/types.h>;
#include <sys/stat.h>;
#include <sys/stream.h>;
#include <stropts.h>;
#include <fcntl.h>;
#include <sys/types.h>;
#define SPX "/dev/spx"
int main( )
{
int fd[2];
int filefd;
struct strrecvfd recvfd ;
struct strfdinsert ins;
int pid ;
int rv ;
char buff[100] ;
if ( (fd[0] = open(SPX, O_RDWR)) < 0)
{
perror( "fd[0] open error" ) ;
return(-1);
}
if ( (fd[1] = open(SPX, O_RDWR)) < 0)
{
perror( "fd[0] open error" ) ;
close(fd[0]);
return(-1);
}
ins.ctlbuf.buf = (char *) &ins ;
ins.ctlbuf.maxlen = sizeof(queue_t *);
ins.ctlbuf.len = sizeof(queue_t *);
ins.databuf.buf = (char *) 0;
ins.databuf.len = -1;
ins.databuf.maxlen = 0;
ins.fildes = fd[1];
ins.flags = 0;
ins.offset = 0;
if (ioctl(fd[0], I_FDINSERT, (char * ) &ins ) < 0)
{
perror( "ioctl fd[0] error" ) ;
close(fd[0]);
close(fd[1]);
return(-1);
}
pid = fork() ;
if ( pid < 0 ) exit ( -1 ) ;
else if ( pid >;0 )
{
close( fd[0] ) ;
if ((filefd = open("./aaa", O_CREAT|O_RDWR)) < 0)
{
perror("open of sample text file failed" ;
exit(-1);
}if ( ioctl( fd[1], I_SENDFD, filefd ) < 0 )
{
perror("ioctl I_SENDFD failed" ;
exit(-1);
}
printf( "[%d] send[%d] to child \n" , getpid() , filefd ) ;
close( fd[1]) ;
sleep (2);
memset( buff , 0x00 , sizeof( buff ) ) ;
read( filefd , buff , 5 ) ;
printf( "[%d][%d] [%s]\n" , getpid() , filefd , buff ) ;
exit(0);
}
else if ( pid == 0 )
{
close( fd[1]) ;
if (ioctl( fd[0], I_RECVFD, &recvfd) < 0)
{
perror("ioctl I_RECVFD failed" ;
exit(-1);
}
filefd = recvfd.fd;
memset( buff , 0x00 , sizeof( buff )) ;
read( filefd , buff , 5 ) ;
printf( "[%d][%d] [%s]\n" , getpid() , filefd , buff ) ;
close( filefd ) ;
close( fd[0] ) ;
exit(0) ;
}
}
相关处理:
在./aaa中输入 1234567890 十个字符。 运行程序。结果如下
[3919] send[3] to child
[3920][4] [12345]
[3919][3] [67890]
结果说明描述符传递成功了。可是有如下问题。
1。在子进程读了前5个字符后关闭描述符后父进程还是能读,而且很奇怪了读出了后面5个字符。 按我的理解,文件描述符每个进程间是无关的。那么父进程也应该读出前5个。就算是相关的,那子进程关闭了后,为什么父进程还能读到?这里的结果实在让我无法理解。
2。 这里的 fd[2] 如果用 pipe 或是 socketpair都不能成功传递描述符。
pipe( fd ) ;
socketpair( AF_UNIX, SOCK_STREAM, 0, fd );
是不是还要加上别的操作。望高手指教。 |
|