免费注册 查看新帖 |

Chinaunix

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

[SCO UNIX] SCO提供的不相关进程间传递描述符的例子!!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-11-06 23:54 |只看该作者 |倒序浏览
测试一下,没有问题。原来的程序有一点BUG,已经改正。

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 *) &amp; /* 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);
}

论坛徽章:
0
2 [报告]
发表于 2003-11-07 08:06 |只看该作者

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

不错,不知道这些资料是那里的,想问一下。

论坛徽章:
0
3 [报告]
发表于 2003-11-07 11:32 |只看该作者

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

不能用send_fd和recv_fd函数么?apue15.3中提到过。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP