From 8678660b82022f0d64876f3d2b1e3ed233ce336b Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 20 Nov 2014 15:12:28 +0000 Subject: [PATCH] added some experimental and unfinished code using tli --- qse/Makefile.in | 2 +- qse/configure | 87 +++++++++- qse/configure.ac | 27 ++- qse/include/qse/config.h.in | 6 + qse/lib/cmn/nwio.c | 329 +++++++++++++++++++++++++++++++++--- qse/lib/cmn/sck.c | 34 ++++ 6 files changed, 444 insertions(+), 41 deletions(-) diff --git a/qse/Makefile.in b/qse/Makefile.in index 9b9cdaa2..69dd0bff 100644 --- a/qse/Makefile.in +++ b/qse/Makefile.in @@ -51,7 +51,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . -DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/README.in \ $(top_srcdir)/configure ac/config.guess ac/config.sub \ ac/depcomp ac/install-sh ac/ltmain.sh ac/missing diff --git a/qse/configure b/qse/configure index 1ca0690c..b926dfa8 100755 --- a/qse/configure +++ b/qse/configure @@ -17143,7 +17143,7 @@ case "$host" in platform_win32=no ;; esac - if test "${platform_win32}" = "yes" ; then + if test "x${platform_win32}" = "xyes" ; then WIN32_TRUE= WIN32_FALSE='#' else @@ -17451,7 +17451,20 @@ fi done -for ac_header in sys/sysctl.h sys/socket.h sys/sockio.h sys/un.h ifaddrs.h linux/netfilter_ipv4.h netinet/sctp.h +for ac_header in sys/sysctl.h sys/socket.h sys/sockio.h sys/un.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in ifaddrs.h tiuser.h linux/netfilter_ipv4.h netinet/sctp.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -17728,7 +17741,7 @@ _ACEOF fi done -if test "$ac_cv_func_gethostbyname" = "no" +if test "x$ac_cv_func_gethostbyname" = "xno" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } @@ -17775,7 +17788,7 @@ if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : fi fi -if test "$ac_cv_func_connect" = "no" +if test "x$ac_cv_func_connect" = "xno" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } @@ -17821,8 +17834,70 @@ if test "x$ac_cv_lib_socket_connect" = xyes; then : fi + + if test "x$ac_cv_lib_socket_connect" = xno + then + for ac_func in t_connect +do : + ac_fn_c_check_func "$LINENO" "t_connect" "ac_cv_func_t_connect" +if test "x$ac_cv_func_t_connect" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_T_CONNECT 1 +_ACEOF + fi -if test "${platform_win32}" = "yes" +done + + if test "x$ac_cv_func_t_connect" = "xno" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_connect in -lnsl_s" >&5 +$as_echo_n "checking for t_connect in -lnsl_s... " >&6; } +if ${ac_cv_lib_nsl_s_t_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl_s $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char t_connect (); +int +main () +{ +return t_connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_s_t_connect=yes +else + ac_cv_lib_nsl_s_t_connect=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_s_t_connect" >&5 +$as_echo "$ac_cv_lib_nsl_s_t_connect" >&6; } +if test "x$ac_cv_lib_nsl_s_t_connect" = xyes; then : + + SOCKET_LIBS="$SOCKET_LIBS -lnsl_s" + $as_echo "#define HAVE_T_CONNECT 1" >>confdefs.h + + +fi + + fi + fi +fi +if test "x${platform_win32}" = "xyes" then SOCKET_LIBS="$SOCKET_LIBS -lws2_32" fi @@ -19883,7 +19958,7 @@ _ACEOF -if test "${platform_win32}" = "yes" +if test "x${platform_win32}" = "xyes" then # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects diff --git a/qse/configure.ac b/qse/configure.ac index 14a03758..797fa5a0 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -111,7 +111,7 @@ case "$host" in platform_win32=no ;; esac -AM_CONDITIONAL(WIN32, test "${platform_win32}" = "yes" ) +AM_CONDITIONAL(WIN32, test "x${platform_win32}" = "xyes" ) dnl check the math library (check if -lm is needed) LT_LIB_M @@ -123,7 +123,8 @@ AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h dirent.h]) AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h ucontext.h]) AC_CHECK_HEADERS([sys/resource.h sys/wait.h sys/syscall.h sys/ioctl.h]) AC_CHECK_HEADERS([sys/sendfile.h sys/epoll.h sys/event.h]) -AC_CHECK_HEADERS([sys/sysctl.h sys/socket.h sys/sockio.h sys/un.h ifaddrs.h linux/netfilter_ipv4.h netinet/sctp.h]) +AC_CHECK_HEADERS([sys/sysctl.h sys/socket.h sys/sockio.h sys/un.h]) +AC_CHECK_HEADERS([ifaddrs.h tiuser.h linux/netfilter_ipv4.h netinet/sctp.h]) AC_CHECK_HEADERS([net/if.h net/if_dl.h], [], [], [ #include #include ]) @@ -169,21 +170,33 @@ dnl SOCKET_LIBS="$SOCKET_LIBS -lsocket" dnl fi dnl AC_SUBST(SOCKET_LIBS) AC_CHECK_FUNCS([connect gethostbyname]) -if test "$ac_cv_func_gethostbyname" = "no" +if test "x$ac_cv_func_gethostbyname" = "xno" then AC_CHECK_LIB([nsl], [gethostbyname], [ SOCKET_LIBS="$SOCKET_LIBS -lnsl" AC_DEFINE(HAVE_GETHOSTBYNAME, 1) ]) fi -if test "$ac_cv_func_connect" = "no" +if test "x$ac_cv_func_connect" = "xno" then AC_CHECK_LIB([socket], [connect], [ SOCKET_LIBS="$SOCKET_LIBS -lsocket" AC_DEFINE(HAVE_CONNECT, 1) - ]) + ]) + + if test "x$ac_cv_lib_socket_connect" = xno + then + AC_CHECK_FUNCS([t_connect]) + if test "x$ac_cv_func_t_connect" = "xno" + then + AC_CHECK_LIB([nsl_s], [t_connect], [ + SOCKET_LIBS="$SOCKET_LIBS -lnsl_s" + AC_DEFINE(HAVE_T_CONNECT, 1) + ]) + fi + fi fi -if test "${platform_win32}" = "yes" +if test "x${platform_win32}" = "xyes" then SOCKET_LIBS="$SOCKET_LIBS -lws2_32" fi @@ -376,7 +389,7 @@ AC_CHECK_SIZEOF(off64_t) AC_CHECK_SIZEOF(mbstate_t,,[#include ]) AX_CHECK_NUMVALOF(MB_LEN_MAX,[32],[#include ]) -if test "${platform_win32}" = "yes" +if test "x${platform_win32}" = "xyes" then AC_CHECK_SIZEOF(struct sockaddr_in,,[ #include diff --git a/qse/include/qse/config.h.in b/qse/include/qse/config.h.in index ed1c846f..14ca8954 100644 --- a/qse/include/qse/config.h.in +++ b/qse/include/qse/config.h.in @@ -694,9 +694,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H +/* Define to 1 if you have the header file. */ +#undef HAVE_TIUSER_H + /* Define to 1 if you have the `towctrans' function. */ #undef HAVE_TOWCTRANS +/* Define to 1 if you have the `t_connect' function. */ +#undef HAVE_T_CONNECT + /* Define to 1 if you have the header file. */ #undef HAVE_UCI_H diff --git a/qse/lib/cmn/nwio.c b/qse/lib/cmn/nwio.c index 4f3f2a36..94650297 100644 --- a/qse/lib/cmn/nwio.c +++ b/qse/lib/cmn/nwio.c @@ -57,11 +57,30 @@ /* SO_RCVTIMEO doesn't work or i don't know how to get it to work. */ # undef SO_RCVTIMEO # undef SO_SNDTIMEO +#elif defined(HAVE_T_CONNECT) && !defined(HAVE_CONNECT) && defined(HAVE_TIUSER_H) +# include "syscall.h" +# include +# include +# include +# define USE_TLI +# define USE_SELECT + + + extern int t_accept(int, int, struct t_call *); + extern void *t_alloc(int, int, int); + extern int t_bind(int, struct t_bind *, struct t_bind *); + extern int t_close(int); + extern int t_connect(int, struct t_call *, struct t_call *); + extern int t_listen(int, struct t_call *); + extern int t_open(const char *, int, struct t_info *); + extern int t_errno; + extern int t_snd(int fd, char* buf, unsigned int nbytes, int flags); + extern int t_rcv(int fd, char* buf, unsigned int nbytes, int* flags); + #else # include "syscall.h" # include # include -# include # define USE_SELECT #endif @@ -150,13 +169,8 @@ static qse_nwio_errnum_t skerr_to_errnum (int e) } } -/*#elif defined(__DOS__) -static qse_nwio_errnum_t skerr_to_errnum (int e) -{ - - return QSE_NWIO_ESYSERR; -}*/ #else + static qse_nwio_errnum_t skerr_to_errnum (int e) { switch (e) @@ -175,7 +189,7 @@ static qse_nwio_errnum_t skerr_to_errnum (int e) case EEXIST: return QSE_NWIO_EEXIST; - + case EINTR: return QSE_NWIO_EINTR; @@ -217,6 +231,28 @@ static qse_nwio_errnum_t skerr_to_errnum (int e) return QSE_NWIO_ESYSERR; } } + + +#if defined(USE_TLI) +static qse_nwio_errnum_t tlierr_to_errnum (int te, int se) +{ + switch (te) + { + /* TODO: add more t_error conversion */ + + case TACCES: + return QSE_NWIO_EACCES; + + case TSYSERR: + return skerr_to_errnum (se); + + default: + return QSE_NWIO_ESYSERR; + } +} +#endif + + #endif static qse_nwio_errnum_t tio_errnum_to_nwio_errnum (qse_tio_t* tio) @@ -253,7 +289,23 @@ static int wait_for_data (qse_nwio_t* nwio, const qse_ntime_t* tmout, int what) FD_ZERO (&fds[0]); FD_ZERO (&fds[1]); - FD_SET (nwio->handle, &fds[what]); + switch (what) + { + case 0: + case 1: + FD_SET (nwio->handle, &fds[what]); + break; + + case 2: + FD_SET (nwio->handle, &fds[0]); + FD_SET (nwio->handle, &fds[1]); + break; + + default: + nwio->errnum = QSE_NWIO_EINVAL; + return -1; + } + tv.tv_sec = tmout->sec; tv.tv_usec = QSE_NSEC_TO_USEC (tmout->nsec); @@ -417,7 +469,7 @@ int qse_nwio_init ( nwio->tmout.c.sec = -1; nwio->tmout.a.sec = -1; } - + tmp = qse_nwadtoskad (nwad, &addr); if (tmp <= -1) { @@ -426,7 +478,6 @@ int qse_nwio_init ( } addrlen = tmp; - #if defined(SOCK_STREAM) && defined(SOCK_DGRAM) if (flags & QSE_NWIO_TCP) type = SOCK_STREAM; else if (flags & QSE_NWIO_UDP) type = SOCK_DGRAM; @@ -779,6 +830,126 @@ int qse_nwio_init ( } } +#elif defined(USE_TLI) + + { + + static const qse_mchar_t* dev_path[2][2] = + { + { "/dev/tcp", "/dev/inet/tcp" }, + { "/dev/udp", "/dev/inet/tcp" } + }; + int dev_id; + + if (flags & QSE_NWIO_TCP) dev_id = 0; + else + { + QSE_ASSERT (flags & QSE_NWIO_UDP); + dev_id = 1; + } + + nwio->handle = t_open (dev_path[dev_id][0], O_RDWR, QSE_NULL); + if (nwio->handle <= -1) + { + nwio->handle = t_open (dev_path[dev_id][1], O_RDWR, QSE_NULL); + if (nwio->handle <= -1) + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + goto oops; + } + } + + if (flags & QSE_NWIO_PASSIVE) + { + /* TODO: */ + nwio->errnum = QSE_NWIO_ENOIMPL; + goto oops; + } + else + { + struct t_call call; /* for connecting */ + struct t_bind req, ret; /* for binding */ + qse_skad_t reqaddr, retaddr; + qse_nwad_t reqnwad; + + /* + call = t_alloc (nwio->handle, T_CALL, T_ADDR); + if (!call) + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + goto oops; + }*/ + + qse_clearnwad (&reqnwad, nwad->type); + qse_nwadtoskad (&reqnwad, &reqaddr); + + QSE_MEMSET (&ret, 0, QSE_SIZEOF(req)); + req.addr.maxlen = addrlen; + req.addr.len = addrlen; + req.addr.buf = &reqaddr; + + QSE_MEMSET (&ret, 0, QSE_SIZEOF(ret)); + ret.addr.maxlen = addrlen; + ret.addr.len = addrlen; + ret.addr.buf = &retaddr; + + if (t_bind (nwio->handle, &req, &ret) <= -1) + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + goto oops; + } + +/* TODO: should i use t_alloc() and t_free for call, ret, req? */ + QSE_MEMSET (&call, 0, QSE_SIZEOF(call)); + call.addr.maxlen = addrlen; + call.addr.len = addrlen; + call.addr.buf = &addr; + + if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP)) + { + int orgfl; + + orgfl = fcntl (nwio->handle, F_GETFL, 0); + if (orgfl <= -1 || fcntl (nwio->handle, F_SETFL, orgfl | O_NONBLOCK) <= -1) + { + nwio->errnum = skerr_to_errnum (errno); + goto oops; + } + + if (t_connect (nwio->handle, &call, 0) <= -1) + { + if (t_errno != TNODATA) + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + goto oops; + } + + /* TODO: this doesn't seem to work wel... REDO THE WORK */ + if (wait_for_data (nwio, &nwio->tmout.c, 0) <= -1) goto oops; + + if (t_rcvconnect (nwio->handle, QSE_NULL) <= -1) + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + goto oops; + } + } + + if (fcntl (nwio->handle, F_SETFL, orgfl) <= -1) + { + nwio->errnum = skerr_to_errnum (errno); + goto oops; + } + } + else + { + if (t_connect (nwio->handle, &call, 0) <= -1) + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + goto oops; + } + } + } + } #else #if defined(SOCK_CLOEXEC) @@ -841,8 +1012,8 @@ int qse_nwio_init ( goto oops; } - QSE_CLOSE (nwio->handle); - nwio->handle = handle; + qse_closesckhnd (nwio->handle); /* close the listening socket */ + nwio->handle = handle; /* set the handle to the accepted socket */ } else if (flags & QSE_NWIO_UDP) { @@ -852,7 +1023,7 @@ int qse_nwio_init ( else { int xret; - + if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP)) { int orgfl; @@ -1048,7 +1219,7 @@ static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size) if (connect (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1) { nwio->errnum = skerr_to_errnum (WSAGetLastError()); - return -1; + return -1; } nwio->status &= ~STATUS_UDP_CONNECT; } @@ -1093,7 +1264,7 @@ static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size) if (connect (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1) { nwio->errnum = skerr_to_errnum (sock_errno()); - return -1; + return -1; } nwio->status &= ~STATUS_UDP_CONNECT; } @@ -1110,15 +1281,99 @@ static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size) return n; -/*#elif defined(__DOS__) +#elif defined(USE_TLI) - nwio->errnum = QSE_NWIO_ENOIMPL; - return -1; */ + if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int))) + size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int); + +reread: + if (nwio->status & STATUS_UDP_CONNECT) + { + qse_skad_t addr; + qse_sck_len_t addrlen; + + addrlen = QSE_SIZEOF(addr); + + /* it's similar to accept for tcp because i'm expecting + * the first sender and call connect() to it below just + * like the 'nc' utility does. + * so i treat this recvfrom() as if it is accept(). + */ + if (TMOUT_ENABLED(nwio->tmout.a) && + wait_for_data (nwio, &nwio->tmout.a, 0) <= -1) return -1; + + /* TODO: */ + nwio->errnum = QSE_NWIO_ENOIMPL; + return -1; + /* + n = recvfrom ( + nwio->handle, buf, size, 0, + (struct sockaddr*)&addr, &addrlen); + */ + + if (n <= -1) + { + if (t_errno == TSYSERR && errno == EINTR) + { + if (nwio->flags & QSE_NWIO_READNORETRY) + nwio->errnum = QSE_NWIO_EINTR; + else goto reread; + } + else + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + } + } + else if (n >= 1) + { + /* TODO: */ + nwio->errnum = QSE_NWIO_ENOIMPL; + return -1; + + /* for udp, it just creates a stream with the + * first sender */ + /* + if (t_connect (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1) + { + nwio->errnum = skerr_to_errnum (errno); + return -1; + } + nwio->status &= ~STATUS_UDP_CONNECT; + */ + } + } + else + { + int flags; + + if (!(nwio->status & STATUS_TMOUT_R_PRESET) && + TMOUT_ENABLED(nwio->tmout.r) && + wait_for_data (nwio, &nwio->tmout.r, 0) <= -1) + { + return -1; + } + + n = t_rcv (nwio->handle, buf, size, &flags); + if (n <= -1) + { + if (t_errno == TSYSERR && errno == EINTR) + { + if (nwio->flags & QSE_NWIO_READNORETRY) + nwio->errnum = QSE_NWIO_EINTR; + else goto reread; + } + else + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + } + } + } + + return n; #else - if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t))) - size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t); + if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t); reread: if (nwio->status & STATUS_UDP_CONNECT) @@ -1159,7 +1414,7 @@ reread: if (connect (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1) { nwio->errnum = skerr_to_errnum (errno); - return -1; + return -1; } nwio->status &= ~STATUS_UDP_CONNECT; } @@ -1245,15 +1500,35 @@ static qse_ssize_t nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t si if (n <= -1) nwio->errnum = skerr_to_errnum (sock_errno()); return n; -/*#elif defined(__DOS__) +#elif defined(USE_TLI) - nwio->errnum = QSE_NWIO_ENOIMPL; - return -1;*/ + if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int))) + size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int); + +rewrite: + if (!(nwio->status & STATUS_TMOUT_W_PRESET) && + TMOUT_ENABLED(nwio->tmout.w) && + wait_for_data (nwio, &nwio->tmout.w, 1) <= -1) return -1; + + n = t_snd (nwio->handle, data, size, 0); + if (n <= -1) + { + if (errno == EINTR) + { + if (nwio->flags & QSE_NWIO_WRITENORETRY) + nwio->errnum = QSE_NWIO_EINTR; + else goto rewrite; + } + else + { + nwio->errnum = tlierr_to_errnum (t_errno, errno); + } + } + return n; #else - if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t))) - size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t); + if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t); rewrite: if (!(nwio->status & STATUS_TMOUT_W_PRESET) && diff --git a/qse/lib/cmn/sck.c b/qse/lib/cmn/sck.c index 65528f18..0fd0d005 100644 --- a/qse/lib/cmn/sck.c +++ b/qse/lib/cmn/sck.c @@ -47,6 +47,13 @@ # endif #elif defined(__DOS__) # include /* watt-32 */ + +#elif defined(HAVE_T_CONNECT) && !defined(HAVE_CONNECT) && defined(HAVE_TIUSER_H) + +# include "syscall.h" +# include +# define USE_TLI + #else # include "syscall.h" # include @@ -78,7 +85,9 @@ QSE_INLINE int qse_isvalidsckhnd (qse_sck_hnd_t handle) return handle >= 0; #elif defined(__DOS__) + return handle >= 0; +#elif defined(USE_TLI) return handle >= 0; #else @@ -90,10 +99,16 @@ QSE_INLINE void qse_closesckhnd (qse_sck_hnd_t handle) { #if defined(_WIN32) closesocket (handle); + #elif defined(__OS2__) soclose (handle); + #elif defined(__DOS__) close_s (handle); + +#elif defined(USE_TLI) + t_close (handle); + #else QSE_CLOSE (handle); #endif @@ -105,10 +120,29 @@ QSE_INLINE void qse_shutsckhnd (qse_sck_hnd_t handle, qse_shutsckhnd_how_t how) #if defined(_WIN32) shutdown (handle, how_v[how]); + #elif defined(__OS2__) shutdown (handle, how_v[how]); + #elif defined(__DOS__) shutdown (handle, how_v[how]); + +#elif defined(USE_TLI) + /* Is this correct? */ + switch (how) + { + case QSE_SHUTSCKHND_R: + t_rcvrel (handle); + break; + case QSE_SHUTSCKHND_W: + t_sndrel (handle); + break; + case QSE_SHUTSCKHND_RW: + t_rcvrel (handle); + t_sndrel (handle); + break; + } + #else shutdown (handle, how_v[how]); #endif