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

📄 xnet.c

📁 This a separate release of the OpenSS7 X/Open XTI/TLI library, TLI modules (timod, tirdwr) and the I
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** @(#) xnet.c,v strxnet-0_9_2-4(0.9.2.3) 2004/06/11 07:37:17 ----------------------------------------------------------------------------- Copyright (c) 2001-2004  OpenSS7 Corporation <http://www.openss7.com> Copyright (c) 1997-2000  Brian F. G. Bidulock <bidulock@openss7.org> All Rights Reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA ----------------------------------------------------------------------------- U.S. GOVERNMENT RESTRICTED RIGHTS.  If you are licensing this Software on behalf of the U.S. Government ("Government"), the following provisions apply to you.  If the Software is supplied by the Department of Defense ("DoD"), it is classified as "Commercial Computer Software" under paragraph 252.227-7014 of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any successor regulations) and the Government is acquiring only the license rights granted herein (the license rights customarily provided to non-Government users).  If the Software is supplied to any unit or agency of the Government other than DoD, it is classified as "Restricted Computer Software" and the Government's rights in the Software are defined in paragraph 52.227-19 of the Federal Acquisition Regulations ("FAR") (or any success regulations) or, in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR (or any successor regulations). ----------------------------------------------------------------------------- Commercial licensing and support of this software is available from OpenSS7 Corporation at a fee.  See http://www.openss7.com/ ----------------------------------------------------------------------------- Last Modified 2004/06/11 07:37:17 by brian *****************************************************************************/#ident "@(#) xnet.c,v strxnet-0_9_2-4(0.9.2.3) 2004/06/11 07:37:17"static char const ident[] = "xnet.c,v strxnet-0_9_2-4(0.9.2.3) 2004/06/11 07:37:17";#define _XOPEN_SOURCE 600#define _REENTRANT#define _THREAD_SAFE#if 0#define __USE_UNIX98#define __USE_XOPEN2K#define __USE_GNU#endif/*   strangely unistd.h defines _SC_T_IOV_MAX as 1  */#if 0#define _SC_T_IOV_MAX		1#endif#define _SC_T_DEFAULT_ADDRLEN	2#define _SC_T_DEFAULT_CONNLEN	3#define _SC_T_DEFAULT_DISCLEN	4#define _SC_T_DEFAULT_OPTLEN	5#define _SC_T_DEFAULT_DATALEN	6#define _T_DEFAULT_ADDRLEN	128#define _T_DEFAULT_CONNLEN	256#define _T_DEFAULT_DISCLEN	256#define _T_DEFAULT_OPTLEN	256#define _T_DEFAULT_DATALEN	1024#define _T_TIMEOUT		-1#define _T_IOV_MAX		16#define NEED_T_USCALAR_T 1#include "gettext.h"#include <sys/types.h>#include <sys/stropts.h>#include <sys/poll.h>#if 0#pragma weak getpmsg#pragma weak putpmsg#pragma weak getmsg#pragma weak putmsg#pragma weak isastream#endif#include <unistd.h>#include <errno.h>#include <stddef.h>#include <stdio.h>#include <stropts.h>#include <pthread.h>#include <linux/limits.h>#include <values.h>#include <xti.h>#include <tihdr.h>#include <timod.h>#undef min#define min(a, b) (a < b ? a : b)/** * @defgroup libxnet OpenSS7 XNS/XTI Library * @brief OpenSS7 XNS/XTI Library Calls * * This manual contains documentation of the OpenSS7 XNS/XTI Library functions * that are generated automatically from the source code with doxygen.  This * documentation is intended to be used for maintainers of the OpenSS7 XNS/XTI * Library and is not intended for users of the OpenSS7 XNS/XTI Library. * Users should consult the documentation found in the user manual pages * beginning with xti(3). * * <h2>Thread Safety</h2> * The OpenSS7 XNS/XTI Library is design to be thread-safe.  This is * accomplished in a number of ways.  Thread-safety depends on the use of * glibc2 and the pthreads library. * * Glibc2 provides lightweight thread-specific data for errno and h_errno. * Because h_errno uses communications function orthoginal to the XTI Library * services, we borrow h_errno and use it for t_errno.  This does not cause a * problem because neither h_errno nor t_errno need to maintain their value * accross any other system call. * * Glibc2 also provides some weak undefined aliases for POSIX thread functions * to peform its own thread-safety.  When the pthread library (libpthread) is * linked with glibc2, these functions call libpthread functions instead * of internal dummy routines.  The same approach is taken for the OpenSS7 * XNS/XTI Library.  The library uses weak defined and undefined aliases that * automatically invoke libpthread functions when libpthread is (dynamically) * linked and uses dummy functions when it is not.  This maintains maximum * efficiency when libpthread is not dynamically linked, but provides full * thread safety when it is. * * Libpthread behaves in some strange ways with regards to thread * cancellation.  Because libpthread uses Linux clone processes for threads, * cancellation of a thread is accomplished by sending a signal to the thread * process.  This does not directly result in cancellation, but will result in * the failure of a system call with the EINTR error code.  It is necessary to * test for cancellation upon error return from system calls to perform the * actual cancellation of the thread. * * The XTI sepcification (OpenGroup XNS 5.2) lists the following functions as * being thread cancellation points: t_close(), t_connect(), t_listen(), * t_rcv(), t_rcvconnect(), t_rcvrel(), t_rcvreldata(), t_rcvudata(), t_rcvv, * t_rcvvudata(), t_snd(), t_sndrel(), t_sndreldata(), t_sndudata(), t_sndv(), * t_sndvudata(). * * The OpenSS7 XNS/XTI Library adds the following functions that operate on * data or expedited data with options that are not present in the XNS 5.2 * specifications, that are also thread cancellation points: t_rcvopt(), * t_rcvvopt(), t_sndopt(), t_sndvopt(). * * Other XTI functions are not permitted by XNS 5.2 to be thread cancellation * points.  Any function that cannot be a thread cancellation point needs to * have its cancellation status deferred if it internally invokes a function * that permits thread cancellation.  Functions that do not permit thread * cancellation are: t_accept(), t_addleaf(), t_alloc(), t_bind(), t_error(), * t_free(), t_getinfo(), t_getprotaddr(), t_getstate(), t_look(), t_open(), * t_optmgmt(), t_rcvdis(), t_rcvleafchange(), t_rcvuderr(), t_removeleaf(), * t_snddis(), t_strerror(), t_sync(), t_sysconf(), t_unbind(). * * Locks and asynchronous thread cancellation present challenges: * * Functions that act as thread cancellation points must push routines onto * the function stack executed at exit of the thread to release the locks held * by the function.  These are performed with weak definitions of POSIX thread * library functions. * * Functions that do not act as thread cancellation points must defer thread * cancellation before taking locks and then release locks before thread * canceallation is restored. * * The above are the techniques used by glibc2 for the same purpose and is the * same technique that is used by the OpenSS7 XNS/XTI library. * * @{ */extern void __pthread_cleanup_push(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg);extern void __pthread_cleanup_pop(struct _pthread_cleanup_buffer *buffer, int execute);extern void __pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg);extern void __pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *buffer, int execute);extern void __pthread_testcancel(void);extern int __pthread_setcanceltype(int type, int *oldtype);extern int __pthread_rwlock_init(pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr);extern int __pthread_rwlock_rdlock(pthread_rwlock_t * rwlock);extern int __pthread_rwlock_wrlock(pthread_rwlock_t * rwlock);extern int __pthread_rwlock_unlock(pthread_rwlock_t * rwlock);extern int __pthread_rwlock_destroy(pthread_rwlock_t * rwlock);#pragma weak __pthread_cleanup_push#pragma weak __pthread_cleanup_pop#pragma weak __pthread_cleanup_push_defer#pragma weak __pthread_cleanup_pop_restore#pragma weak __pthread_testcancel#pragma weak __pthread_setcanceltype#pragma weak __pthread_rwlock_init#pragma weak __pthread_rwlock_rdlock#pragma weak __pthread_rwlock_wrlock#pragma weak __pthread_rwlock_unlock#pragma weak __pthread_rwlock_destroy#pragma weak _pthread_cleanup_push#pragma weak _pthread_cleanup_pop#pragma weak _pthread_cleanup_push_defer#pragma weak _pthread_cleanup_pop_restore#pragma weak pthread_testcancel#pragma weak pthread_setcanceltype#pragma weak pthread_rwlock_init#pragma weak pthread_rwlock_rdlock#pragma weak pthread_rwlock_wrlock#pragma weak pthread_rwlock_unlock#pragma weak pthread_rwlock_destroyvoid_pthread_cleanup_push(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg){	if (__pthread_cleanup_push)		return __pthread_cleanup_push(buffer, routine, arg);	buffer->__routine = routine;	buffer->__arg = arg;	buffer->__canceltype = 0;	buffer->__prev = NULL;}void_pthread_cleanup_pop(struct _pthread_cleanup_buffer *buffer, int execute){	if (__pthread_cleanup_pop)		return __pthread_cleanup_pop(buffer, execute);	if (execute)		(*buffer->__routine) (buffer->__arg);}void_pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg){	if (__pthread_cleanup_push_defer)		return __pthread_cleanup_push_defer(buffer, routine, arg);	buffer->__routine = routine;	buffer->__arg = arg;	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &buffer->__canceltype);	buffer->__prev = NULL;}void_pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *buffer, int execute){	if (__pthread_cleanup_pop_restore)		return __pthread_cleanup_pop_restore(buffer, execute);	if (execute)		(*buffer->__routine) (buffer->__arg);	pthread_setcanceltype(buffer->__canceltype, NULL);}voidpthread_testcancel(void){	if (__pthread_testcancel)		return __pthread_testcancel();	return;}intpthread_setcanceltype(int type, int *oldtype){	if (__pthread_setcanceltype)		return __pthread_setcanceltype(type, oldtype);	if (oldtype)		*oldtype = type;}intpthread_rwlock_init(pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr){	if (__pthread_rwlock_init)		return __pthread_rwlock_init(rwlock, attr);	*(char *) rwlock = 0;	return (0);}intpthread_rwlock_rdlock(pthread_rwlock_t * rwlock){	if (__pthread_rwlock_rdlock)		return __pthread_rwlock_rdlock(rwlock);	*(char *) rwlock = *(char *) rwlock + 1;	return (0);}intpthread_rwlock_wrlock(pthread_rwlock_t * rwlock){	if (__pthread_rwlock_wrlock)		return __pthread_rwlock_wrlock(rwlock);	*(char *) rwlock = *(char *) rwlock - 1;	return (0);}intpthread_rwlock_unlock(pthread_rwlock_t * rwlock){	if (__pthread_rwlock_unlock)		return __pthread_rwlock_unlock(rwlock);	if (*(char *) rwlock > 0)		*(char *) rwlock = *(char *) rwlock - 1;	else		*(char *) rwlock = 0;	return (0);}intpthread_rwlock_destroy(pthread_rwlock_t * rwlock){	if (__pthread_rwlock_destroy)		return __pthread_rwlock_destroy(rwlock);	*(char *) rwlock = 0xff;	return (0);}int t_errno;extern int *__h_errno_location(void);#pragma weak __h_errno_location#pragma weak __t_errno_locationint *__t_errno_location(void){	if (__h_errno_location != 0)		return __h_errno_location();	return &t_errno;}int *_t_errno(void){	return __t_errno_location();}struct _t_user {	pthread_rwlock_t lock;		/* lock for this structure */	int refs;			/* number of references to this structure */	int event;			/* pending t_look() events */	int flags;			/* user flags */	int fflags;			/* file flags */	int gflags;			/* getmsg flags */	int state;			/* XTI state */	int statef;			/* TPI state flag */	int prim;			/* last received TLI primitive */	int qlen;			/* length of the listen queue */	int ocnt;			/* outstanding connection indications */	u_int8_t moredat;		/* more data in T_DATA_IND/T_OPTDATA_IND */	u_int8_t moresdu;		/* more tsdu */	u_int8_t moreexp;		/* more data in T_EXDATA_IND/T_OPTDATA_IND */	u_int8_t moreedu;		/* more etsdu */	u_int8_t moremsg;		/* more data with dis/con/rel message */	int ctlmax;			/* maximum size of ctlbuf */	char *ctlbuf;			/* ctrl part buffer */	int datmax;			/* maximum size of datbuf */	char *datbuf;			/* data part buffer */	uint token;			/* acceptor id */	struct strbuf ctrl;		/* ctrl part of received message */	struct strbuf data;		/* data part of received message */	struct t_info info;		/* information structure */};#define TUF_FLOW_NORM		01	/* was flow controlled for normal messages */#define TUF_FLOW_EXP		02	/* was flow controlled for expedited messages */#define TUF_SYNC_REQUIRED	04	/* t_sync() required */#define TUF_WACK_INFO		010	/* waiting for T_INFO_ACK */#define TUF_WACK_OPTMGMT	020	/* waiting for T_OPTMGMT_ACK */#define TUF_WACK_ADDR		040	/* waiting for T_ADDR_ACK */#define TUF_WACK_CAPABILITY	0100	/* waitinf for T_CAPABILITY_ACK */#define TUF_WACK_GETADDR	0200	/* waiting for T_GETADDR_ACK */#define TUF_WACK_OK		0400	/* waiting for T_OK_ACK */#define TUF_WACK_BIND		01000	/* waiting for T_BIND_ACK */#define TUF_MORE_DATA		02000	/* more data left on receive queue */#ifndef T_ACK#define T_ACK (-2)		/* for now */#endifstatic struct _t_user *_t_fds[OPEN_MAX] = { NULL, };/*   State flags  */#define TSF_UNBND	(1 << TS_UNBND		)#define TSF_WACK_BREQ	(1 << TS_WACK_BREQ	)#define TSF_WACK_UREQ	(1 << TS_WACK_UREQ	)#define TSF_IDLE	(1 << TS_IDLE		)#define TSF_WACK_OPTREQ	(1 << TS_WACK_OPTREQ	)#define TSF_WACK_CREQ	(1 << TS_WACK_CREQ	)#define TSF_WCON_CREQ	(1 << TS_WCON_CREQ	)#define TSF_WRES_CIND	(1 << TS_WRES_CIND	)#define TSF_WACK_CRES	(1 << TS_WACK_CRES	)#define TSF_DATA_XFER	(1 << TS_DATA_XFER	)#define TSF_WIND_ORDREL	(1 << TS_WIND_ORDREL	)#define TSF_WREQ_ORDREL	(1 << TS_WREQ_ORDREL	)#define TSF_WACK_DREQ6	(1 << TS_WACK_DREQ6	)#define TSF_WACK_DREQ7	(1 << TS_WACK_DREQ7	)#define TSF_WACK_DREQ9	(1 << TS_WACK_DREQ9	)#define TSF_WACK_DREQ10	(1 << TS_WACK_DREQ10	)#define TSF_WACK_DREQ11	(1 << TS_WACK_DREQ11	)/** * @internal * @brief set the state of the endpoint to a constant state * @param user a pointer to the _t_user structure for this endpoint. * @param state the constant state value to set. *  * This inline function sets the state of the the transport endpoint in the * user structure to the constate state specified.  This function is an inline * accepting a constant so that the compiler can inline just the appropriate * case value. */static inline void__xnet_u_setstate_const(struct _t_user *user, const 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;

⌨️ 快捷键说明

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