netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* sendmsg, descriptors and no content
@ 2006-10-31 22:01 netdev
  2006-10-31 22:43 ` bert hubert
  0 siblings, 1 reply; 2+ messages in thread
From: netdev @ 2006-10-31 22:01 UTC (permalink / raw)
  To: netdev

Hi,


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
fine on openbsd (ie. filedescriptors could be send without normal data).
If no normal data is included sendmsg will return 0, as if all data is
send correctly.


Is this difference on purpose? If so, why?


Regards,
Hylke


ps.
The current behaviour is because unix_stream_sendmsg in af_unix.c will
not do anything if len=0.


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: sendmsg, descriptors and no content
  2006-10-31 22:01 sendmsg, descriptors and no content netdev
@ 2006-10-31 22:43 ` bert hubert
  0 siblings, 0 replies; 2+ messages in thread
From: bert hubert @ 2006-10-31 22:43 UTC (permalink / raw)
  To: netdev; +Cc: netdev

On Tue, Oct 31, 2006 at 11:01:01PM +0100, netdev@weary.nl 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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-10-31 22:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-31 22:01 sendmsg, descriptors and no content netdev
2006-10-31 22:43 ` bert hubert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).