• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

SCO提供的不相关进程间传递描述符的例子!!!

发布: 2007-6-08 22:43 | 作者: seanhe | 来源: | 查看: 32次 | 进入软件测试论坛讨论

领测软件测试网
[color=blue:0046d02c9b]测试一下,没有问题。原来的程序有一点BUG,已经改正。[/color:0046d02c9b]  

named streams pipe /unix kernel example source code sample I_SENDFD I_FDINSERT ioctl af_unix
domain sockets socketpair pass file descriptor /dev/spx I_RCVFD openserver 5.0.0 5.0.2 faststart
1.0.0 1.0.1 full duplex bidrectional

Release 
SCO OpenServer Enterprise System Release 5.0.0, 5.0.2
SCO OpenServer Desktop System Release 5.0.0, 5.0.2
SCO FastStart Release 1.0.0, 1.0.1
SCO OpenServer Development System Release 5.0.0, 5.0.2
SCO Open Desktop Release 3.0
SCO Open Desktop Development System Release 3.0
SCO UNIX System V/386 Release 3.2 Development System Version 4.2 


How are the I_SENDFD and I_RCVFD ioctl()s properly used? -or- Is there an alternative to 
Unix Domain Sockets and passing file descriptors via "access rights" in sendmsg(SSC) and 
recvmsg(SSC) function calls, in SCO OpenServer 5? Is there a workaround to the current 
lack of support for Unix Domain Sockets in SCO Open Desktop Release 3.0?

The following source code consists of three files. These three files illustrate the proper 
use of the I_SENDFD ioctl(S). This provides a functionality similar to Unix Domain sockets 
and BSD-style stream pipes. In this example, the server process creates an unnamed streams 
pipe by performing open(S) on the streams cloning device /dev/spx twice, and calling the 
I_FDINSERT ioctl() function to link the two streams together, thus creating the two ends of 
the pipe. The mknod(S) system call is then used to attach the name "/tmp/nspipe.serv" to one 
of the file descriptors. This end is then connected to by the client process via open() of 
this file name. The client sends a well-known request byte over the pipe and is received by 
the server. The server then satisfies the request by sending an open file descriptor to the 
file "/tmp/sample_file". Finally, the client makes use of the passed descriptor by writing to 
the end of the file. 

Makefile:
----------------------------------------------------------------------
all: server client

server: server.c
         cc $(CFLAGS) -o server server.c
client: client.c
         cc $(CFLAGS) -o client client.c

clean:
         -rm -f core /tmp/nspipe.serv /tmp/sample_file client server
----------------------------------------------------------------------


client.c
----------------------------------------------------------------------
#include        <stdio.h>
#include        <sys/types.h>
#include        <sys/stat.h>
#include        <sys/stream.h>          /* defines queue_t */
#include        <stropts.h>             /* defines struct strfdinsert */
#include        <fcntl.h>

#define NSPIPESERV      "/tmp/nspipe.serv"
#define REQ             5

main()
{
        int servfd, filefd, nwrite;
        char buf[2];
        char newbuf[11]="abcdefghij";
        struct strrecvfd recvfd;
        struct stat filstat;

        if ((servfd = open(NSPIPESERV, O_RDWR)) < 0)
        {
                perror("open of server pipe failed");
                exit(1);
        }

        buf[0] = REQ;
        if (write(servfd, buf, 1) != 1)
        {
                perror("couldn't write request byte");
                exit(1);
        }
        if (ioctl( servfd, I_RECVFD, &recvfd) < 0)
        {
                printf("I_RECVFD failed\n");
                exit(1);
        }
        filefd = recvfd.fd;
        if (filefd < 3)
        {
                printf("filefd is not valid\n");
                exit(1);
        }
        /* now try appending to the file */

        if (fstat( filefd, &filstat  < 0)
        perror( "fstat error" ;
        else
        printf("file size before write is: %lu\n", filstat.st_size);

        if ( lseek(filefd, 0, 2) < 0 
        {
                printf( "lseek to end of file error" ;
                exit(1);
        }
        if ( (nwrite = write(filefd, newbuf, 10)) < 0)
        perror( "write error to passed text file fd" ;
        else
        {
                printf("write to text file fd successful\n");
                printf("%d bytes written: %s\n", nwrite, newbuf);
        }

        if (fstat( filefd, &filstat  < 0)
        perror( "fstat error" ;
        else
        printf("file size after write is: %lu\n", filstat.st_size);

        exit(0);
}
----------------------------------------------------------------------


server.c
-------------------------------------------------------------------
#include        <stdio.h>
#include        <sys/types.h>
#include        <sys/stat.h>
#include        <sys/stream.h>          /* defines queue_t */
#include        <stropts.h>             /* defines struct strfdinsert */
#include        <fcntl.h>


#define SPX_DEVICE      "/dev/spx"
#define NSPIPESERV      "/tmp/nspipe.serv"
#define REQ             5
#define SAMPLEFILE      "/tmp/sample_file"

int s_pipe(fd)
int     fd[2];          /* two file descriptors returned through here */
{
        struct strfdinsert      ins;
        queue_t                 *pointer;

        /*
         * First open the stream clone device "/dev/spx" twice,
         * obtaining the two file descriptors.
         */

        if ( (fd[0] = open(SPX_DEVICE, O_RDWR)) < 0)
                return(-1);

        if ( (fd[1] = open(SPX_DEVICE, O_RDWR)) < 0)
        {
                close(fd[0]);
                return(-1);
        }

        /*
         * Now link these two streams together with an I_FDINSERT ioctl.
         */

        ins.ctlbuf.buf     = (char *) & /* no ctl info, just the ptr */
        ins.ctlbuf.maxlen  = sizeof(queue_t *);
        ins.ctlbuf.len     = sizeof(queue_t *);

        ins.databuf.buf    = (char *) 0;        /* no data to send */
        ins.databuf.len    = -1; /* magic: must be -1, not 0, for stream pipe */
        ins.databuf.maxlen = 0;

        ins.fildes = fd[1];     /* the fd to connect with fd[0] */
        ins.flags  = 0;         /* nonpriority message */
        ins.offset = 0;         /* offset of pointer in control buffer */

        if (ioctl(fd[0], I_FDINSERT, (char *  &ins) < 0)
        {
                close(fd[0]);
                close(fd[1]);
                return(-1);
        }

        return(0);              /* all OK */
}

int ns_pipe( name, fd, rdwr 
char *name;
int fd[2];
char *rdwr;
{
   int omask;
   struct stat statbuff;

   if (s_pipe(fd) < 0)
      return(-1);

   if (*rdwr == 'r')
   {
      if (fstat(fd[0], &statbuff) < 0)
      {
              close(fd[0]);
              close(fd[1]);
              return(-1);
      }
   }

   else if (*rdwr == 'w')
   {
      if (fstat(fd[1], &statbuff) < 0)
      {
              close(fd[0]);
              close(fd[1]);
              return(-1);
      }
   }

   unlink(name);
   omask = umask(0);
   if (mknod(name, S_IFCHR | 0666, statbuff.st_rdev) < 0)
   {
      close(fd[0]);
      close(fd[1]);
      umask(omask);
      return(-1);
   }
   umask(omask);

   return(0);
}

int main( 
{
        int servfd[2];  /*streams pipe to pass passfd on*/
        int passfd;     /*file descriptor to pass over filefd*/
        char buf[2];

        /* set up pass fd server-named streams pipe */
        if (ns_pipe( NSPIPESERV, servfd, "r"  < 0)
        {
                perror("creation of serv pipe failed");
                exit(1);
        }

        /* now wait til a client request comes in */
        if (read( servfd[1], buf, 1) != 1)
        {
                perror("couldn't read request byte from client");
                exit(1);
        }
        if (buf[0] != REQ)
        {
                fprintf(stderr,"request byte read was incorrect: %d\n", buf[0]);
                exit(1);
        }

        /* client should be waiting for the file descriptor, let's */
        /* open the file and pass it over servfd */

        if ((passfd = open(SAMPLEFILE, O_CREAT|O_RDWR)) < 0)
        {
                perror("open of sample text file failed");
                exit(1);
        }

        if ( ioctl( servfd[1], I_SENDFD, passfd  
        {
                fprintf(stderr,"I_SENDFD failed\n");
                exit(1);
        }
        exit(0);
}

 li2002 回复于:2003-11-07 08:06:20
不错,不知道这些资料是那里的,想问一下。

 nuoran 回复于:2003-11-07 11:32:26
不能用send_fd和recv_fd函数么?apue15.3中提到过。

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网