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

📄 externalconnect.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Bill Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#if defined(LIBC_SCCS) && !defined(lint)static char sccsid[] = "@(#)externalconnect.c	5.2 (Berkeley) 5/29/93";#endif /* LIBC_SCCS and not lint *//* * externalconnect: *	send a message to connection daemon via UNIX domain socket *	containing a resource request and preparation instructions; *	expect a response message containing either the file descriptor *	of the resource and method of preparation, or an connection *	error status explaining why it could not be done. */#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/uio.h>#include <connect.h>static struct fdsocket {	int fd;	int sock;	int state ;}	fdsockets[MAXCONNECTS];static nfds = 0, inprocess = -1 ;externalconnect (cdp, opts, optlen, efd)	struct connectdomain *cdp ;	char *opts ; int optlen ; int efd ;{	int sock, n, i, fd, rv ;	struct sockaddr_un rqsts;	struct iovec iov[4];	struct msghdr msg ;	int constatus, rqstfmt;	sock = socket (AF_UNIX, SOCK_STREAM, 0) ;	if (sock < 0) {		perror("externalconnect: stream socket") ;		exit(1) ;	}	rqsts.sun_family = AF_UNIX ;	strcpy (rqsts.sun_path,"/dev/connect") ;	if (connect (sock, &rqsts, sizeof (rqsts)) < 0) {		perror ("externalconnect: connect /dev/connect") ;		exit (1) ;	}		/* record evidence of communication, so that multiple	   outstandings/aborts are possible */	if (!nfds)		for (i = 0; i < MAXCONNECTS ; i++) {			fdsockets[i].fd = -1;			fdsockets[i].sock = -1;			fdsockets[i].state = -1; } ;	fdsockets[nfds].sock = sock ;	fdsockets[nfds].state = CDNEWREQUEST ;	inprocess = nfds++ ;		/* send connnection request message */	rqstfmt = CDNEWREQUEST;	msg.msg_name = "";	msg.msg_namelen = 0 ;	iov[0].iov_base = (caddr_t) &rqstfmt ;	iov[0].iov_len = sizeof (rqstfmt) ;	iov[1].iov_base = (caddr_t) cdp ;	iov[1].iov_len = CDSIZE(cdp) ;	iov[2].iov_base = (caddr_t) opts;	iov[2].iov_len = optlen ;	msg.msg_iov = iov;	msg.msg_iovlen = 3;	if (efd) {		msg.msg_accrights = (caddr_t) &efd ;		msg.msg_accrightslen = sizeof (efd) ;	} else	msg.msg_accrightslen = 0;	if (sendmsg (sock, &msg, 0) < 0) {		perror("externalconnection: sendmsg") ;		exit(1) ;	}	/* recieve message from connection daemon */	msg.msg_name = "" ;	msg.msg_namelen = 0 ;	iov[0].iov_base = (caddr_t) &rqstfmt ;	iov[0].iov_len = sizeof(rqstfmt) ;	iov[1].iov_base = (caddr_t) &constatus ;	iov[1].iov_len = sizeof(constatus) ;	iov[2].iov_base = (caddr_t) opts;	iov[2].iov_len = optlen ;	msg.msg_iov = iov;	msg.msg_iovlen = 3;	msg.msg_accrights = (caddr_t) &fd ;	msg.msg_accrightslen = sizeof (fd) ;	if (recvmsg (sock, &msg, 0) < 0) {		perror("externalconnection: recvmsg") ;		exit(1) ;	}	/* did we succeed? */	inprocess = -1 ;	if (msg.msg_accrightslen >= sizeof (fd)) {/* XXX needs more work */		fdsockets[nfds-1].fd = fd ;		fdsockets[nfds-1].state = CDNEWRESPONSE ;		return (fd) ;	} else {		nfds--;		close (sock) ;		return (constatus) ;	}}/* * externalfinish: send back file descriptor we got from *	external connect for a well-behaved close. We *	will wait for close just to be able to report *	back any trouble. */externalfinish (fd)	int fd ;{	int sock, n, i, rv ;	struct iovec iov[2];	struct msghdr msg ;	int constatus, rqstfmt;	struct fdsocket *fdp;	fdp = fdsockets ;	/* find socket associated with file descriptor */	for (i = 0; i < nfds ; i++,fdp++)		if (fdp->fd == fd) break;	/* not found at all */	if (i > nfds || !nfds) {		if (inprocess >= 0) externalabort(-1);		return (-1) ;	}	sock = fdp->sock ;	/* never was open */	if (sock < 0) return (-2) ;	/* is there an outstanding request on this guy? */	if (ISCDREQUEST(fdp->state)) externalabort(fdp->fd);		/* mark as closed */	fdp->fd = -1 ;	/* send finish request message */	inprocess = rqstfmt = CDFINISHREQUEST;	msg.msg_name = "";	msg.msg_namelen = 0 ;	iov[0].iov_base = (caddr_t) &rqstfmt ;	iov[0].iov_len = sizeof (rqstfmt) ;	msg.msg_iov = iov;	msg.msg_iovlen = 1;	msg.msg_accrights = (caddr_t) &fd ;	msg.msg_accrightslen = sizeof (fd) ;	if (sendmsg (sock, &msg, 0) < 0) {		perror("externalfinish: sendmsg") ;		return (-3) ;	}	/* recieve message from connection daemon */	msg.msg_name = "" ;	msg.msg_namelen = 0 ;	iov[0].iov_base = (caddr_t) &rqstfmt ;	iov[0].iov_len = sizeof(rqstfmt) ;	iov[1].iov_base = (caddr_t) &constatus ;	iov[1].iov_len = sizeof(constatus) ;	msg.msg_iov = iov;	msg.msg_iovlen = 2;	msg.msg_accrights = 0 ;	msg.msg_accrightslen = 0;	if (recvmsg (sock, &msg, 0) < 0) {		perror("externalfinish: recvmsg") ;		return (-4) ;	}	inprocess = -1 ;	close (fd) ;	close (sock) ;	if (rqstfmt != CDFINISHRESPONSE) return (-5) ;	return (constatus) ;}/* * externalabort: if we have an outstanding request, *	cancel it and return immediately. If the request *	was the initial open, the connection will never *	return a file descriptor, otherwise connection *	status is unaffected. This  routine is mean to be *	called from interrupt routines.  */externalabort (fd)	int fd ;{	int sock, n, i, rv ;	struct iovec iov[2];	struct msghdr msg ;	int constatus, rqstfmt;	struct fdsocket *fdp;	fdp = fdsockets ;	/* if we don't know who we are, abort current connection */	if (fd < 0) {		/* but nothing's going on... */		if (inprocess < 0) return (-1) ;		fdp += inprocess ;	} else	{		/* find socket associated with file descriptor */		for (i = 0; i < nfds ; i++,fdp++)			if (fdp->fd == fd) break;		/* not found at all */		if (i > nfds || !nfds)			return (-1) ;	}	sock = fdp->sock ;	/* never was open */	if (sock < 0) return (-2) ;	/* is there not an outstanding request on this guy? */	if (!ISCDREQUEST(fdp->state)) return (-3) ;		/* send abort request message */	rqstfmt = CDCANCELREQUEST;	msg.msg_name = "";	msg.msg_namelen = 0 ;	iov[0].iov_base = (caddr_t) &rqstfmt ;	iov[0].iov_len = sizeof (rqstfmt) ;	msg.msg_iov = iov;	msg.msg_iovlen = 1;	msg.msg_accrights = (caddr_t) &fd ;	msg.msg_accrightslen = sizeof (fd) ;	if (sendmsg (sock, &msg, MSG_OOB) < 0) {		perror("externalabort: sendmsg") ;		return (-4) ;	}	return (0) ;}/* * externaloption: send a bag of options to be done to the file descriptor *	we got from externalconnect. Options are passed as value-result. */externaloption (fd, opts, optlen)	int fd ;	char *opts ;	int *optlen ;{	int sock, n, i, rv ;	struct iovec iov[3];	struct msghdr msg ;	int constatus, rqstfmt;	struct fdsocket *fdp;	fdp = fdsockets ;	/* find socket associated with file descriptor */	for (i = 0; i < nfds ; i++,fdp++)		if (fdp->fd == fd) break;	/* not found at all */	if (i > nfds || !nfds)		return (-1) ;	sock = fdp->sock ;	/* never was open */	if (sock < 0) return (-2) ;	/* is there an outstanding request on this guy? */	if (ISCDREQUEST(fdp->state)) return (-3) ;		/* mark as closed */	fdp->fd = -1 ;	/* send finish request message */	inprocess = rqstfmt = CDOPTIONREQUEST;	msg.msg_name = "";	msg.msg_namelen = 0 ;	iov[0].iov_base = (caddr_t) &rqstfmt ;	iov[0].iov_len = sizeof (rqstfmt) ;	iov[1].iov_base = (caddr_t) opts ;	iov[1].iov_len = *optlen ;	msg.msg_iov = iov;	msg.msg_iovlen = 2;	msg.msg_accrights = (caddr_t) &fd ;	msg.msg_accrightslen = sizeof (fd) ;	if (sendmsg (sock, &msg, 0) < 0) {		perror("externaloption: sendmsg") ;		return (-3) ;	}	/* recieve message from connection daemon */	msg.msg_name = "" ;	msg.msg_namelen = 0 ;	iov[0].iov_base = (caddr_t) &rqstfmt ;	iov[0].iov_len = sizeof(rqstfmt) ;	iov[1].iov_base = (caddr_t) &constatus ;	iov[1].iov_len = sizeof(constatus) ;	iov[2].iov_base = (caddr_t) opts ;	iov[2].iov_len = *optlen ;	msg.msg_iov = iov;	msg.msg_iovlen = 3;	msg.msg_accrights = 0 ;	msg.msg_accrightslen = 0;	if (recvmsg (sock, &msg, 0) < 0) {		perror("externaloption: recvmsg") ;		return (-4) ;	}	inprocess = -1 ;	if (rqstfmt != CDOPTIONRESPONSE) return (-5) ;	return (constatus) ;}

⌨️ 快捷键说明

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