📄 xtransmnx.c
字号:
return NULL; } if (restart_listen(ciptr_listen) == -1) { priv->listen_list= listen_list; listen_list= ciptr_listen; PRMSG(1, "MnxTcpAccept: unable to restart listen\n", 0, 0, 0); } ciptr->fd= fd; ref.ref_ptr= ciptr; nbio_register(fd); nbio_setcallback(fd, ASIO_WRITE, write_cb, ref); nbio_setcallback(fd, ASIO_READ, read_cb, ref); if (ioctl(ciptr->fd, NWIOGTCPCONF, &tcpconf) == -1) { PRMSG(1, "MnxTcpAccept: NWIOGTCPCONF failed: %s\n", strerror(errno),0, 0); close(fd); free_ConnInfo(ciptr); *status= TRANS_ACCEPT_MISC_ERROR; return NULL; } if ((addr= (struct sockaddr_in *)xalloc(sizeof(struct sockaddr_in))) == NULL) { PRMSG(1, "MnxTcpAccept: malloc failed\n", 0, 0, 0); close(fd); free_ConnInfo(ciptr); *status= TRANS_ACCEPT_BAD_MALLOC; return NULL; } 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); if (*(u8_t *)&tcpconf.nwtc_remaddr == 127) { /* Make ConvertAddress return FamilyLocal */ addr->sin_addr.s_addr= tcpconf.nwtc_remaddr; } if ((addr= (struct sockaddr_in *)xalloc(sizeof(struct sockaddr_in))) == NULL) { PRMSG(1, "MnxTcpConnect: malloc failed\n", 0, 0, 0); close(fd); free_ConnInfo(ciptr); *status= TRANS_ACCEPT_BAD_MALLOC; return NULL; } addr->sin_family= AF_INET; addr->sin_addr.s_addr= tcpconf.nwtc_remaddr; addr->sin_port= tcpconf.nwtc_remport; ciptr->peeraddr= (char *)addr; ciptr->peeraddrlen= sizeof(struct sockaddr_in); *status= 0; return ciptr;}#endif /* TRANS_SERVER */TRANS(MnxTcpConnect) (ciptr, host, port)XtransConnInfo ciptr;char *host;char *port;{ struct hostent *hostp; struct servent *servp; char hostnamebuf[256]; /* tmp space */ tcpport_t num_port; ipaddr_t num_addr; char *check; nwio_tcpconf_t tcpconf; nwio_tcpcl_t tcpcl; struct sockaddr_in *addr; PRMSG(2, "MnxTcpConnect(%d,%s,%s)\n", ciptr->fd, host, port); if (!host) { hostnamebuf[0] = '\0'; (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf); host = hostnamebuf; } 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 num_addr= inet_addr(host); if (num_addr != -1) host= NULL; if (host != NULL) { if ((hostp = gethostbyname(host)) == NULL) { PRMSG(1, "MnxTcpConnect: can't get address for %s\n", host, 0, 0); errno= EINVAL; return TRANS_CONNECT_FAILED; } if (hostp->h_addrtype != AF_INET) /* is IP host? */ { PRMSG(1, "MnxTcpConnect: %s in not an INET host\n", host, 0, 0); errno= EINVAL; return TRANS_CONNECT_FAILED; } num_addr= *(ipaddr_t *)hostp->h_addr; } if (port != NULL) { if ((servp = getservbyname (port, "tcp")) == NULL) { PRMSG(1, "MnxTcpConnect: can't get service for %s\n", port, 0, 0); errno= EINVAL; return TRANS_CONNECT_FAILED; } num_port= servp->s_port; } tcpconf.nwtc_flags= NWTC_EXCL | NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP; tcpconf.nwtc_remaddr= num_addr; tcpconf.nwtc_remport= num_port; if (ioctl(ciptr->fd, NWIOSTCPCONF, &tcpconf) == -1) { PRMSG(1, "MnxTcpConnect: NWIOSTCPCONF failed: %s\n", strerror(errno),0, 0); return TRANS_CONNECT_FAILED; } tcpcl.nwtcl_flags= 0; if (ioctl(ciptr->fd, NWIOTCPCONN, &tcpcl) == -1) { PRMSG(1, "MnxTcpConnect: connect failed: %s\n", strerror(errno),0, 0); if (errno == ECONNREFUSED || errno == EINTR) return TRANS_TRY_CONNECT_AGAIN; else return TRANS_CONNECT_FAILED; } if (ioctl(ciptr->fd, NWIOGTCPCONF, &tcpconf) == -1) { PRMSG(1, "MnxTcpConnect: NWIOGTCPCONF failed: %s\n", strerror(errno),0, 0); return TRANS_CONNECT_FAILED; } if ((addr= (struct sockaddr_in *)xalloc(sizeof(struct sockaddr_in))) == NULL) { PRMSG(1, "MnxTcpConnect: malloc failed\n", 0, 0, 0); return TRANS_CONNECT_FAILED; } addr->sin_family= AF_INET; addr->sin_addr.s_addr= tcpconf.nwtc_locaddr; addr->sin_port= tcpconf.nwtc_locport; ciptr->addr= (char *)addr; ciptr->addrlen= sizeof(struct sockaddr_in); if (*(u8_t *)&tcpconf.nwtc_remaddr == 127) { /* Make ConvertAddress return FamilyLocal */ addr->sin_addr.s_addr= tcpconf.nwtc_remaddr; } if ((addr= (struct sockaddr_in *)xalloc(sizeof(struct sockaddr_in))) == NULL) { PRMSG(1, "MnxTcpConnect: malloc failed\n", 0, 0, 0); return TRANS_CONNECT_FAILED; } addr->sin_family= AF_INET; addr->sin_addr.s_addr= tcpconf.nwtc_remaddr; addr->sin_port= tcpconf.nwtc_remport; ciptr->peeraddr= (char *)addr; ciptr->peeraddrlen= sizeof(struct sockaddr_in); return 0;}static intTRANS(MnxTcpBytesReadable) (ciptr, pend)XtransConnInfo ciptr;BytesReadable_t *pend;{ struct private *priv; int r; PRMSG(2, "MnxTcpBytesReadable(%x,%d,%x)\n", ciptr, ciptr->fd, pend); *pend= 0; priv= (struct private *)ciptr->priv; if (priv->read_inprogress) { PRMSG(5, "MnxTcpBytesReadable: read inprogress, %d\n", *pend, 0, 0); return *pend; } if (priv->read_offset < priv->read_size) { *pend= priv->read_size-priv->read_offset; PRMSG(5, "MnxTcpBytesReadable: %d\n", *pend, 0, 0); return *pend; } priv->read_offset= 0; r= read(ciptr->fd, priv->read_buffer, priv->read_bufsize); if (r >= 0) { if (r == 0) r= 1; /* Signal EOF condition */ priv->read_size= r; PRMSG(5, "MnxTcpBytesReadable: %d\n", *pend, 0, 0); *pend= r; } else if (r == -1 && errno == EINPROGRESS) { priv->read_inprogress= 1; nbio_inprogress(ciptr->fd, ASIO_READ, 1 /* read */, 0 /* write */, 0 /* exception */); } else { PRMSG(1, "MnxTcpBytesReadable: read failed: %s\n", strerror(errno), 0, 0); return -1; } PRMSG(5, "MnxTcpBytesReadable: %d\n", *pend, 0, 0); return *pend;}static intTRANS(MnxTcpRead) (ciptr, buf, size)XtransConnInfo ciptr;char *buf;int size;{ int len, r, ret, s_errno; int offset; struct private *priv; asio_fd_set_t fd_set; fwait_t fw; PRMSG(2, "MnxTcpRead(%d,%x,%d)\n", ciptr->fd, buf, size); priv= (struct private *)ciptr->priv; offset= 0; if (priv->read_inprogress) { PRMSG(5, "MnxTcpRead: EAGAIN\n", 0, 0, 0); errno= EAGAIN; return -1; } /* Copy any data left in the buffer */ if (priv->read_offset < priv->read_size) { len= priv->read_size-priv->read_offset; if (len > size-offset) len= size-offset; PRMSG(5, "MnxTcpRead: copying %d bytes\n", len, 0, 0); memcpy(buf+offset, priv->read_buffer + priv->read_offset, len); offset += len; priv->read_offset += len; if (priv->read_offset < priv->read_size) return offset; } /* Try to read directly into the user's buffer. */ ret= 0; s_errno= 0; while(offset < size) { r= read(ciptr->fd, buf+offset, size-offset); if (r == -1 && errno == EINPROGRESS) { r= fcancel(ciptr->fd, ASIO_READ); if (r == -1) abort(); ASIO_FD_ZERO(&fd_set); ASIO_FD_SET(ciptr->fd, ASIO_READ, &fd_set); fw.fw_flags= FWF_NONBLOCK; fw.fw_bits= fd_set.afds_bits; fw.fw_maxfd= ASIO_FD_SETSIZE; r= fwait(&fw); if (r == -1 || fw.fw_fd != ciptr->fd || fw.fw_operation != ASIO_READ) { abort(); } r= fw.fw_result; errno= fw.fw_errno; } if (r > 0) { PRMSG(5, "MnxTcpRead: read %d bytes\n", r, 0, 0); offset += r; continue; } else if (r == 0) { PRMSG(5, "MnxTcpRead: read EOF\n", 0, 0, 0); break; } else { if (errno == EINTR) { PRMSG(5, "MnxTcpRead: EINTR\n", 0, 0, 0); errno= EAGAIN; } else { PRMSG(1, "MnxTcpRead: read error %s\n", strerror(errno), 0, 0); } s_errno= errno; ret= -1; break; } } if (offset != 0) ret= offset; if (priv->read_offset != priv->read_size) abort(); priv->read_offset= 0; priv->read_size= 0; if (priv->nonblocking) { r= read(ciptr->fd, priv->read_buffer, priv->read_bufsize); if (r >= 0) { PRMSG(5, "MnxTcpRead: buffered %d bytes\n", r, 0, 0); priv->read_size= r; } else if (r == -1 && errno == EINPROGRESS) { priv->read_inprogress= 1; nbio_inprogress(ciptr->fd, ASIO_READ, 1 /* read */, 0 /* write */, 0 /* exception */); } else { PRMSG(1, "MnxTcpRead: read failed: %s\n", strerror(errno), 0, 0); } } errno= s_errno; return ret;}static intTRANS(MnxTcpWrite) (ciptr, buf, size)XtransConnInfo ciptr;char *buf;int size;{ int len, r, ret, s_errno; int offset; struct private *priv; asio_fd_set_t fd_set; fwait_t fw; PRMSG(2, "MnxTcpWrite(%d,%x,%d)\n", ciptr->fd, buf, size); priv= (struct private *)ciptr->priv; offset= 0; if (priv->write_errno) { PRMSG(5, "MnxTcpWrite: write_errno %d\n", priv->write_errno, 0, 0); errno= priv->write_errno; return -1; } if (priv->write_inprogress) { PRMSG(5, "MnxTcpWrite: EAGAIN\n", 0, 0, 0); errno= EAGAIN; return -1; } /* Try to write directly out of the user's buffer. */ ret= 0; s_errno= 0; while(offset < size) { r= write(ciptr->fd, buf+offset, size-offset); if (r == -1 && errno == EINPROGRESS) { r= fcancel(ciptr->fd, ASIO_WRITE); if (r == -1) abort(); ASIO_FD_ZERO(&fd_set); ASIO_FD_SET(ciptr->fd, ASIO_WRITE, &fd_set); fw.fw_flags= FWF_NONBLOCK; fw.fw_bits= fd_set.afds_bits; fw.fw_maxfd= ASIO_FD_SETSIZE; r= fwait(&fw); if (r == -1 || fw.fw_fd != ciptr->fd || fw.fw_operation != ASIO_WRITE) { abort(); } r= fw.fw_result; errno= fw.fw_errno; } if (r > 0) { PRMSG(5, "MnxTcpWrite: wrote %d bytes\n", r, 0, 0); offset += r; continue; } else if (r == 0) abort(); else { if (errno == EINTR) { PRMSG(5, "MnxTcpWrite: EINTR\n", 0, 0, 0); errno= EAGAIN; } else { PRMSG(1, "MnxTcpWrite: write error: %s\n", strerror(errno), 0, 0); } s_errno= errno; ret= -1; break; } } /* Copy any data to the buffer */ if (offset < size) { len= priv->write_bufsize; if (len > size-offset) len= size-offset; PRMSG(5, "MnxTcpWrite: copying %d bytes\n", len, 0, 0); memcpy(priv->write_buffer, buf+offset, len); offset += len; priv->write_offset= 0; priv->write_size= len; } if (offset != 0) ret= offset; while (priv->write_offset < priv->write_size) { r= write(ciptr->fd, priv->write_buffer+priv->write_offset, priv->write_size-priv->write_offset); if (r > 0) { PRMSG(5, "MnxTcpWrite: wrote %d bytes\n", r, 0, 0); priv->write_offset += r; continue; } else if (r == -1 && errno == EINPROGRESS) { priv->write_inprogress= 1; nbio_inprogress(ciptr->fd, ASIO_WRITE, 0 /* read */, 1 /* write */, 0 /* exception */); } else { PRMSG(1, "MnxTcpWrite: write failed: %s\n", strerror(errno), 0, 0); priv->write_errno= errno; } break; } errno= s_errno; return ret;}static intTRANS(MnxTcpReadv) (ciptr, buf, size)XtransConnInfo ciptr;struct iovec *buf;int size;{ int i, offset, total, len, r; PRMSG(2, "MnxTcpReadv(%d,%x,%d)\n", ciptr->fd, buf, size); /* Simply call read a number of times. */ total= 0; offset= 0; i= 0; while(i<size)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -