home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / unix / solaris / 504 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  7.3 KB

  1. Xref: sparky comp.unix.solaris:504 comp.sys.sun.misc:6574
  2. Path: sparky!uunet!ukma!bogus.sura.net!howland.reston.ans.net!usc!news.service.uci.edu!ucivax!schmidt
  3. From: schmidt@liege.ics.uci.edu (Douglas C. Schmidt)
  4. Subject: Problems peeking at messages using recvmsg
  5. Nntp-Posting-Host: liege.ics.uci.edu
  6. Message-ID: <2B68536E.18888@ics.uci.edu>
  7. Newsgroups: comp.unix.solaris,comp.sys.sun.misc
  8. Reply-To: schmidt@ics.uci.edu (Douglas C. Schmidt)
  9. Organization: University of California at Irvine: ICS Dept.
  10. Lines: 258
  11. Date: 28 Jan 93 21:43:10 GMT
  12. Distribution: inet
  13.  
  14.  
  15. Hi,
  16.  
  17.     The following program illustrates what I believe to
  18. be a bug with Solaris 2.1.  The short client/server example below
  19. (which runs fine with Sun OS 4.1.x) opens a file in the client and
  20. then passes the open file descriptor to the server, which performs the
  21. actual read.
  22.  
  23.     However, for some reason Solaris hangs if the implementation
  24. of this functionality in the server is written as follows:
  25.  
  26. ----------------------------------------
  27.       if ((nbytes = recvmsg (n_fd, &msg, MSG_PEEK)) != -1)
  28.     {
  29.       if (nbytes == sizeof a && a[0] == 0xab && a[1] == 0xcd)
  30.         {
  31.           msg.msg_accrights    = (char *) &fd;
  32.           msg.msg_accrightslen = sizeof fd;
  33.           if (recvmsg (n_fd, &msg, 0) == -1)
  34.         {
  35.           perror ("recvmsg");
  36.           continue;
  37.         }
  38.         }
  39.       else
  40.         fprintf (stderr, "say what?!\n");
  41.     }
  42. ----------------------------------------
  43.  
  44.     Note that if I change the code to be
  45.  
  46. ----------------------------------------
  47.       if ((nbytes = recvmsg (n_fd, &msg, 0)) != -1)
  48.     {
  49.       if (nbytes == sizeof a && a[0] == 0xab && a[1] == 0xcd)
  50.         {
  51.           msg.msg_accrights    = (char *) &fd;
  52.           msg.msg_accrightslen = sizeof fd;
  53.         }
  54.       else
  55.         fprintf (stderr, "say what?!\n");
  56.     }
  57. ----------------------------------------
  58.  
  59.     Then everything works just fine with both Solaris 2.1 and Sun
  60. OS 4.1.x.  However, the functionality is no longer the same.
  61.  
  62.     Therefore, does anyone know why Solaris would hang on the
  63. MSG_PEEK and whether or not the code really ought to work in the first
  64. place?!
  65.  
  66.     Thanks,
  67.  
  68.         Doug
  69.  
  70. #! /bin/sh
  71. # This is a shell archive.  Remove anything before this line, then unpack
  72. # it by saving it into a file and typing "sh file".  To overwrite existing
  73. # files, type "sh file -c".  You can also feed this as standard input via
  74. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  75. # will see the following message at the end:
  76. #        "End of shell archive."
  77. # Contents:  fd-server.c fd-client.c
  78. # Wrapped by schmidt@pasteur.ics.uci.edu on Thu Jan 28 13:36:26 1993
  79. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  80. if test -f 'fd-server.c' -a "${1}" != "-c" ; then
  81.   echo shar: Will not clobber existing file \"'fd-server.c'\"
  82. else
  83. echo shar: Extracting \"'fd-server.c'\" \(2379 characters\)
  84. sed "s/^X//" >'fd-server.c' <<'END_OF_FILE'
  85. X#include <sys/types.h>
  86. X#include <sys/socket.h>
  87. X#include <sys/un.h>
  88. X#include <sys/uio.h>
  89. X#include <fcntl.h>
  90. X#include <stdio.h>
  91. X
  92. X#define RENDEZVOUS "/tmp/foo"
  93. X
  94. X/* Server */
  95. X
  96. Xint
  97. Xmain (int argc, char *argv[])
  98. X{
  99. X  int  s_fd;
  100. X  int  n;
  101. X  struct sockaddr_un uaddr;
  102. X  char buf[BUFSIZ];
  103. X  char *rendezvous = argc > 1 ? argv[1] : RENDEZVOUS;
  104. X  /* Create a server */
  105. X  unlink (rendezvous);
  106. X
  107. X  if ((s_fd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
  108. X    perror ("socket"), exit (1);
  109. X
  110. X  memset (&uaddr, 0, sizeof uaddr);
  111. X  uaddr.sun_family = AF_UNIX;
  112. X  strcpy (uaddr.sun_path, rendezvous);
  113. X
  114. X  if (bind (s_fd, &uaddr, sizeof uaddr) == -1)
  115. X    perror ("bind"), exit (1);
  116. X
  117. X  if (listen (s_fd, 5) == -1)
  118. X    perror ("listen"), exit (1);
  119. X
  120. X  /* Performs the iterative server activities */
  121. X
  122. X  for (;;)
  123. X    {
  124. X      char buf[BUFSIZ];
  125. X      int n_fd;
  126. X      int fd;
  127. X      unsigned char a[2];
  128. X      struct iovec  iov;
  129. X      struct msghdr msg;
  130. X      int    nbytes;
  131. X      int    n;
  132. X
  133. X      /* Create a new IPC_SAP_Stream endpoint */
  134. X      if ((n_fd = accept (s_fd, 0, 0)) == -1)
  135. X        perror ("accept");
  136. X
  137. X      /* Read data from client (correctly handles incomplete reads due to flow control) */
  138. X
  139. X      iov.iov_base = (char *) a;
  140. X      iov.iov_len = sizeof a;
  141. X      msg.msg_iov = &iov;
  142. X      msg.msg_iovlen = 1;
  143. X      msg.msg_name = (char *) 0;
  144. X      msg.msg_namelen = 0;
  145. X      msg.msg_accrights    = (char *) &fd;
  146. X      msg.msg_accrightslen = sizeof fd;
  147. X
  148. X      if ((nbytes = recvmsg (n_fd, &msg, MSG_PEEK)) != -1)
  149. X    {
  150. X      if (nbytes == sizeof a && a[0] == 0xab && a[1] == 0xcd)
  151. X        {
  152. X          msg.msg_accrights    = (char *) &fd;
  153. X          msg.msg_accrightslen = sizeof fd;
  154. X          if (recvmsg (n_fd, &msg, 0) == -1)
  155. X        {
  156. X          perror ("recvmsg");
  157. X          continue;
  158. X        }
  159. X        }
  160. X      else
  161. X        fprintf (stderr, "say what?!\n");
  162. X    }
  163. X      else
  164. X    {
  165. X      perror ("recvmsg PEEK failed");
  166. X      continue;
  167. X    }
  168. X
  169. X      puts ("----------------------------------------");
  170. X
  171. X      while (n = read (fd, buf, sizeof buf))
  172. X    write (1, buf, n);
  173. X
  174. X      puts ("----------------------------------------");
  175. X
  176. X      if (write (n_fd, "yow", 3) == -1)
  177. X    perror ("write"), exit (1);
  178. X
  179. X      /* Close new endpoint (listening endpoint stays open) */
  180. X      if (close (n_fd) == -1)
  181. X        perror ("close");
  182. X    }
  183. X  /* NOTREACHED */
  184. X}
  185. END_OF_FILE
  186. if test 2379 -ne `wc -c <'fd-server.c'`; then
  187.     echo shar: \"'fd-server.c'\" unpacked with wrong size!
  188. fi
  189. # end of 'fd-server.c'
  190. fi
  191. if test -f 'fd-client.c' -a "${1}" != "-c" ; then
  192.   echo shar: Will not clobber existing file \"'fd-client.c'\"
  193. else
  194. echo shar: Extracting \"'fd-client.c'\" \(1890 characters\)
  195. sed "s/^X//" >'fd-client.c' <<'END_OF_FILE'
  196. X#include <sys/types.h>
  197. X#include <sys/socket.h>
  198. X#include <sys/un.h>
  199. X#include <sys/uio.h>
  200. X#include <fcntl.h>
  201. X#include <stdio.h>
  202. X
  203. X#define RENDEZVOUS "/tmp/foo"
  204. X
  205. X/* Client */
  206. X
  207. Xint
  208. Xmain (int argc, char *argv[])
  209. X{
  210. X  char *file_name = argc > 1 ? argv[1] : "./local_data";
  211. X  char *send_str = argc > 2 ? argv[2] : "hello world";
  212. X  char *rendezvous = argc > 3 ? argv[3] : RENDEZVOUS;
  213. X  int  fd;
  214. X  int  s_fd;
  215. X  int  n;
  216. X  struct sockaddr_un uaddr;
  217. X  char buf[BUFSIZ];
  218. X  unsigned char a[2];
  219. X  struct iovec iov;
  220. X  struct msghdr    msg;
  221. X
  222. X  if ((s_fd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
  223. X    perror ("socket"), exit (1);
  224. X
  225. X  memset (&uaddr, 0, sizeof uaddr);
  226. X  uaddr.sun_family = AF_UNIX;
  227. X  strcpy (uaddr.sun_path, rendezvous);
  228. X
  229. X  if (connect (s_fd, &uaddr, sizeof uaddr.sun_family + strlen (rendezvous)) == -1)
  230. X    perror ("connect"), exit (1);
  231. X
  232. X  if ((fd = open (file_name, O_RDONLY)) == -1)
  233. X    perror ("open"), exit (1);
  234. X
  235. X  a[0]                   = 0xab;
  236. X  a[1]                   = 0xcd;
  237. X  iov.iov_base             = (char *) a;
  238. X  iov.iov_len         = sizeof a;
  239. X  msg.msg_iov         = &iov;
  240. X  msg.msg_iovlen     = 1;
  241. X  msg.msg_name         = (char *) 0;
  242. X  msg.msg_namelen     = 0;
  243. X  msg.msg_accrights     = (char *) &fd;
  244. X  msg.msg_accrightslen     = sizeof fd;
  245. X
  246. X  if (sendmsg (s_fd, &msg, 0) == -1)
  247. X    perror ("sendmsg"), exit (1);
  248. X
  249. X  if ((n = read (s_fd, buf, sizeof buf)) == -1)
  250. X    perror ("recv"), exit (1);
  251. X  else
  252. X    write (1, buf, n);
  253. X
  254. X  /* Explicitly close the connection */
  255. X  if (close (s_fd) == -1)
  256. X    perror ("close"), exit (1);
  257. X  exit (0);
  258. X}
  259. END_OF_FILE
  260. if test 1890 -ne `wc -c <'fd-client.c'`; then
  261.     echo shar: \"'fd-client.c'\" unpacked with wrong size!
  262. fi
  263. # end of 'fd-client.c'
  264. fi
  265. echo shar: End of shell archive.
  266. exit 0
  267. --
  268. Douglas C. Schmidt
  269. Department of Information and Computer Science
  270. University of California, Irvine
  271. Irvine, CA 92717. (714) 856-4105
  272.