免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2350 | 回复: 5
打印 上一主题 下一主题

用ioctl传递文件描述符的奇怪现像( SCO 5.05 ) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-04-06 11:21 |只看该作者 |倒序浏览
由于编写复杂的转发程序,用了传递文件描述符的方式。 可是在编写的过程中出现了一些问题,望高手指点。

程序如下

#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 );
是不是还要加上别的操作。望高手指教。

论坛徽章:
0
2 [报告]
发表于 2005-04-06 11:47 |只看该作者

用ioctl传递文件描述符的奇怪现像( SCO 5.05 )

子进程自动继承各父进程的fd, 不需要传递。
如果fork()后有不同的fd操作,那么pipe, dup, dup2就可以了。
fd是和自己进程相关的,关闭了的仅仅是自己进程的。

论坛徽章:
0
3 [报告]
发表于 2005-04-06 13:56 |只看该作者

用ioctl传递文件描述符的奇怪现像( SCO 5.05 )

误解我的意思了。 我只是用文件来实现这个程序,因为比较简单。 本意是用父进程进行accept 再将描述符传给子进程。这样就不用化时间在fork()上了。
所以程序是先fork() 后再打开文件的。

论坛徽章:
0
4 [报告]
发表于 2005-04-06 14:31 |只看该作者

用ioctl传递文件描述符的奇怪现像( SCO 5.05 )

linux上有I_FDINSERT吗?

无论有无,FD是和进程相关的,仅仅是一个index to struct file.
一个关了,另一个进程为什么不能读?
文件SEEK_POS和FD无关,而在struct file中,一个进程读了,POS就移动了,
另一个就从那里开始读

论坛徽章:
0
5 [报告]
发表于 2005-04-06 14:54 |只看该作者

用ioctl传递文件描述符的奇怪现像( SCO 5.05 )

多谢了。试了一下。确实这样。 现在就是不知道除了用 /dev/spx 外 还能不能用 pipe() 或是 socketpair 实现。

论坛徽章:
0
6 [报告]
发表于 2005-04-12 10:49 |只看该作者

用ioctl传递文件描述符的奇怪现像( SCO 5.05 )

/dev/spx 和 pipe   socketpair 等有什么区别???
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP