?? xtransmnx.c
字號:
/* $XFree86: xc/lib/xtrans/Xtransmnx.c,v 3.3 1996/05/10 06:55:50 dawes Exp $ *//*Xtransmnx.cCreated: 11 April 1994 by Philip Homburg <philip@cs.vu.nl>*/#include <stdlib.h>#include <sys/ioctl.h>#include <sys/nbio.h>#include <net/hton.h>#include <net/netlib.h>#include <net/gen/in.h>#include <net/gen/netdb.h>#include <net/gen/tcp.h>#include <net/gen/tcp_io.h>struct private{ int nonblocking; int read_inprogress; char *read_buffer; size_t read_bufsize; size_t read_size; size_t read_offset; int write_inprogress; char *write_buffer; size_t write_bufsize; size_t write_size; size_t write_offset; int write_errno; int listen_completed; u16_t listen_port; XtransConnInfo listen_list;};#define RD_BUFSIZE 1024#define WR_BUFSIZE 1024static XtransConnInfo listen_list= NULL;static XtransConnInfo alloc_ConnInfo(Xtransport *thistrans);static void free_ConnInfo(XtransConnInfo ciptr);static struct private *alloc_private(size_t rd_size, size_t wr_size);static void free_private(struct private *priv);static void read_cb(nbio_ref_t ref, int res, int err);static void write_cb(nbio_ref_t ref, int res, int err);static void listen_cb(nbio_ref_t ref, int res, int err);static int restart_listen(XtransConnInfo ciptr);#ifdef TRANS_CLIENTstatic XtransConnInfoTRANS(MnxTcpOpenCOTSClient) (thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ XtransConnInfo ciptr; char *tcp_device; int s_errno; int fd; nbio_ref_t ref; PRMSG(2, "MnxTcpOpenCOTSClient(%s,%s,%s)\n", protocol, host, port); if ((ciptr= alloc_ConnInfo(thistrans)) == NULL) { PRMSG(1, "MnxTcpOpenCOTSClient: alloc_ConnInfo failed\n", 0, 0, 0); return NULL; } if ((ciptr->priv= (char *)alloc_private(RD_BUFSIZE, WR_BUFSIZE)) == NULL) { PRMSG(1, "MnxTcpOpenCOTSClient: alloc_private() failed\n", 0, 0, 0); s_errno= errno; free_ConnInfo(ciptr); errno= s_errno; return NULL; } if ((tcp_device= getenv("TCP_DEVICE")) == NULL) tcp_device= TCP_DEVICE; PRMSG(4, "MnxTcpOpenCOTSClient: tcp_device= '%s'\n", tcp_device, 0, 0); if ((fd= open(tcp_device, O_RDWR)) == -1) { PRMSG(1, "MnxTcpOpenCOTSClient: open '%s' failed: %s\n", tcp_device, strerror(errno), 0); s_errno= errno; free_ConnInfo(ciptr); errno= s_errno; return NULL; } ciptr->fd= fd; ref.ref_ptr= ciptr; nbio_register(fd); nbio_setcallback(fd, ASIO_READ, read_cb, ref); nbio_setcallback(fd, ASIO_WRITE, write_cb, ref); return ciptr;}#endif /* TRANS_CLIENT */#ifdef TRANS_SERVERstatic XtransConnInfoTRANS(MnxTcpOpenCOTSServer) (thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ XtransConnInfo ciptr; char *tcp_device; int s_errno; int fd; nbio_ref_t ref; PRMSG(2, "MnxTcpOpenCOTSServer(%s,%s,%s)\n", protocol, host, port); if ((ciptr= alloc_ConnInfo(thistrans)) == NULL) { PRMSG(1, "MnxTcpOpenCOTSServer: alloc_ConnInfo failed\n", 0, 0, 0); return NULL; } if ((ciptr->priv= (char *)alloc_private(RD_BUFSIZE, WR_BUFSIZE)) == NULL) { PRMSG(1, "MnxTcpOpenCOTSServer: alloc_private() failed\n", 0, 0, 0); s_errno= errno; free_ConnInfo(ciptr); errno= s_errno; return NULL; } if ((tcp_device= getenv("TCP_DEVICE")) == NULL) tcp_device= TCP_DEVICE; PRMSG(4, "MnxTcpOpenCOTSServer: tcp_device= '%s'\n", tcp_device, 0, 0); if ((fd= open(tcp_device, O_RDWR)) == -1) { PRMSG(1, "MnxTcpOpenCOTSServer: open '%s' failed: %s\n", tcp_device, strerror(errno), 0); s_errno= errno; free_ConnInfo(ciptr); errno= s_errno; return NULL; } PRMSG(5, "MnxTcpOpenCOTSServer: fd= '%d'\n", fd, 0, 0); ciptr->fd= fd; ref.ref_ptr= ciptr; nbio_register(fd); nbio_setcallback(fd, ASIO_IOCTL, listen_cb, ref); return ciptr;}#endif /* TRANS_SERVER */#ifdef TRANS_CLIENTstatic XtransConnInfoTRANS(MnxTcpOpenCLTSClient) (thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ abort();}#endif /* TRANS_CLIENT */#ifdef TRANS_SERVERstatic XtransConnInfoTRANS(MnxTcpOpenCLTSServer) (thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ abort();}#endif /* TRANS_SERVER */#ifdef TRANS_REOPENstatic XtransConnInfoTRANS(MnxTcpReopenCOTSServer) (thistrans, fd, port)Xtransport *thistrans;int fd;char *port;{ XtransConnInfo ciptr; int i; PRMSG (2, "MnxTcpReopenCOTSServer(%d, %s)\n", fd, port, 0); abort();}static XtransConnInfoTRANS(MnxTcpReopenCLTSServer) (thistrans, fd, port)Xtransport *thistrans;int fd;char *port;{ XtransConnInfo ciptr; int i; PRMSG (2, "MnxTcpReopenCLTSServer(%d, %s)\n", fd, port, 0); abort();}#endif /* TRANS_REOPEN */static intTRANS(MnxTcpSetOption) (ciptr, option, arg)XtransConnInfo ciptr;int option;int arg;{ int flags; struct private *priv; PRMSG(2, "MnxTcpSetOption(%d,%d,%d)\n", ciptr->fd, option, arg); priv= (struct private *)ciptr->priv; switch(option) { case TRANS_NONBLOCKING: flags= fcntl(ciptr->fd, F_GETFD); if (flags == -1) { PRMSG(1, "MnxTcpSetOption: fcntl F_GETFD failed: %s\n", strerror(errno), 0, 0); return -1; } if (arg == 0) flags &= ~FD_ASYNCHIO; else if (arg == 1) flags |= FD_ASYNCHIO; else { PRMSG(1, "MnxTcpSetOption: bad arg for TRANS_NONBLOCKING: %d\n", arg, 0, 0); return -1; } if (fcntl(ciptr->fd, F_SETFD, flags) == -1) { PRMSG(1, "MnxTcpSetOption: fcntl F_SETFD failed: %s\n", strerror(errno), 0, 0); return -1; } priv->nonblocking= arg; return 0; case TRANS_CLOSEONEXEC: flags= fcntl(ciptr->fd, F_GETFD); if (flags == -1) { PRMSG(1, "MnxTcpSetOption: fcntl F_GETFD failed: %s\n", strerror(errno), 0, 0); return -1; } if (arg == 0) flags &= ~FD_CLOEXEC; else if (arg == 1) flags |= FD_CLOEXEC; else { PRMSG(1, "MnxTcpSetOption: bad arg for TRANS_CLOSEONEXEC: %d\n", arg, 0, 0); return -1; } if (fcntl(ciptr->fd, F_SETFD, flags) == -1) { PRMSG(1, "MnxTcpSetOption: fcntl F_SETFD failed: %s\n", strerror(errno), 0, 0); return -1; } return 0; default: PRMSG(1, "MnxTcpSetOption: unknown option '%d'\n", option, 0, 0); errno= EINVAL; return -1; }}#ifdef TRANS_SERVERstatic intTRANS(MnxTcpCreateListener) (ciptr, port)XtransConnInfo ciptr;char *port;{ struct servent *servp; tcpport_t num_port; char *check; nwio_tcpconf_t tcpconf; nwio_tcpcl_t tcpcl; int r, s_errno, flags; struct private *priv; struct sockaddr_in *addr; PRMSG(2, "MnxTcpCreateListener(%d,%s)\n", ciptr->fd, port, 0); priv= (struct private *)ciptr->priv; if (port == NULL) num_port= 0; else { num_port= strtol(port, &check, 10); num_port= htons(num_port); if (check[0] == '\0') port= NULL; }#ifdef X11_t /* * X has a well known port, that is transport dependent. It is easier * to handle it here, than try and come up with a transport independent * representation that can be passed in and resolved the usual way. * * The port that is passed here is really a string containing the * idisplay from ConnectDisplay(). */ if (port == NULL) num_port= htons(ntohs(num_port) + X_TCP_PORT);#endif if (port != NULL) { if ((servp = getservbyname (port, "tcp")) == NULL) { PRMSG(1, "MnxTcpCreateListener: can't get service for %s\n", port, 0, 0); errno= EINVAL; return TRANS_CREATE_LISTENER_FAILED; } num_port= servp->s_port; } tcpconf.nwtc_flags= NWTC_SHARED | NWTC_UNSET_RA | NWTC_UNSET_RP; if (num_port != 0) { tcpconf.nwtc_locport= num_port; tcpconf.nwtc_flags |= NWTC_LP_SET; } else tcpconf.nwtc_flags |= NWTC_LP_SEL; if (ioctl(ciptr->fd, NWIOSTCPCONF, &tcpconf) == -1) { PRMSG(1, "MnxTcpCreateListener: NWIOSTCPCONF failed: %s\n", strerror(errno),0, 0); return TRANS_CREATE_LISTENER_FAILED; } if (ioctl(ciptr->fd, NWIOGTCPCONF, &tcpconf) == -1) { PRMSG(1, "MnxTcpListen: NWIOGTCPCONF failed: %s\n", strerror(errno),0, 0); return TRANS_CREATE_LISTENER_FAILED; } priv->listen_port= tcpconf.nwtc_locport; if ((addr= (struct sockaddr_in *)xalloc(sizeof(struct sockaddr_in))) == NULL) { PRMSG(1, "MnxTcpAccept: malloc failed\n", 0, 0, 0); return TRANS_CREATE_LISTENER_FAILED; } addr->sin_family= AF_INET; addr->sin_addr.s_addr= tcpconf.nwtc_locaddr; addr->sin_port= tcpconf.nwtc_locport; if (ciptr->addr) xfree(ciptr->addr); ciptr->addr= (char *)addr; ciptr->addrlen= sizeof(struct sockaddr_in); flags= fcntl(ciptr->fd, F_GETFD); if (flags == -1) { PRMSG(1, "MnxTcpCreateListener: fcntl F_GETFD failed: %s\n", strerror(errno), 0, 0); return TRANS_CREATE_LISTENER_FAILED; } if (fcntl(ciptr->fd, F_SETFD, flags | FD_ASYNCHIO) == -1) { PRMSG(1, "MnxTcpCreateListener: fcntl F_SETFD failed: %s\n", strerror(errno), 0, 0); return TRANS_CREATE_LISTENER_FAILED; } tcpcl.nwtcl_flags= 0; r= ioctl(ciptr->fd, NWIOTCPLISTEN, &tcpcl); s_errno= errno; if (fcntl(ciptr->fd, F_SETFD, flags) == -1) { PRMSG(1, "MnxTcpCreateListener: fcntl F_SETFD failed: %s\n", strerror(errno), 0, 0); return TRANS_CREATE_LISTENER_FAILED; } if (r == -1 && s_errno == EINPROGRESS) { nbio_inprogress(ciptr->fd, ASIO_IOCTL, 1 /* read */, 1 /* write */, 0 /* exception */); return 0; } if (r == 0) { priv->listen_completed= 1; return 0; } errno= s_errno; PRMSG(1, "MnxTcpCreateListener: NWIOTCPLISTEN failed: %s\n", strerror(errno), 0, 0); return TRANS_CREATE_LISTENER_FAILED;}#endif /* TRANS_SERVER */#ifdef TRANS_SERVERstatic intTRANS(MnxTcpResetListener) (ciptr)XtransConnInfo ciptr;{ PRMSG(2, "MnxTcpResetListener(%d)\n", ciptr->fd, 0, 0); return TRANS_RESET_NOOP;}#endif /* TRANS_SERVER */#ifdef TRANS_SERVERstatic XtransConnInfoTRANS(MnxTcpAccept) (ciptr_listen, status)XtransConnInfo ciptr_listen;int *status;{ XtransConnInfo ciptr; int s_errno; int fd; nbio_ref_t ref; struct private *priv; nwio_tcpconf_t tcpconf; struct sockaddr_in *addr; PRMSG(2, "MnxTcpAccept(%d,%p)\n", ciptr_listen->fd, status, 0); priv= (struct private *)ciptr_listen->priv; *status= TRANS_ACCEPT_MISC_ERROR; if (!priv->listen_completed) { PRMSG(1, "MnxTcpAccept: listen is not completed\n", 0, 0, 0); *status= TRANS_ACCEPT_FAILED; return NULL; } priv->listen_completed= 0; if ((ciptr= alloc_ConnInfo(ciptr_listen->transptr)) == NULL) { PRMSG(1, "MnxTcpAccept: alloc_ConnInfo failed\n", 0, 0, 0); *status= TRANS_ACCEPT_BAD_MALLOC; return NULL; } if ((ciptr->priv= (char *)alloc_private(RD_BUFSIZE, WR_BUFSIZE)) == NULL) { PRMSG(1, "MnxTcpAccept: alloc_private() failed\n", 0, 0, 0); s_errno= errno; free_ConnInfo(ciptr); errno= s_errno; *status= TRANS_ACCEPT_BAD_MALLOC; return NULL; } fd= dup(ciptr_listen->fd); if (fd == -1) { s_errno= errno; PRMSG(1, "MnxTcpAccept: dup failed: %s\n", strerror(errno), 0, 0); free_ConnInfo(ciptr); *status= TRANS_ACCEPT_FAILED;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -