msg.msg_control = (caddr_t) message; msg.msg_controllen = msglen;
msg.msg_control = message; msg.msg_controllen = CMSG_LEN(sizeof(int) * 2);
main(int argc, char *argv[]){	struct msghdr msg;	int listensock, sock, pfd[2], fd, i;	char fname[16], buf[64];	struct cmsghdr *cmp;	int *files = NULL;	struct sockaddr_un sun, csun;	int csunlen;	pid_t pid;	void *message;	int msglen, pflag;	extern char *__progname;	pflag = 0;	while ((i = getopt(argc, argv, "p")) != -1) {		switch (i) {		case 'p':			pflag = 1;			break;		default:			fprintf(stderr, "usage: %s [-p]\n", __progname);			exit(1);		}	}	msglen = CMSG_LEN(sizeof(int) * 2);	if ((message = malloc(msglen)) == NULL)		err(1, "malloc");	/*	 * Create the test files.	 */	for (i = 0; i < 2; i++) {		(void) snprintf(fname, sizeof fname, "file%d", i + 1);		if ((fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)			err(1, "open %s", fname);		(void) snprintf(buf, sizeof buf, "This is file %d.\n", i + 1);		if (write(fd, buf, strlen(buf)) != strlen(buf))			err(1, "write %s", fname);		(void) close(fd);	}	if (pflag) {		/*		 * Create the socketpair		 */		if (socketpair(PF_LOCAL, SOCK_STREAM, 0, pfd) == -1)			err(1, "socketpair");	} else {		/*		 * Create the listen socket.		 */		if ((listensock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1)			err(1, "socket");		(void) unlink(SOCK_NAME);		(void) memset(&sun, 0, sizeof(sun));		sun.sun_family = AF_LOCAL;		(void) strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path);		sun.sun_len = SUN_LEN(&sun);		if (bind(listensock, (struct sockaddr *)&sun, sizeof(sun)) == -1)			err(1, "bind");		if (listen(listensock, 1) == -1)			err(1, "listen");		pfd[0] = pfd[1] = -1;	}	/*	 * Create the sender.	 */	(void) signal(SIGCHLD, catch_sigchld);	pid = fork();	switch (pid) {	case -1:		err(1, "fork");		/* NOTREACHED */	case 0:		if (pfd[0] != -1)			close(pfd[0]);		child(pfd[1]);		/* NOTREACHED */	}	if (pfd[0] != -1) {		close(pfd[1]);		sock = pfd[0];	} else {		/*		 * Wait for the sender to connect.		 */		if ((sock = accept(listensock, (struct sockaddr *)&csun,		    &csunlen)) == -1)		err(1, "accept");	}	/*	 * Give sender a chance to run.  We will get going again	 * once the SIGCHLD arrives.	 */	(void) sleep(10);	/*	 * Grab the descriptors passed to us.	 */	(void) memset(&msg, 0, sizeof(msg));	msg.msg_control = (caddr_t) message;	msg.msg_controllen = msglen;	if (recvmsg(sock, &msg, 0) < 0)		err(1, "recvmsg");	(void) close(sock);	if (msg.msg_controllen == 0)		errx(1, "no control messages received");	if (msg.msg_flags & MSG_CTRUNC)		errx(1, "lost control message data");	for (cmp = CMSG_FIRSTHDR(&msg); cmp != NULL;	    cmp = CMSG_NXTHDR(&msg, cmp)) {		if (cmp->cmsg_level != SOL_SOCKET)			errx(1, "bad control message level %d",			    cmp->cmsg_level);		switch (cmp->cmsg_type) {		case SCM_RIGHTS:			if (cmp->cmsg_len != CMSG_LEN(sizeof(int) * 2))				errx(1, "bad fd control message length %d",				    cmp->cmsg_len);			files = (int *)CMSG_DATA(cmp);			break;		default:			errx(1, "unexpected control message");			/* NOTREACHED */		}	}	/*	 * Read the files and print their contents.	 */	if (files == NULL)		warnx("didn't get fd control message");	else {		for (i = 0; i < 2; i++) {			(void) memset(buf, 0, sizeof(buf));			if (read(files[i], buf, sizeof(buf)) <= 0)				err(1, "read file %d (%d)", i + 1, files[i]);			printf("%s", buf);		}	}	/*	 * All done!	 */	exit(0);}