home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / unix / programm / 5315 < prev    next >
Encoding:
Text File  |  1992-11-17  |  3.6 KB  |  123 lines

  1. Path: sparky!uunet!mcsun!sunic!dkuug!diku!thorinn
  2. From: thorinn@diku.dk (Lars Henrik Mathiesen)
  3. Newsgroups: comp.unix.programmer
  4. Subject: Re: Passing file descriptors between processes
  5. Message-ID: <1992Nov17.155819.17834@odin.diku.dk>
  6. Date: 17 Nov 92 15:58:19 GMT
  7. References: <TML.92Nov17125115@tiuhti.tik.vtt.fi>
  8. Sender: thorinn@tyr.diku.dk
  9. Organization: Department of Computer Science, U of Copenhagen
  10. Lines: 111
  11.  
  12. tml@tik.vtt.fi (Tor Lillqvist) writes:
  13. >I vaguely remember that is is possible (at least in pure BSD) to pass
  14. >open file descriptors between processes.  I think UNIX domain sockets
  15. >had something to do with it.
  16.  
  17. Indeed they do, as illustrated by the small example program that I
  18. shall append. (It creates a socketpair, forks, opens a file and reads
  19. the first byte, passes the descriptor to the other process and reads
  20. some more --- with some test output to show that it works as claimed.)
  21.  
  22. >But I can't find anything about it in the HP-UX or SunOS manual
  23. >pages.  Could somebody refresh my memory please?
  24.  
  25. It does work on SunOS 4.1.1 and HP-UX 8.07. On both systems, the
  26. manual section for recvmsg(2) mentions access rights, but does not
  27. explicitly say that these are file descriptors; while the unix(4F/7P)
  28. sections contain references to the Network Programming document/IPC
  29. programmer's manual, I am not sure that those documents are any more
  30. helpful --- the 4.3 IPC Tutorials certainly are not.
  31.  
  32. Lars Mathiesen (U of Copenhagen CS Dep) <thorinn@diku.dk> (Humour NOT marked)
  33.  
  34. -----s-n-i-p-p-e-t-y---s-n-i-p-p-e-t-y---s-n-i-p-p-e-t-y---s-n-i-p-----
  35. #include <sys/file.h>
  36. #include <sys/types.h>
  37. #include <sys/socket.h>
  38. #include <sys/uio.h>
  39. #include <stdio.h>
  40.  
  41. main(argc, argv)
  42.     char **argv;
  43. {
  44.     char buf[BUFSIZ];
  45.     int sv[2], pid, fd = -1, n;
  46.     struct iovec iov;
  47.     struct msghdr mh;
  48.  
  49.     if (argc != 2) {
  50.     fprintf(stderr, "Usage: pass_access file\n");
  51.     exit(2);
  52.     }
  53.     /* Set up a message header:
  54.            No send/receive address
  55.        One buffer in iovec (otherwise recvmsg won't wait for sendmsg)
  56.        A file descriptor area of length one.
  57.      */
  58.     mh.msg_name = 0;
  59.     mh.msg_namelen = 0;
  60.     iov.iov_base = buf;
  61.     iov.iov_len = BUFSIZ;
  62.     mh.msg_iov = &iov;
  63.     mh.msg_iovlen = 1;
  64.     mh.msg_accrights = (caddr_t)&fd;
  65.     mh.msg_accrightslen = sizeof fd;
  66.     
  67.     /* Create a pair of connected sockets */
  68.     if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sv) < 0) {
  69.     perror("socketpair");
  70.     exit(1);
  71.     }
  72.     if ((pid = fork()) < 0) {
  73.     perror("fork");
  74.     exit(1);
  75.     }
  76.     if (pid == 0) {
  77.     /* Child: close a descriptor to illustrate that
  78.        access rights are passed in internal form
  79.      */
  80.     close(sv[0]);
  81.     /* Open a random file */
  82.     if ((fd = open(argv[1], O_RDONLY)) < 0) {
  83.         fputs(argv[1], stderr);
  84.         perror(": open");
  85.         exit(1);
  86.     }
  87.     if ((n = read(fd, buf, 1)) < 0) {
  88.         perror("child read");
  89.         exit(1);
  90.     }
  91.     printf("Child: fd = %d, first char '%c'\n", fd, n ? buf[0] : '?');
  92.     fflush(stdout);
  93.     /* Send a null message with access right tacked on */
  94.     iov.iov_len = 0;
  95.     if ((n = sendmsg(sv[1], &mh, 0)) < 0) {
  96.         perror("sendmsg");
  97.         exit(1);
  98.     }
  99.     printf("Child: sent %d bytes\n", n);
  100.     fflush(stdout);
  101.     exit(0);
  102.     }
  103.     /* Parent: Close send socket to prevent hang if child never sends */
  104.     close(sv[1]);
  105.     /* Get message and access right */
  106.     if ((n = recvmsg(sv[0], &mh, 0)) < 0) {
  107.     perror("recvmsg");
  108.     exit(1);
  109.     }
  110.     printf("Parent: fd = %d, received %d bytes\n", fd, n);
  111.     fflush(stdout);
  112.     /* Copy contents of (small) file */
  113.     if ((n = read(fd, buf, BUFSIZ)) < 0) {
  114.     perror("read");
  115.     exit(1);
  116.     }
  117.     if ((n = write(1, buf, n)) < 0) {
  118.     perror("write");
  119.     exit(1);
  120.     }
  121.     exit(0);
  122. }
  123.