home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.solaris:504 comp.sys.sun.misc:6574
- Path: sparky!uunet!ukma!bogus.sura.net!howland.reston.ans.net!usc!news.service.uci.edu!ucivax!schmidt
- From: schmidt@liege.ics.uci.edu (Douglas C. Schmidt)
- Subject: Problems peeking at messages using recvmsg
- Nntp-Posting-Host: liege.ics.uci.edu
- Message-ID: <2B68536E.18888@ics.uci.edu>
- Newsgroups: comp.unix.solaris,comp.sys.sun.misc
- Reply-To: schmidt@ics.uci.edu (Douglas C. Schmidt)
- Organization: University of California at Irvine: ICS Dept.
- Lines: 258
- Date: 28 Jan 93 21:43:10 GMT
- Distribution: inet
-
-
- Hi,
-
- The following program illustrates what I believe to
- be a bug with Solaris 2.1. The short client/server example below
- (which runs fine with Sun OS 4.1.x) opens a file in the client and
- then passes the open file descriptor to the server, which performs the
- actual read.
-
- However, for some reason Solaris hangs if the implementation
- of this functionality in the server is written as follows:
-
- ----------------------------------------
- if ((nbytes = recvmsg (n_fd, &msg, MSG_PEEK)) != -1)
- {
- if (nbytes == sizeof a && a[0] == 0xab && a[1] == 0xcd)
- {
- msg.msg_accrights = (char *) &fd;
- msg.msg_accrightslen = sizeof fd;
- if (recvmsg (n_fd, &msg, 0) == -1)
- {
- perror ("recvmsg");
- continue;
- }
- }
- else
- fprintf (stderr, "say what?!\n");
- }
- ----------------------------------------
-
- Note that if I change the code to be
-
- ----------------------------------------
- if ((nbytes = recvmsg (n_fd, &msg, 0)) != -1)
- {
- if (nbytes == sizeof a && a[0] == 0xab && a[1] == 0xcd)
- {
- msg.msg_accrights = (char *) &fd;
- msg.msg_accrightslen = sizeof fd;
- }
- else
- fprintf (stderr, "say what?!\n");
- }
- ----------------------------------------
-
- Then everything works just fine with both Solaris 2.1 and Sun
- OS 4.1.x. However, the functionality is no longer the same.
-
- Therefore, does anyone know why Solaris would hang on the
- MSG_PEEK and whether or not the code really ought to work in the first
- place?!
-
- Thanks,
-
- Doug
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: fd-server.c fd-client.c
- # Wrapped by schmidt@pasteur.ics.uci.edu on Thu Jan 28 13:36:26 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'fd-server.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fd-server.c'\"
- else
- echo shar: Extracting \"'fd-server.c'\" \(2379 characters\)
- sed "s/^X//" >'fd-server.c' <<'END_OF_FILE'
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/un.h>
- X#include <sys/uio.h>
- X#include <fcntl.h>
- X#include <stdio.h>
- X
- X#define RENDEZVOUS "/tmp/foo"
- X
- X/* Server */
- X
- Xint
- Xmain (int argc, char *argv[])
- X{
- X int s_fd;
- X int n;
- X struct sockaddr_un uaddr;
- X char buf[BUFSIZ];
- X char *rendezvous = argc > 1 ? argv[1] : RENDEZVOUS;
- X /* Create a server */
- X unlink (rendezvous);
- X
- X if ((s_fd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
- X perror ("socket"), exit (1);
- X
- X memset (&uaddr, 0, sizeof uaddr);
- X uaddr.sun_family = AF_UNIX;
- X strcpy (uaddr.sun_path, rendezvous);
- X
- X if (bind (s_fd, &uaddr, sizeof uaddr) == -1)
- X perror ("bind"), exit (1);
- X
- X if (listen (s_fd, 5) == -1)
- X perror ("listen"), exit (1);
- X
- X /* Performs the iterative server activities */
- X
- X for (;;)
- X {
- X char buf[BUFSIZ];
- X int n_fd;
- X int fd;
- X unsigned char a[2];
- X struct iovec iov;
- X struct msghdr msg;
- X int nbytes;
- X int n;
- X
- X /* Create a new IPC_SAP_Stream endpoint */
- X if ((n_fd = accept (s_fd, 0, 0)) == -1)
- X perror ("accept");
- X
- X /* Read data from client (correctly handles incomplete reads due to flow control) */
- X
- X iov.iov_base = (char *) a;
- X iov.iov_len = sizeof a;
- X msg.msg_iov = &iov;
- X msg.msg_iovlen = 1;
- X msg.msg_name = (char *) 0;
- X msg.msg_namelen = 0;
- X msg.msg_accrights = (char *) &fd;
- X msg.msg_accrightslen = sizeof fd;
- X
- X if ((nbytes = recvmsg (n_fd, &msg, MSG_PEEK)) != -1)
- X {
- X if (nbytes == sizeof a && a[0] == 0xab && a[1] == 0xcd)
- X {
- X msg.msg_accrights = (char *) &fd;
- X msg.msg_accrightslen = sizeof fd;
- X if (recvmsg (n_fd, &msg, 0) == -1)
- X {
- X perror ("recvmsg");
- X continue;
- X }
- X }
- X else
- X fprintf (stderr, "say what?!\n");
- X }
- X else
- X {
- X perror ("recvmsg PEEK failed");
- X continue;
- X }
- X
- X puts ("----------------------------------------");
- X
- X while (n = read (fd, buf, sizeof buf))
- X write (1, buf, n);
- X
- X puts ("----------------------------------------");
- X
- X if (write (n_fd, "yow", 3) == -1)
- X perror ("write"), exit (1);
- X
- X /* Close new endpoint (listening endpoint stays open) */
- X if (close (n_fd) == -1)
- X perror ("close");
- X }
- X /* NOTREACHED */
- X}
- END_OF_FILE
- if test 2379 -ne `wc -c <'fd-server.c'`; then
- echo shar: \"'fd-server.c'\" unpacked with wrong size!
- fi
- # end of 'fd-server.c'
- fi
- if test -f 'fd-client.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fd-client.c'\"
- else
- echo shar: Extracting \"'fd-client.c'\" \(1890 characters\)
- sed "s/^X//" >'fd-client.c' <<'END_OF_FILE'
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/un.h>
- X#include <sys/uio.h>
- X#include <fcntl.h>
- X#include <stdio.h>
- X
- X#define RENDEZVOUS "/tmp/foo"
- X
- X/* Client */
- X
- Xint
- Xmain (int argc, char *argv[])
- X{
- X char *file_name = argc > 1 ? argv[1] : "./local_data";
- X char *send_str = argc > 2 ? argv[2] : "hello world";
- X char *rendezvous = argc > 3 ? argv[3] : RENDEZVOUS;
- X int fd;
- X int s_fd;
- X int n;
- X struct sockaddr_un uaddr;
- X char buf[BUFSIZ];
- X unsigned char a[2];
- X struct iovec iov;
- X struct msghdr msg;
- X
- X if ((s_fd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
- X perror ("socket"), exit (1);
- X
- X memset (&uaddr, 0, sizeof uaddr);
- X uaddr.sun_family = AF_UNIX;
- X strcpy (uaddr.sun_path, rendezvous);
- X
- X if (connect (s_fd, &uaddr, sizeof uaddr.sun_family + strlen (rendezvous)) == -1)
- X perror ("connect"), exit (1);
- X
- X if ((fd = open (file_name, O_RDONLY)) == -1)
- X perror ("open"), exit (1);
- X
- X a[0] = 0xab;
- X a[1] = 0xcd;
- X iov.iov_base = (char *) a;
- X iov.iov_len = sizeof a;
- X msg.msg_iov = &iov;
- X msg.msg_iovlen = 1;
- X msg.msg_name = (char *) 0;
- X msg.msg_namelen = 0;
- X msg.msg_accrights = (char *) &fd;
- X msg.msg_accrightslen = sizeof fd;
- X
- X if (sendmsg (s_fd, &msg, 0) == -1)
- X perror ("sendmsg"), exit (1);
- X
- X if ((n = read (s_fd, buf, sizeof buf)) == -1)
- X perror ("recv"), exit (1);
- X else
- X write (1, buf, n);
- X
- X /* Explicitly close the connection */
- X if (close (s_fd) == -1)
- X perror ("close"), exit (1);
- X exit (0);
- X}
- END_OF_FILE
- if test 1890 -ne `wc -c <'fd-client.c'`; then
- echo shar: \"'fd-client.c'\" unpacked with wrong size!
- fi
- # end of 'fd-client.c'
- fi
- echo shar: End of shell archive.
- exit 0
- --
- Douglas C. Schmidt
- Department of Information and Computer Science
- University of California, Irvine
- Irvine, CA 92717. (714) 856-4105
-