lkml.org 
[lkml]   [1999]   [Mar]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectsendmsg/recvmsg on Linux Alpha 2.2.x

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.
#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;
}#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;
}
\
 
 \ /
  Last update: 2005-03-22 13:50    [from the cache]
©2003-2011 Jasper Spaans