Unix/Linux Go Back    


NetBSD 6.1.5 - man page for cmsg_nxthdr (netbsd section 3)

Linux & Unix Commands - Search Man Pages
Man Page or Keyword Search:   man
Select Man Page Set:       apropos Keyword Search (sections above)


CMSG_DATA(3)			   BSD Library Functions Manual 		     CMSG_DATA(3)

NAME
     CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_NXTHDR, CMSG_SPACE -- socket control message rou-
     tines

SYNOPSIS
     #include <sys/socket.h>

     void *
     CMSG_DATA(struct cmsghdr *);

     struct cmsghdr *
     CMSG_FIRSTHDR(struct msghdr *);

     size_t
     CMSG_LEN(size_t);

     struct cmsghdr *
     CMSG_NXTHDR(struct msghdr *, struct cmsghdr *);

     size_t
     CMSG_SPACE(size_t);

DESCRIPTION
     The control message API is used to construct ancillary data objects for use in control mes-
     sages sent and received across sockets.

     Control messages are passed around by the recvmsg(2) and sendmsg(2) system calls.	The
     cmsghdr structure, described in recvmsg(2), is used to specify a chain of control messages.

     These routines should be used instead of directly accessing the control message header mem-
     bers and data buffers as they ensure that necessary alignment constraints are met.

     The following routines are provided:

     CMSG_DATA(cmsg)
	     This routine accesses the data portion of the control message header cmsg.  It
	     ensures proper alignment constraints on the beginning of ancillary data are met.

     CMSG_FIRSTHDR(mhdr)
	     This routine accesses the first control message attached to the message msg.  If no
	     control messages are attached to the message, this routine returns NULL.

     CMSG_LEN(len)
	     This routine determines the size in bytes of a control message, which includes the
	     control message header.  len specifies the length of the data held by the control
	     message.  This value is what is normally stored in the cmsg_len of each control mes-
	     sage.  This routine accounts for any alignment constraints on the beginning of
	     ancillary data.  This macro might not evaluate to a compile-time constant.

     CMSG_NXTHDR(mhdr, cmsg)
	     This routine returns the location of the control message following cmsg in the mes-
	     sage mhdr.  If cmsg is the last control message in the chain, this routine returns
	     NULL.

     CMSG_SPACE(len)
	     This routine determines the size in bytes needed to hold a control message and its
	     contents of length len, which includes the control message header.  This value is
	     what is normally stored in msg_msgcontrollen.  This routine accounts for any align-
	     ment constraints on the beginning of ancillary data as well as any needed to pad the
	     next control message.  This macro might not evaluate to a compile-time constant.

EXAMPLES
     The following example constructs a control message containing a file descriptor and passes
     it over a socket:

	   struct msghdr    msg;
	   struct cmsghdr  *cmsg;
	   /* We use a union to make sure hdr is aligned */
	   union {
		   struct cmsghdr hdr;
		   unsigned char    buf[CMSG_SPACE(sizeof(int))];
	   } *cmsgbuf;

	   /*
	    * We allocate in the heap instead of the stack to avoid C99
	    * variable stack allocation, which breaks gcc -fstack-protector.
	    */
	   if ((cmsgbuf = malloc(sizeof(*cmsgbuf))) == NULL)
		   err(1, "malloc");
	   (void)memset(&msg, 0, sizeof(msg));
	   msg.msg_control = cmsgbuf->buf;
	   msg.msg_controllen = sizeof(cmsgbuf->buf);

	   cmsg = CMSG_FIRSTHDR(&msg);
	   cmsg->cmsg_len = CMSG_LEN(sizeof(int));
	   cmsg->cmsg_level = SOL_SOCKET;
	   cmsg->cmsg_type = SCM_RIGHTS;
	   *(int *)CMSG_DATA(cmsg) = fd;

	   if (sendmsg(s, &msg, 0) == -1)
		   err(1, "sendmsg");
	   free(cmsgbuf);

     And an example that receives and decomposes the control message:

	   struct msghdr    msg;
	   struct cmsghdr  *cmsg;
	   union {
		   struct cmsghdr hdr;
		   unsigned char    buf[CMSG_SPACE(sizeof(int))];
	   } *cmsgbuf;

	   if ((cmsgbuf = malloc(sizeof(*cmsgbuf))) == NULL)
		   err(1, "malloc");
	   (void)memset(&msg, 0, sizeof(msg));
	   msg.msg_control = cmsgbuf->buf;
	   msg.msg_controllen = sizeof(cmsgbuf->buf);

	   if (recvmsg(s, &msg, 0) == -1)
		   err(1, "recvmsg");
	   if ((msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC))
		   errx(1, "control message truncated");
	   for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
	       cmsg = CMSG_NXTHDR(&msg, cmsg)) {
		   if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
		       cmsg->cmsg_level == SOL_SOCKET &&
		       cmsg->cmsg_type == SCM_RIGHTS) {
			   fd = *(int *)CMSG_DATA(cmsg);
			   /* Do something with the descriptor. */
		   }
	   }
	   free(cmsgbuf);

SEE ALSO
     recvmsg(2), sendmsg(2), socket(2)

HISTORY
     The control message API first appeared in 4.2BSD.

BSD					  June 20, 2008 				      BSD
Unix & Linux Commands & Man Pages : ©2000 - 2018 Unix and Linux Forums


All times are GMT -4. The time now is 09:28 AM.