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

📄 xnet.c

📁 This a separate release of the OpenSS7 X/Open XTI/TLI library, TLI modules (timod, tirdwr) and the I
💻 C
📖 第 1 页 / 共 5 页
字号:
	t_errno = TINDOUT;	goto error;      error:	if (t_errno != TLOOK && (__xnet_t_peek(fd) > 0 || __xnet_t_peek(resfd) > 0))		goto tlook;	return (-1);}int__xnet_t_accept_r(int fd, int resfd, const struct t_call *call){	int ret = -1;	pthread_cleanup_push_defer_np(__xnet_t_putuser, &fd);	if (__xnet_t_getuser(fd)) {		ret = __xnet_t_accept(fd, resfd, call);		__xnet_t_putuser(&fd);	}	pthread_cleanup_pop_restore_np(0);	return (ret);}int t_accept(int fd, int resfd, const struct t_call *call)    __attribute__ ((alias("__xnet_t_accept_r")));/** * @fn int t_addleaf(int fd, int leafid, struct netbuf *addr) * @brief Add a leaf to a point to multipoint connection. * @param fd A file descriptor for the transport user endpoint. * @param leafid The identifier for the leaf. * @param addr A netbuf(3) structure describing the address of the added leaf. * * This function is NOT a thread cancellation point. * * This XTI Liubrary function is only used for ATM.  It is used to add a leaf * to a point to multipoint connection.  This function does not translate to * an TPI message exchange, but invokes a t_optmgmt call on an existing ATM * connection. * * t_addleaf() is NOT a thread cancellation point, but ioctl(2) is; therefore, * we disable cancellation for the duration of the call. */int__xnet_t_addleaf(int fd, int leafid, struct netbuf *addr){#if defined HAVE_XTI_ATM_H	struct _t_user *user;	if (!(user = __xnet_t_tstuser(fd, 0, (1 << T_COTS) | (1 << T_COTS_ORD), TSF_DATA_XFER)))		goto error;#ifdef DEBUG	if (!addr)		goto einval;	if (addr->len < 0 || (addr->len > 0 && !addr->buf))		goto einval;#endif	if (!addr || addr->len < sizeof(struct t_atm_addr))		goto tbadaddr;	{		struct {			struct t_opthdr hdr;			struct t_atm_add_leaf leaf;		} opts;		struct t_optmgmt req, ret;		req.opt.maxlen = 0;		req.opt.len = sizeof(opts);		req.opt.buf = (char *) &opts;		req.flags = T_CURRENT;		ret.opt.maxlen = sizeof(opts);		ret.opt.len = 0;		ret.opt.buf = (char *) &opts;		ret.flags = 0;		opts.hdr.len = sizeof(opts);		opts.hdr.level = T_ATM_SIGNALLING;		opts.hdr.name = T_ATM_ADD_LEAF;		opts.hdr.status = 0;		opts.leaf.leaf_ID = leafid;		memcpy(&opt.leaf.leaf_address, addr->buf, addr->len);		if (__xnet_t_optmgmt(fd, &req, &ret) == -1)			goto error;		if (ret.opt.flags == T_FAILURE)			goto tproto;		if (ret.opt.len < sizeof(opts) || opts.hdr.len < sizeof(opts))			goto tproto;		if (opts.hdr.status != T_SUCCESS)			goto tproto;		if (opts.hdr.level != T_ATM_SIGNALLING || opts.hdr.name != T_ATM_ADD_LEAF)			goto tproto;		/** The t_addleaf function requires an operating-system specific blocking mechanism		   to know when to check for the leaf status indication.  The most obvious approach 		   is to have the ATM transport service provider send a signal to the stream head		   when an indication has arrived.  What signal (SIGPOLL, SIGIO, SIGUSR) is a		   question. Nevertheless, we can check our open flags here and either decide to		   block on a poll or not to check for the indication that the addition was		   successful.  We do not do this yet.  We just always return nodata.  It is the		   caller's responsibility to check with t_rcvleafchange(). 		 */		goto tnodata;	}#ifdef DEBUG      einval:	errno = EINVAL;	goto tsyserr;      tsyserr:	t_errno = TSYSERR;	goto error;#endif      tnodata:	t_errno = TNODATA;	goto error;      tbadaddr:	t_errno = TBADADDR;	goto error;      error:	return (-1);#else				/* defined HAVE_XTI_ATM_H */	t_errno = TNOTSUPPORT;	return (-1);#endif				/* defined HAVE_XTI_ATM_H */}int__xnet_t_addleaf_r(int fd, int leafid, struct netbuf *addr){	int ret = -1;	pthread_cleanup_push_defer_np(__xnet_t_putuser, &fd);	if (__xnet_t_getuser(fd)) {		ret = __xnet_t_addleaf(fd, leafid, addr);		__xnet_t_putuser(&fd);	}	pthread_cleanup_pop_restore_np(0);	return (ret);}int t_addleaf(int fd, int leafid, struct netbuf *addr)    __attribute__ ((weak, alias("__xnet_t_addleaf_r")));/** * @fn char * t_alloc(int fd, int type, int fields) * @brief Allocate an XTI structure and initialize fields. * @param fd A file descriptor for the transport user endpoint. * @param type The type of structure to allocate. * @param fields The fields in the structure to initialize. * * This function is NOT a thread cancellation point. * * Allocate the requested library structure and initialize the requested * fields.  This consists of allocating the structure itself and allocating * buffers for any of the requested fields. * * It would be more efficient if we allocated the structure and the buffers * together in a single allocation.  We would probably get better memory * performance if all of the pieces were kept contiguous.  However, the user * has the possibility of separately freeing the buffers and the t_free() * function does exactly that. *  * t_alloc() is NOT a thread cancellation point; therefore, we defer * cancellation for the duration of the call.  Note that there are no inherent * cancellation points within __xnet_t_alloc(). */char *__xnet_t_alloc(int fd, int type, int fields){	struct _t_user *user;	if (!(user = __xnet_t_tstuser(fd, 0, -1, -1)))		goto error;	switch (type) {	case T_BIND:	{		struct t_bind *bind;		if (!(bind = (struct t_bind *) malloc(sizeof(*bind))))			goto badalloc;		memset(bind, 0, sizeof(*bind));		if (fields & T_ADDR) {			int len;			switch ((len = user->info.addr)) {			case T_INFINITE:				len = _T_DEFAULT_ADDRLEN;			default:				if (!(bind->addr.buf = (char *) malloc(len))) {					free(bind);					goto badalloc;				}				bind->addr.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					free(bind);					goto einval;				}				break;			}		}		return ((char *) bind);	}	case T_OPTMGMT:	{		struct t_optmgmt *opts;		if (!(opts = (struct t_optmgmt *) malloc(sizeof(*opts))))			goto badalloc;		memset(opts, 0, sizeof(*opts));		if (fields & T_OPT) {			int len;			switch ((len = user->info.options)) {			case T_INFINITE:				len = _T_DEFAULT_OPTLEN;			default:				if (!(opts->opt.buf = (char *) malloc(len))) {					free(opts);					goto badalloc;				}				opts->opt.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					free(opts);					goto einval;				}				break;			}		}		return ((char *) opts);	}	case T_CALL:	{		struct t_call *call;		if (user->info.servtype == T_CLTS)			goto tnostructype;		if (!(call = (struct t_call *) malloc(sizeof(*call))))			goto badalloc;		memset(call, 0, sizeof(*call));		if (fields & T_ADDR) {			int len;			switch ((len = user->info.addr)) {			case T_INFINITE:				len = _T_DEFAULT_ADDRLEN;			default:				if (!(call->addr.buf = (char *) malloc(len))) {					free(call);					goto badalloc;				}				call->addr.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					free(call);					goto einval;				}				break;			}		}		if (fields & T_OPT) {			int len;			switch ((len = user->info.options)) {			case T_INFINITE:				len = _T_DEFAULT_OPTLEN;			default:				if (!(call->opt.buf = (char *) malloc(len))) {					if (call->addr.buf)						free(call->addr.buf);					free(call);					goto badalloc;				}				call->opt.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					if (call->addr.buf)						free(call->addr.buf);					free(call);					goto einval;				}				break;			}		}		if (fields & T_UDATA) {			int len;			switch ((len = user->info.connect)) {			case T_INFINITE:				len = _T_DEFAULT_CONNLEN;			default:				if (!(call->udata.buf = (char *) malloc(len))) {					if (call->addr.buf)						free(call->addr.buf);					if (call->opt.buf)						free(call->opt.buf);					free(call);					goto badalloc;				}				call->udata.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					if (call->addr.buf)						free(call->addr.buf);					if (call->opt.buf)						free(call->opt.buf);					free(call);					goto einval;				}				break;			}		}		return ((char *) call);	}	case T_DIS:	{		struct t_discon *discon;		if (user->info.servtype == T_CLTS)			goto tnostructype;		if (!(discon = (struct t_discon *) malloc(sizeof(*discon))))			goto badalloc;		memset(discon, 0, sizeof(*discon));		if (fields & T_UDATA) {			int len;			switch ((len = user->info.discon)) {			case T_INFINITE:				len = _T_DEFAULT_DISCLEN;;			default:				if (!(discon->udata.buf = (char *) malloc(len))) {					free(discon);					goto badalloc;				}				discon->udata.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					free(discon);					goto einval;				}				break;			}		}		return ((char *) discon);	}	case T_UNITDATA:	{		struct t_unitdata *udata;		if (user->info.servtype != T_CLTS)			goto tnostructype;		if (!(udata = (struct t_unitdata *) malloc(sizeof(*udata))))			goto badalloc;		memset(udata, 0, sizeof(*udata));		if (fields & T_ADDR) {			int len;			switch ((len = user->info.addr)) {			case T_INFINITE:				len = _T_DEFAULT_ADDRLEN;			default:				if (!(udata->addr.buf = (char *) malloc(len))) {					free(udata);					goto badalloc;				}				udata->addr.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					free(udata);					goto einval;				}				break;			}		}		if (fields & T_OPT) {			int len;			switch ((len = user->info.options)) {			case T_INFINITE:				len = _T_DEFAULT_OPTLEN;			default:				if (!(udata->opt.buf = (char *) malloc(len))) {					if (udata->addr.buf)						free(udata->addr.buf);					free(udata);					goto badalloc;				}				udata->opt.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					if (udata->addr.buf)						free(udata->addr.buf);					free(udata);					goto einval;				}				break;			}		}		if (fields & T_UDATA) {			int len;			switch ((len = user->info.tsdu)) {			case T_INFINITE:				len = _T_DEFAULT_DATALEN;			default:				if (!(udata->udata.buf = (char *) malloc(len))) {					if (udata->addr.buf)						free(udata->addr.buf);					if (udata->opt.buf)						free(udata->opt.buf);					free(udata);					goto badalloc;				}				udata->udata.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					if (udata->addr.buf)						free(udata->addr.buf);					if (udata->opt.buf)						free(udata->opt.buf);					free(udata);					goto einval;				}				break;			}		}		return ((char *) udata);	}	case T_UDERROR:	{		struct t_uderr *uderr;		if (user->info.servtype != T_CLTS)			goto tnostructype;		if (!(uderr = (struct t_uderr *) malloc(sizeof(*uderr))))			goto badalloc;		memset(uderr, 0, sizeof(*uderr));		if (fields & T_ADDR) {			int len;			switch ((len = user->info.addr)) {			case T_INFINITE:				len = _T_DEFAULT_ADDRLEN;			default:				if (!(uderr->addr.buf = (char *) malloc(len))) {					free(uderr);					goto badalloc;				}				uderr->addr.maxlen = len;			case 0:				break;			case T_INVALID:				if (fields != T_ALL) {					free(uderr);					goto einval;				}				break;			}		}		if (fields & T_OPT) {			int len;			switch ((len = user->info.options)) {			case T_INFINITE:				len = _T_DEFAULT_OPTLEN;			default:				if (!(uderr->opt.buf = (char *) malloc(len))) {					if (uderr->addr.buf)						free(uderr->addr.buf);					free(uderr);

⌨️ 快捷键说明

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