?? xtransmnx.c
字號(hào):
{ PRMSG(5, "MnxTcpReadv: [%d] size %d-%d\n", i, buf[i].iov_len, offset); if (offset >= buf[i].iov_len) { offset= 0; i++; continue; } len= buf[i].iov_len-offset; r= TRANS(MnxTcpRead)(ciptr, buf[i].iov_base+offset, len); if (r == -1) { if (errno == EAGAIN) { PRMSG(5, "MnxTcpReadv: read returned: %s\n", strerror(errno), 0, 0); } else { PRMSG(1, "MnxTcpReadv: read failed: %s\n", strerror(errno), 0, 0); } if (total != 0) return total; else return -1; } if (r == 0) break; if (r > len) abort(); total += r; offset += r; } return total;}static intTRANS(MnxTcpWritev) (ciptr, buf, size)XtransConnInfo ciptr;struct iovec *buf;int size;{ int i, offset, total, len, r; PRMSG(2, "MnxTcpWritev(%d,%x,%d)\n", ciptr->fd, buf, size); /* Simply call write a number of times. */ total= 0; offset= 0; i= 0; while(i<size) { if (offset >= buf[i].iov_len) { offset= 0; i++; continue; } len= buf[i].iov_len-offset; r= TRANS(MnxTcpWrite)(ciptr, buf[i].iov_base+offset, len); if (r == -1) { if (errno == EAGAIN) { PRMSG(5, "MnxTcpWritev: AGAIN\n", 0, 0, 0); } else { PRMSG(1, "MnxTcpWritev: write failed: %s\n", strerror(errno), 0, 0); } if (total != 0) return total; else return -1; } if (r == 0 || r > len) abort(); total += r; offset += r; } return total;}static intTRANS(MnxTcpDisconnect) (ciptr)XtransConnInfo ciptr;{ PRMSG(2, "MnxTcpDisconnect(%x,%d)\n", ciptr, ciptr->fd, 0); return ioctl(ciptr->fd, NWIOTCPSHUTDOWN, NULL);}static intTRANS(MnxTcpClose) (ciptr)XtransConnInfo ciptr;{ XtransConnInfo list, t_ciptr; struct private *priv; PRMSG(2, "MnxTcpClose(%x,%d)\n", ciptr, ciptr->fd, 0); if (listen_list) { list= listen_list; listen_list= NULL; while(list) { t_ciptr= list; priv= (struct private *)t_ciptr->priv; list= priv->listen_list; if (t_ciptr == ciptr) continue; if (restart_listen(t_ciptr) == -1) { priv->listen_list= listen_list; listen_list= t_ciptr; } } } free_private((struct private *)ciptr->priv); nbio_unregister(ciptr->fd); return close (ciptr->fd);}static XtransConnInfoalloc_ConnInfo(thistrans)Xtransport *thistrans;{ XtransConnInfo ciptr; PRMSG(2, " alloc_ConnInfo(%p)\n", thistrans, 0, 0); if ((ciptr= (XtransConnInfo) xalloc(sizeof(struct _XtransConnInfo))) == NULL) { PRMSG(1, " alloc_ConnInfo: malloc failed\n", 0, 0, 0); return NULL; } ciptr->transptr= thistrans; ciptr->priv= NULL; ciptr->flags= 0; ciptr->fd= -1; ciptr->port= NULL; ciptr->family= AF_INET; ciptr->addr= NULL; ciptr->addrlen= 0; ciptr->peeraddr= NULL; ciptr->peeraddrlen= 0; return ciptr;}static voidfree_ConnInfo(ciptr)XtransConnInfo ciptr;{ if (ciptr == NULL) return; free_private((struct private *)ciptr->priv); xfree(ciptr);}static struct private *alloc_private(rd_size, wr_size)size_t rd_size;size_t wr_size;{ struct private *priv; int s_errno; char *buf; PRMSG(2, ":alloc_private(%d, %d)\n", rd_size, wr_size, 0); if ((priv= (struct private *)xalloc(sizeof(struct private))) == NULL) { PRMSG(1, ":alloc_private: malloc failed\n", 0, 0, 0); return NULL; } priv->nonblocking= 0; priv->read_inprogress= 0; priv->read_buffer= NULL; priv->read_bufsize= rd_size; priv->read_size= 0; priv->read_offset= 0; if (rd_size != 0) { if ((buf= xalloc(rd_size)) == NULL) { PRMSG(1, ":alloc_private: malloc failed\n", 0, 0, 0); s_errno= errno; free_private(priv); errno= s_errno; return NULL; } priv->read_buffer= buf; } priv->write_inprogress= 0; priv->write_buffer= NULL; priv->write_bufsize= rd_size; priv->write_size= 0; priv->write_offset= 0; priv->write_errno= 0; if (wr_size != 0) { if ((buf= xalloc(wr_size)) == NULL) { PRMSG(1, ":alloc_private: malloc failed\n", 0, 0, 0); s_errno= errno; free_private(priv); errno= s_errno; return NULL; } priv->write_buffer= buf; } priv->listen_completed= 0; priv->listen_port= 0; priv->listen_list= NULL; return priv;}static voidfree_private(priv)struct private *priv;{ if (priv == NULL) return; xfree(priv->read_buffer); xfree(priv->write_buffer); xfree(priv);}static voidread_cb(ref, res, err)nbio_ref_t ref;int res;int err;{ XtransConnInfo ciptr; struct private *priv; PRMSG(2, ":read_cb(%x,%d,%d)\n", ref.ref_ptr, res, err); ciptr= ref.ref_ptr; priv= (struct private *)ciptr->priv; if (res > 0) priv->read_size= res; priv->read_inprogress= 0;}static voidwrite_cb(ref, res, err)nbio_ref_t ref;int res;int err;{ XtransConnInfo ciptr; struct private *priv; int r; PRMSG(2, ":write_cb(%x,%d,%d)\n", ref.ref_ptr, res, err); ciptr= ref.ref_ptr; priv= (struct private *)ciptr->priv; if (res > 0) priv->write_offset += res; else if (res == 0) abort(); else { priv->write_errno= err; return; } priv->write_inprogress= 0; 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; }}static voidlisten_cb(ref, res, err)nbio_ref_t ref;int res;int err;{ XtransConnInfo ciptr; struct private *priv; struct sockaddr_in *addr; nwio_tcpconf_t tcpconf; PRMSG(2, ":listen_cb(%x,%d,%d)\n", ref.ref_ptr, res, err); ciptr= ref.ref_ptr; priv= (struct private *)ciptr->priv; if (res == 0) { if (ioctl(ciptr->fd, NWIOGTCPCONF, &tcpconf) == -1) { PRMSG(1, ":listen_cb: NWIOGTCPCONF failed: %s\n", strerror(errno),0, 0); return; } if ((addr= (struct sockaddr_in *)xalloc(sizeof(struct sockaddr_in))) == NULL) { PRMSG(1, ":listen_cb: malloc failed\n", 0, 0, 0); return; } 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); priv->listen_completed= 1; return; } PRMSG(2, ":listen_cb: listen failed: %s\n", strerror(err), 0, 0); if (restart_listen(ciptr) == -1) { priv->listen_list= listen_list; listen_list= ciptr; }}static intrestart_listen(ciptr)XtransConnInfo ciptr;{ char *tcp_device; nwio_tcpconf_t tcpconf; nwio_tcpcl_t tcpcl; int fd, r, s_errno, flags; struct private *priv; nbio_ref_t ref; PRMSG(2, ":restart_listen(%d)\n", ciptr->fd, 0, 0); nbio_unregister(ciptr->fd); if ((tcp_device= getenv("TCP_DEVICE")) == NULL) tcp_device= TCP_DEVICE; if ((fd= open(tcp_device, O_RDWR)) == -1) { PRMSG(1, ":restart_listen: open '%s' failed: %s\n", tcp_device, strerror(errno), 0); return -1; } PRMSG(5, ":restart_listen: fd= '%d'\n", fd, 0, 0); if (fd != ciptr->fd) { if (dup2(fd, ciptr->fd) == -1) abort(); /* no way to recover */ close(fd); } fd= ciptr->fd; ref.ref_ptr= ciptr; nbio_register(fd); nbio_setcallback(fd, ASIO_IOCTL, listen_cb, ref); priv= (struct private *)ciptr->priv; tcpconf.nwtc_flags= NWTC_SHARED | NWTC_UNSET_RA | NWTC_UNSET_RP; tcpconf.nwtc_locport= priv->listen_port; tcpconf.nwtc_flags |= NWTC_LP_SET; if (ioctl(ciptr->fd, NWIOSTCPCONF, &tcpconf) == -1) { PRMSG(1, ":restart_listen: NWIOSTCPCONF failed: %s\n", strerror(errno),0, 0); return -1; } flags= fcntl(ciptr->fd, F_GETFD); if (flags == -1) { PRMSG(1, ":restart_listen: fcntl F_GETFD failed: %s\n", strerror(errno), 0, 0); return -1; } if (fcntl(ciptr->fd, F_SETFD, flags | FD_ASYNCHIO) == -1) { PRMSG(1, ":restart_listen: fcntl F_SETFD failed: %s\n", strerror(errno), 0, 0); return -1; } tcpcl.nwtcl_flags= 0; r= ioctl(ciptr->fd, NWIOTCPLISTEN, &tcpcl); s_errno= errno; if (fcntl(ciptr->fd, F_SETFD, flags) == -1) { PRMSG(1, ":restart_listen: fcntl F_SETFD failed: %s\n", strerror(errno), 0, 0); return -1; } 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, ":restart_listen: NWIOTCPLISTEN failed: %s\n", strerror(errno), 0, 0); return -1;}Xtransport TRANS(MnxINETFuncs) ={ /* Minix TCP Interface */ "inet", 0,#ifdef TRANS_CLIENT TRANS(MnxTcpOpenCOTSClient),#endif /* TRANS_CLIENT */#ifdef TRANS_SERVER TRANS(MnxTcpOpenCOTSServer),#endif /* TRANS_SERVER */#ifdef TRANS_CLIENT TRANS(MnxTcpOpenCLTSClient),#endif /* TRANS_CLIENT */#ifdef TRANS_SERVER TRANS(MnxTcpOpenCLTSServer),#endif /* TRANS_SERVER */#ifdef TRANS_REOPEN TRANS(MnxTcpReopenCOTSServer), TRANS(MnxTcpReopenCLTSServer),#endif TRANS(MnxTcpSetOption),#ifdef TRANS_SERVER TRANS(MnxTcpCreateListener), TRANS(MnxTcpResetListener), TRANS(MnxTcpAccept),#endif /* TRANS_SERVER */#ifdef TRANS_CLIENT TRANS(MnxTcpConnect),#endif /* TRANS_CLIENT */ TRANS(MnxTcpBytesReadable), TRANS(MnxTcpRead), TRANS(MnxTcpWrite), TRANS(MnxTcpReadv), TRANS(MnxTcpWritev), TRANS(MnxTcpDisconnect), TRANS(MnxTcpClose), TRANS(MnxTcpClose),};Xtransport TRANS(MnxTCPFuncs) ={ /* Minix TCP Interface */ "tcp", TRANS_ALIAS,#ifdef TRANS_CLIENT TRANS(MnxTcpOpenCOTSClient),#endif /* TRANS_CLIENT */#ifdef TRANS_SERVER TRANS(MnxTcpOpenCOTSServer),#endif /* TRANS_SERVER */#ifdef TRANS_CLIENT TRANS(MnxTcpOpenCLTSClient),#endif /* TRANS_CLIENT */#ifdef TRANS_SERVER TRANS(MnxTcpOpenCLTSServer),#endif /* TRANS_SERVER */#ifdef TRANS_REOPEN TRANS(MnxTcpReopenCOTSServer), TRANS(MnxTcpReopenCLTSServer),#endif TRANS(MnxTcpSetOption),#ifdef TRANS_SERVER TRANS(MnxTcpCreateListener), TRANS(MnxTcpResetListener), TRANS(MnxTcpAccept),#endif /* TRANS_SERVER */#ifdef TRANS_CLIENT TRANS(MnxTcpConnect),#endif /* TRANS_CLIENT */ TRANS(MnxTcpBytesReadable), TRANS(MnxTcpRead), TRANS(MnxTcpWrite), TRANS(MnxTcpReadv), TRANS(MnxTcpWritev), TRANS(MnxTcpDisconnect), TRANS(MnxTcpClose), TRANS(MnxTcpClose),};
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -