On Tue, Oct 31, 2006 at 11:01:01PM +0100, [EMAIL PROTECTED] wrote:
> When I use sendmsg to send descriptors from one process to another using
> unix-sockets I need to include at least one byte of normal data for the
> descriptors to be send (using the iovec structure). The same code worked

W. R. Stevens, Unix Network Programming (2nd ed), vol 1, p. 389 recommends
sending at least a byte anyhow, which allows you to detect EOF.

Also see
http://www.cs-ipv6.lancs.ac.uk/ipv6/mail-archive/LinuxNetdev/1998-03/0144.html 
however.

I've attached an example that appears to work.

        Bert

#include <sys/socket.h>
#include <stdio.h>

int sfd(int passfd, int fd, int data)
{
    char cbuf[CMSG_SPACE(sizeof(int))];
    struct msghdr mh = { 0 };
    struct cmsghdr *cm;
    int *dp;
    struct iovec iov;

    if (fd >= 0) {
        mh.msg_control = cbuf;
        mh.msg_controllen = sizeof cbuf;
        cm = CMSG_FIRSTHDR(&mh);
        cm->cmsg_len = CMSG_LEN(sizeof(int));
        cm->cmsg_level = SOL_SOCKET;
        cm->cmsg_type = SCM_RIGHTS;

        dp = CMSG_DATA(cm);
        *dp = fd;
    }
    if (data != 0) {
        iov.iov_base = &data;
        iov.iov_len = sizeof data;
        mh.msg_iov = &iov;
        mh.msg_iovlen = 1;
    }

    return sendmsg(passfd, &mh, 0);
}

/* Only prepared to rcv one fd per message */
int rcvfd(int passfd, int *data, int *datalen)
{
    char cbuf[CMSG_SPACE(sizeof(int))];
    struct msghdr mh = { 0 };
    struct cmsghdr *cm;
    int *dp, ret;
    struct iovec iov;

    if (data) {
        mh.msg_iov = &iov;
        mh.msg_iovlen = 1;
        iov.iov_base = &data;
        iov.iov_len = sizeof(int);
    }

    mh.msg_control = cbuf;
    mh.msg_controllen = sizeof cbuf;
    cm = CMSG_FIRSTHDR(&mh);
    cm->cmsg_len = CMSG_LEN(sizeof(int));
    cm->cmsg_level = SOL_SOCKET;
    cm->cmsg_type = SCM_RIGHTS;

    *datalen = 0;
    ret = recvmsg(passfd, &mh, 0);
    if (ret < 0)
        return ret;
    if (datalen)
        *datalen = ret;

    dp = CMSG_DATA(cm);
    return *dp;
}

int main()
{
  int fd[2];
  int datalen;

  socketpair(AF_UNIX, SOCK_DGRAM, 0, fd);

  printf("Sending returned status: %d\n", sfd(fd[0], 0, 1));
  
  printf("Received fd: %d\n", rcvfd(fd[1], 0, &datalen));
  
}

-- 
http://www.PowerDNS.com      Open source, database driven DNS Software 
http://netherlabs.nl              Open and Closed source services
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to