sendmsg/recvmsg on Linux Alpha 2.2.x

Thorsten Kukuk (kukuk@suse.de)
Thu, 11 Mar 1999 11:56:06 +0100


--OgqxwSJOaUobr8KG
Content-Type: text/plain; charset=us-ascii

Hello,

I have a problem with the sendmsg/recvmsg functions on an Alpha.
I have append 2 programs, reader.c and writer.c. Starting them
on an Intel platform, it works great with glibc 2. On an Alpha
I always get an Invalid argument from sendmsg back.

Any ideas what is different for Alphas ?

Thorsten

-- 
Thorsten Kukuk      http://www.suse.de/~kukuk/        kukuk@suse.de
SuSE GmbH           Schanzaeckerstr. 10             90443 Nuernberg
Linux is like a Vorlon.  It is incredibly powerful, gives terse,
cryptic answers and has a lot of things going on in the background.

--OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="reader.c"

#include <errno.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <rpc/rpc.h> #include <sys/socket.h> #include <sys/uio.h> #include <sys/un.h> #include <errno.h> #include <stdlib.h>

struct cmessage { struct cmsghdr cmsg; struct ucred cmcred; };

static struct cmessage cm;

static int __msgread (int sock, void *buf, size_t cnt) { struct iovec iov[1]; struct msghdr msg;

iov[0].iov_base = buf; iov[0].iov_len = cnt;

msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = (caddr_t) &cm; msg.msg_controllen = sizeof (struct cmessage); msg.msg_flags = 0; { int on = 1; if (setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on))) return -1; }

return recvmsg (sock, &msg, 0); }

int main (void) { struct sockaddr_un addr; socklen_t len = sizeof (struct sockaddr_in); int sock, result; char *path = "/tmp/test_socket"; int cnt = 200; char *buf = calloc (1, cnt);

unlink (path);

if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { perror ("AF_UNIX socket creation problem"); return 1; }

memset (&addr, '\0', sizeof (addr)); addr.sun_family = AF_UNIX; len = strlen (path) + 1; memcpy (addr.sun_path, path, len); len += sizeof (addr.sun_family);

bind (sock, (struct sockaddr *) &addr, len);

if (getsockname (sock, (struct sockaddr *) &addr, &len) != 0 || listen (sock, 2) != 0) { perror ("cannot getsockname or listen"); return 1; }

sock = accept (sock, (struct sockaddr *) &addr, &len); errno = 0; result =__msgread (sock, buf, cnt); perror ("__msgread"); printf ("Received: %s\n", buf); close (sock); unlink (path); return result; }

--OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="writer.c"

#include <stdio.h> #include <unistd.h> #include <string.h> #include <rpc/rpc.h> #include <sys/socket.h> #include <sys/uio.h> #include <sys/un.h> #include <errno.h> #include <stdlib.h>

struct cmessage { struct cmsghdr cmsg; struct ucred cmcred; };

static int __msgwrite (int sock, void *buf, size_t cnt) { struct iovec iov[1]; struct msghdr msg; struct cmessage cm;

iov[0].iov_base = buf; iov[0].iov_len = cnt;

cm.cmsg.cmsg_type = SCM_CREDENTIALS; cm.cmsg.cmsg_level = SOL_SOCKET; cm.cmsg.cmsg_len = sizeof (struct cmessage); /* XXX I'm not sure, if gete?id() is always correct, or if we should use get?id(). But since keyserv needs geteuid(), we have no other chance. It would be much better, if the kernel could pass both to the server. */ cm.cmcred.pid = getpid (); cm.cmcred.uid = geteuid (); cm.cmcred.gid = getegid ();

msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = (caddr_t) &cm; msg.msg_controllen = sizeof (struct cmessage); msg.msg_flags = 0;

return sendmsg (sock, &msg, 0); }

int main (void) { struct sockaddr_un sun; socklen_t len; int sock; char *path = "/tmp/test_socket"; char *buf = "test string 1 alpha"; size_t cnt = strlen (buf) + 1; int result;

bzero ((char *)&sun, sizeof (sun)); sun.sun_family = AF_UNIX; strcpy (sun.sun_path, path); sock = RPC_ANYSOCK;

sock = socket (AF_UNIX, SOCK_STREAM, 0); len = strlen (sun.sun_path) + sizeof (sun.sun_family) + 1; if (sock < 0 || connect (sock, (struct sockaddr *) &sun, len) < 0) { if (sock != -1) close (sock); perror ("socket"); return -2; }

result = __msgwrite (sock, buf, cnt); perror ("__msgwrite"); return result; }

--OgqxwSJOaUobr8KG--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/