added some experimental and unfinished code using tli

This commit is contained in:
2014-11-20 15:12:28 +00:00
parent 619425cd72
commit 8678660b82
6 changed files with 444 additions and 41 deletions

View File

@ -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 <tiuser.h>
# include <sys/socket.h>
# include <netinet/in.h>
# 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 <sys/socket.h>
# include <netinet/in.h>
# include <sys/time.h>
# 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) &&

View File

@ -47,6 +47,13 @@
# endif
#elif defined(__DOS__)
# include <tcp.h> /* watt-32 */
#elif defined(HAVE_T_CONNECT) && !defined(HAVE_CONNECT) && defined(HAVE_TIUSER_H)
# include "syscall.h"
# include <tiuser.h>
# define USE_TLI
#else
# include "syscall.h"
# include <sys/socket.h>
@ -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