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    [W:0.026 / U:32.816 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site