⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fig17.25

📁 unix环境高级编程第二版配套源代码 unix环境高级编程第二版配套源代码
💻 25
字号:
#include "apue.h"#include <sys/socket.h>		/* struct msghdr */#include <sys/un.h>#if defined(SCM_CREDS)			/* BSD interface */#define CREDSTRUCT		cmsgcred#define CR_UID			cmcred_uid#define CREDOPT			LOCAL_PEERCRED#define SCM_CREDTYPE	SCM_CREDS#elif defined(SCM_CREDENTIALS)	/* Linux interface */#define CREDSTRUCT		ucred#define CR_UID			uid#define CREDOPT			SO_PASSCRED#define SCM_CREDTYPE	SCM_CREDENTIALS#else#error passing credentials is unsupported!#endif/* size of control buffer to send/recv one file descriptor */#define RIGHTSLEN	CMSG_LEN(sizeof(int))#define CREDSLEN	CMSG_LEN(sizeof(struct CREDSTRUCT))#define	CONTROLLEN	(RIGHTSLEN + CREDSLEN)static struct cmsghdr	*cmptr = NULL;		/* malloc'ed first time *//* * Receive a file descriptor from a server process.  Also, any data * received is passed to (*userfunc)(STDERR_FILENO, buf, nbytes). * We have a 2-byte protocol for receiving the fd from send_fd(). */intrecv_ufd(int fd, uid_t *uidptr,         ssize_t (*userfunc)(int, const void *, size_t)){	struct cmsghdr		*cmp;	struct CREDSTRUCT	*credp;	int					newfd, nr, status;	char				*ptr;	char				buf[MAXLINE];	struct iovec		iov[1];	struct msghdr		msg;	const int			on = 1;	status = -1;	newfd = -1;	if (setsockopt(fd, SOL_SOCKET, CREDOPT, &on, sizeof(int)) < 0) {		err_ret("setsockopt failed");		return(-1);	}	for ( ; ; ) {		iov[0].iov_base = buf;		iov[0].iov_len  = sizeof(buf);		msg.msg_iov     = iov;		msg.msg_iovlen  = 1;		msg.msg_name    = NULL;		msg.msg_namelen = 0;		if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL)			return(-1);		msg.msg_control    = cmptr;		msg.msg_controllen = CONTROLLEN;		if ((nr = recvmsg(fd, &msg, 0)) < 0) {			err_sys("recvmsg error");		} else if (nr == 0) {			err_ret("connection closed by server");			return(-1);		}		/*		 * See if this is the final data with null & status.  Null		 * is next to last byte of buffer; status byte is last byte.		 * Zero status means there is a file descriptor to receive.		 */		for (ptr = buf; ptr < &buf[nr]; ) {			if (*ptr++ == 0) {				if (ptr != &buf[nr-1])					err_dump("message format error"); 				status = *ptr & 0xFF;	/* prevent sign extension */ 				if (status == 0) {					if (msg.msg_controllen != CONTROLLEN)						err_dump("status = 0 but no fd");					/* process the control data */					for (cmp = CMSG_FIRSTHDR(&msg);					  cmp != NULL; cmp = CMSG_NXTHDR(&msg, cmp)) {						if (cmp->cmsg_level != SOL_SOCKET)							continue;						switch (cmp->cmsg_type) {						case SCM_RIGHTS:							newfd = *(int *)CMSG_DATA(cmp);							break;						case SCM_CREDTYPE:							credp = (struct CREDSTRUCT *)CMSG_DATA(cmp);							*uidptr = credp->CR_UID;						}					}				} else {					newfd = -status;				}				nr -= 2;			}		}		if (nr > 0 && (*userfunc)(STDERR_FILENO, buf, nr) != nr)			return(-1);		if (status >= 0)	/* final data has arrived */			return(newfd);	/* descriptor, or -status */	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -