📄 xnet.c
字号:
case TS_WIND_ORDREL: case TS_WACK_DREQ10: user->state = T_OUTREL; break; case TS_WREQ_ORDREL: case TS_WACK_DREQ11: user->state = T_INREL; break; default: user->state = T_UNINIT; }}/** * @internal * @brief set the state of the endpoint to a variable state * @param user a pointer to the _t_user structure for this endpoint. * @param state the variable state value to set. * * Sets the state of the transport endpoint in the user structure to the * variable state specified. This is in contrast to the inline version. @see * __xnet_u_setstate_const. */static void__xnet_u_setstate(struct _t_user *user, int state){ user->statef = (1 << state); switch (state) { case TS_UNBND: case TS_WACK_BREQ: user->state = T_UNBND; break; case TS_WACK_UREQ: case TS_IDLE: case TS_WACK_CREQ: user->state = T_IDLE; break; case TS_WCON_CREQ: case TS_WACK_DREQ6: user->state = T_OUTCON; break; case TS_WRES_CIND: case TS_WACK_CRES: case TS_WACK_DREQ7: user->state = T_INCON; break; case TS_DATA_XFER: case TS_WACK_DREQ9: user->state = T_DATAXFER; break; case TS_WIND_ORDREL: case TS_WACK_DREQ10: user->state = T_OUTREL; break; case TS_WREQ_ORDREL: case TS_WACK_DREQ11: user->state = T_INREL; break; default: user->state = T_UNINIT; }}/** * @internal * @brief set the current event. * @param user a pointer to the _t_user structure for this endpoint. * @param prim the TPI primitive associated with the event. * @param flags the flags associated with a @c T_OPTDATA_IND primitive. * * Sets the current event in the transport endpoint user structure according * to the current primitive. */static inline int__xnet_u_setevent(struct _t_user *user, int prim, int flags){ switch ((user->prim = prim)) { case -1: return (user->event = T_DATA); case T_CONN_IND: return (user->event = T_LISTEN); case T_CONN_CON: return (user->event = T_CONNECT); case T_DISCON_IND: return (user->event = T_DISCONNECT); case T_DATA_IND: return (user->event = T_DATA); case T_EXDATA_IND: return (user->event = T_EXDATA); case T_UNITDATA_IND: return (user->event = T_DATA); case T_UDERROR_IND: return (user->event = T_UDERR); case T_ORDREL_IND: return (user->event = T_ORDREL); case T_OPTDATA_IND: return (user->event = (flags & T_ODF_EX) ? T_EXDATA : T_DATA); default: return (user->event = 0); }}/** * @internal * @brief reset (consume) the current event. * @param user a pointer to the _t_user structure for this endpoint. * * Resets (or consumes) the current event. All event information within the * specified user structure is reset. */static void__xnet_u_reset_event(struct _t_user *user){ if (user->event != T_EXDATA || (!user->moresdu && !user->moredat)) { user->prim = 0; user->event = 0; user->ctrl.maxlen = user->ctlmax; user->ctrl.len = 0; user->ctrl.buf = user->ctlbuf; user->data.maxlen = user->datmax; user->data.len = 0; user->data.buf = user->datbuf; user->moredat = 0; user->moresdu = 0; user->moreexp = 0; user->moreedu = 0; user->moremsg = 0; } else { /* When we are clearing an expedited data event, we must revert to an outstanding data event. */ user->prim = 0; user->event = T_DATA; user->ctrl.maxlen = user->ctlmax; user->ctrl.len = 0; user->ctrl.buf = user->ctlbuf; user->data.maxlen = user->datmax; user->data.len = 0; user->data.buf = user->datbuf; user->moreexp = 0; user->moreedu = 0; user->moremsg = 0; }}static int__xnet_u_max_addr(struct _t_user *user){ return (user->info.addr == T_INFINITE ? MAXINT : (user->info.addr >= 0 ? user->info.addr : 0));}static int__xnet_u_max_options(struct _t_user *user){ return (user->info.options == T_INFINITE ? MAXINT : (user->info.options >= 0 ? user->info.options : 0));}static int__xnet_u_max_tsdu(struct _t_user *user){ return ((user->info.tsdu == T_INFINITE || user->info.tsdu == T_INVALID) ? MAXINT : (user->info.tsdu >= 0 ? user->info.tsdu : 0));}static int__xnet_u_max_etsdu(struct _t_user *user){ return (user->info.etsdu == T_INFINITE ? MAXINT : (user->info.etsdu >= 0 ? user->info.etsdu : 0));}static int__xnet_u_max_connect(struct _t_user *user){ return (user->info.connect == T_INFINITE ? MAXINT : (user->info.connect >= 0 ? user->info.connect : 0));}static int__xnet_u_max_discon(struct _t_user *user){ return (user->info.discon == T_INFINITE ? MAXINT : (user->info.discon >= 0 ? user->info.discon : 0));}static int__xnet_u_max_tidu(struct _t_user *user){ return (user->info.tidu == T_INFINITE ? MAXINT : (user->info.tidu >= 0 ? user->info.tidu : 0));}/* Forward declarations */static int __xnet_t_getmsg(int fd, struct strbuf *ctrl, struct strbuf *data, int *flagsp);static int __xnet_t_putmsg(int fd, struct strbuf *ctrl, struct strbuf *data, int flags);static int __xnet_t_putpmsg(int fd, struct strbuf *ctrl, struct strbuf *data, int band, int flags);static int __xnet_t_ioctl(int fd, int cmd, void *arg);static int __xnet_t_strioctl(int fd, int cmd, void *arg, size_t arglen);int __xnet_t_accept(int fd, int resfd, const struct t_call *call);int __xnet_t_addleaf(int fd, int leafid, struct netbuf *addr);char *__xnet_t_alloc(int fd, int type, int fields);int __xnet_t_bind(int fd, const struct t_bind *req, struct t_bind *ret);int __xnet_t_close(int fd);int __xnet_t_connect(int fd, const struct t_call *sndcall, struct t_call *rcvcall);int __xnet_t_free(void *ptr, int type);int __xnet_t_getinfo(int fd, struct t_info *info);int __xnet_t_getstate(int fd);int __xnet_t_listen(int fd, struct t_call *call);int __xnet_t_look(int fd);int __xnet_t_peek(int fd);int __xnet_t_open(const char *path, int oflag, struct t_info *info);int __xnet_t_optmgmt(int fd, const struct t_optmgmt *req, struct t_optmgmt *ret);int __xnet_t_rcv(int fd, char *buf, unsigned int nbytes, int *flags);int __xnet_t_rcvconnect(int fd, struct t_call *call);int __xnet_t_rcvdis(int fd, struct t_discon *discon);int __xnet_t_rcvleafchange(int fd, struct t_leaf_status *change);int __xnet_t_rcvrel(int fd);int __xnet_t_rcvreldata(int fd, struct t_discon *discon);int __xnet_t_rcvopt(int fd, struct t_unitdata *optdata, int *flags);int __xnet_t_rcvudata(int fd, struct t_unitdata *unitdata, int *flags);int __xnet_t_rcvv(int fd, struct t_iovec *iov, unsigned int iovcount, int *flags);int __xnet_t_rcvvudata(int fd, struct t_unitdata *unitdata, struct t_iovec *iov, unsigned int iovcount, int *flags);int __xnet_t_removeleaf(int fd, int leafid, int reason);int __xnet_t_snd(int fd, char *buf, unsigned int nbytes, int flags);int __xnet_t_snddis(int fd, const struct t_call *call);int __xnet_t_sndrel(int fd);int __xnet_t_sndreldata(int fd, struct t_discon *discon);int __xnet_t_sndopt(int fd, const struct t_unitdata *optdata, int flags);int __xnet_t_sndvopt(int fd, const struct t_unitdata *optdata, const struct t_iovec *iov, unsigned int iovcount, int flags);int __xnet_t_sndudata(int fd, const struct t_unitdata *unitdata);int __xnet_t_sndv(int fd, const struct t_iovec *iov, unsigned int iovcount, int flags);#if 0int __xnet_t_sndvopt(int fd, struct t_optmgmt *options, const struct t_iovec *iov, unsigned int iovcount, int flags);#endifint __xnet_t_sndvudata(int fd, struct t_unitdata *unitdata, struct t_iovec *iov, unsigned int iovcount);int __xnet_t_sysconf(int name);int __xnet_t_unbind(int fd);const char *__xnet_t_strerror(int errnum);/** * @internal * @brief a version of getmsg with XTI errors * @param fd a file descriptor representing the transport endpoint. * @param ctrl a pointer to a strbuf structure returning the control part of * the message. * @param data a pointer to a strbuf structure returning the data part of the * message. * @param flagsp a pointer to an integer returning the flags associated with * the retrieved message. * * This is the same as getmsg(2) with the exception that XTI errors are * returned. * * @since Sun Dec 21 19:23:52 MST 2003 * * @return When __xnet_t_getmsg() succeeds, it returns zero (0); when it * fails, it returns -1. * * @par Errors * * __xnet_t_getmsg() can return the following XTI errors: * * <dl> * <dt>TBADF</dt> * <dd>fd is not associated with a file open for reading or is a directory * rather than a file.</dd> * <dt>TNODATA</dt> * <dd>O_NONBLOCK was set on open() or with fcntl() and no data is available * to be read.</dd> * <dt>TSYSERR</dt> * <dd>A Linux system error occured and the error number is in errno.</dd> * </dl> */static int__xnet_t_getmsg(int fd, struct strbuf *ctrl, struct strbuf *data, int *flagsp){ int ret; if ((ret = getmsg(fd, ctrl, data, flagsp)) >= 0) return (ret); t_errno = TSYSERR; switch (errno) { case EISDIR: case EBADF: t_errno = TBADF; break; case EFAULT: case ENODEV: case ENOSTR: case EIO: case EINVAL: break; case EAGAIN: t_errno = TNODATA; return (0); case EINTR: case ENOSR: case EBADMSG: break; } return (-1);}/** * @internal * @brief a version of putmsg with XTI errors * @param fd a file descriptor representing the transport endpoint. * @param ctrl a pointer to a strbuf structure describing the control part of * the message. * @param data a pointer to a strbuf structure describing the data part of the * message. * @param flags a flag integer describing the nature of the message. * * This is the same as putmsg(2) with the exception that XTI errors are * returned. */static int__xnet_t_putmsg(int fd, struct strbuf *ctrl, struct strbuf *data, int flags){ int ret; if ((ret = putmsg(fd, ctrl, data, flags)) >= 0) return (ret); t_errno = TSYSERR; switch (errno) { case EAGAIN: t_errno = TFLOW; break; case EISDIR: case EBADF: t_errno = TBADF; break; case EFAULT: case EINTR: case EINVAL: case EIO: case ENODEV: case ENOSR: case ENOSTR: case ENXIO: case ERANGE: break; } return (-1);}/** * @internal * @brief a version of putpmsg with XTI errors * @param fd a file descriptor representing the transport endpoint. * @param ctrl a pointer to a strbuf structure describing the control part of * the message. * @param data a pointer to a strbuf structure describing the data part of the * message. * @param band a band number describing the band for the message. * @param flags a flag integer describing the nature of the message. * * This is the same as putpmsg(2) with the exception that XTI errors are * returned. */static int__xnet_t_putpmsg(int fd, struct strbuf *ctrl, struct strbuf *data, int band, int flags){ int ret; if ((ret = putpmsg(fd, ctrl, data, band, flags)) != -1) return (ret); t_errno = TSYSERR; switch (errno) { case EAGAIN: t_errno = TFLOW; break; case EISDIR: case EBADF: t_errno = TBADF; break; case EFAULT: case EINTR: case EINVAL: case EIO: case ENODEV: case ENOSR: case ENOSTR: case ENXIO: case ERANGE: break; } return (-1);}static int__xnet_t_getdata(int fd, struct strbuf *udata, int expect){ struct _t_user *user = _t_fds[fd]; int ret, flag = 0; union T_primitives *p = (typeof(p)) user->ctlbuf; switch (user->event) { case T_DATA: case T_EXDATA: if (!(user->event & expect)) break; if (user->data.len < 1) goto getmoredata; udata->len = min(udata->maxlen, user->data.len); memcpy(udata->buf, user->data.buf, udata->len); user->data.buf += udata->len; user->data.len -= udata->len; break; case 0: __xnet_u_reset_event(user); getmoredata: user->data.maxlen = min(udata->maxlen, user->datmax); user->data.len = 0; user->data.buf = udata->buf; if ((ret = __xnet_t_getmsg(fd, &user->ctrl, &user->data, &flag)) < 0) goto error; if (user->ctrl.len < 0) user->ctrl.len = 0; if (user->data.len < 0) user->data.len = 0; udata->len = user->data.len; if (ret & MORECTL) goto cleanup; if (flag != 0 || flag == RS_HIPRI) goto tsync; if (user->ctrl.len || user->data.len) { if (user->event == 0 || user->ctrl.len > 0) __xnet_u_setevent(user, user->ctrl.len ? p->type : -1, 0); /* There is a little extra handling for data indications */ switch (user->prim) { case -1: /* just data */ user->moredat = ((ret & MOREDATA) != 0); break; case T_DATA_IND: user->moresdu = (p->data_ind.MORE_flag != 0); user->moredat = ((ret & MOREDATA) != 0); break; case T_EXDATA_IND: user->moreedu = (p->exdata_ind.MORE_flag != 0); user->moreexp = ((ret & MOREDATA) != 0); break; case T_OPTDATA_IND: if (p->optdata_ind.DATA_flag & T_ODF_EX) { user->moreedu = ((p->optdata_ind.DATA_flag & T_ODF_MORE) != 0); user->moreexp = ((ret & MOREDATA) != 0); } else { user->moresdu = ((p->optdata_ind.DATA_flag & T_ODF_MORE) != 0); user->moredat = ((ret & MOREDATA) != 0); } break; case T_UNITDATA_IND: user->moresdu = 0; user->moredat = ((ret & MOREDATA) != 0); user->moreedu = 0; user->moreexp = 0; break; case T_CONN_IND: case T_CONN_CON: case T_DISCON_IND: case T_ORDREL_IND: case T_UDERROR_IND: user->moremsg = ((ret & MOREDATA) != 0); break; } if ((user->event & expect)) user->data.len = 0; /* consumed */ else { /* didn't get what we were expecting, so we need to move any data from the user buffer back to the look buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -