added a little timeout handling code to nwio
This commit is contained in:
		@ -182,7 +182,7 @@ void* qse_awk_rtx_getxtnstd (
 | 
				
			|||||||
 * The qse_awk_rtx_getcmgrstd() function gets the current character 
 | 
					 * The qse_awk_rtx_getcmgrstd() function gets the current character 
 | 
				
			||||||
 * manager associated with a particular I/O target indicated by the name 
 | 
					 * manager associated with a particular I/O target indicated by the name 
 | 
				
			||||||
 * @a ioname if #QSE_CHAR_IS_WCHAR is defined. It always returns #QSE_NULL
 | 
					 * @a ioname if #QSE_CHAR_IS_WCHAR is defined. It always returns #QSE_NULL
 | 
				
			||||||
 * if #QSE_CHAR_IS_MCHAR.
 | 
					 * if #QSE_CHAR_IS_MCHAR is defined.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
qse_cmgr_t* qse_awk_rtx_getcmgrstd (
 | 
					qse_cmgr_t* qse_awk_rtx_getcmgrstd (
 | 
				
			||||||
	qse_awk_rtx_t*    rtx,
 | 
						qse_awk_rtx_t*    rtx,
 | 
				
			||||||
 | 
				
			|||||||
@ -59,6 +59,7 @@ enum qse_nwio_errnum_t
 | 
				
			|||||||
	QSE_NWIO_ENOENT,     /**< no such file */
 | 
						QSE_NWIO_ENOENT,     /**< no such file */
 | 
				
			||||||
	QSE_NWIO_EEXIST,     /**< already exist */
 | 
						QSE_NWIO_EEXIST,     /**< already exist */
 | 
				
			||||||
	QSE_NWIO_EINTR,      /**< interrupted */
 | 
						QSE_NWIO_EINTR,      /**< interrupted */
 | 
				
			||||||
 | 
						QSE_NWIO_ETMOUT,     /**< timed out */
 | 
				
			||||||
	QSE_NWIO_EPIPE,      /**< broken pipe */
 | 
						QSE_NWIO_EPIPE,      /**< broken pipe */
 | 
				
			||||||
	QSE_NWIO_ECONN,      /**< connection refused */
 | 
						QSE_NWIO_ECONN,      /**< connection refused */
 | 
				
			||||||
	QSE_NWIO_EILSEQ,     /**< illegal sequence */
 | 
						QSE_NWIO_EILSEQ,     /**< illegal sequence */
 | 
				
			||||||
@ -71,6 +72,13 @@ enum qse_nwio_errnum_t
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
typedef enum qse_nwio_errnum_t qse_nwio_errnum_t;
 | 
					typedef enum qse_nwio_errnum_t qse_nwio_errnum_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct qse_nwio_tmout_t 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r, w, c, a;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct qse_nwio_tmout_t qse_nwio_tmout_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32)
 | 
					#if defined(_WIN32)
 | 
				
			||||||
	typedef qse_intptr_t qse_nwio_hnd_t;
 | 
						typedef qse_intptr_t qse_nwio_hnd_t;
 | 
				
			||||||
#elif defined(__OS2__)
 | 
					#elif defined(__OS2__)
 | 
				
			||||||
@ -89,11 +97,12 @@ typedef struct qse_nwio_t qse_nwio_t;
 | 
				
			|||||||
struct qse_nwio_t
 | 
					struct qse_nwio_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QSE_DEFINE_COMMON_FIELDS (nwio)
 | 
						QSE_DEFINE_COMMON_FIELDS (nwio)
 | 
				
			||||||
	int               flags;
 | 
						int                flags;
 | 
				
			||||||
	qse_nwio_errnum_t errnum;
 | 
						qse_nwio_errnum_t  errnum;
 | 
				
			||||||
	qse_nwio_hnd_t    handle;
 | 
						qse_nwio_tmout_t tmout;
 | 
				
			||||||
	qse_tio_t*        tio;
 | 
						qse_nwio_hnd_t     handle;
 | 
				
			||||||
	int               status;
 | 
						qse_tio_t*         tio;
 | 
				
			||||||
 | 
						int                status;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QSE_NWIO_HANDLE(nwio) ((nwio)->handle)
 | 
					#define QSE_NWIO_HANDLE(nwio) ((nwio)->handle)
 | 
				
			||||||
@ -113,10 +122,11 @@ QSE_DEFINE_COMMON_FUNCTIONS (nwio)
 | 
				
			|||||||
 * as a pointer to qse_nwio_hnd_t.
 | 
					 * as a pointer to qse_nwio_hnd_t.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
qse_nwio_t* qse_nwio_open (
 | 
					qse_nwio_t* qse_nwio_open (
 | 
				
			||||||
	qse_mmgr_t*       mmgr,
 | 
						qse_mmgr_t*               mmgr,
 | 
				
			||||||
	qse_size_t        ext,
 | 
						qse_size_t                ext,
 | 
				
			||||||
	const qse_nwad_t* nwad,
 | 
						const qse_nwad_t*         nwad,
 | 
				
			||||||
	int               flags
 | 
						int                       flags,
 | 
				
			||||||
 | 
						const qse_nwio_tmout_t* tmout
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -130,10 +140,11 @@ void qse_nwio_close (
 | 
				
			|||||||
 * The qse_nwio_close() function opens a file into @a nwio.
 | 
					 * The qse_nwio_close() function opens a file into @a nwio.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int qse_nwio_init (
 | 
					int qse_nwio_init (
 | 
				
			||||||
	qse_nwio_t*       nwio,
 | 
						qse_nwio_t*             nwio,
 | 
				
			||||||
	qse_mmgr_t*       mmgr,
 | 
						qse_mmgr_t*             mmgr,
 | 
				
			||||||
	const qse_nwad_t* nwad,
 | 
						const qse_nwad_t*       nwad,
 | 
				
			||||||
	int               flags
 | 
						int                     flags,
 | 
				
			||||||
 | 
						const qse_nwio_tmout_t* tmout
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
				
			|||||||
@ -126,9 +126,11 @@ typedef struct ioattr_t
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
        qse_cmgr_t* cmgr;
 | 
					        qse_cmgr_t* cmgr;
 | 
				
			||||||
	qse_char_t cmgr_name[64]; /* i assume that the cmgr name never exceeds this length */
 | 
						qse_char_t cmgr_name[64]; /* i assume that the cmgr name never exceeds this length */
 | 
				
			||||||
        qse_long_t timeout[3];
 | 
					        qse_long_t tmout[4];
 | 
				
			||||||
} ioattr_t;
 | 
					} ioattr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ioattr_t* get_ioattr (qse_htb_t* tab, const qse_char_t* ptr, qse_size_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y)
 | 
					static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined(HAVE_POWL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
 | 
					#if defined(HAVE_POWL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
 | 
				
			||||||
@ -804,14 +806,16 @@ int qse_awk_parsestd (
 | 
				
			|||||||
/*** RTX_OPENSTD ***/
 | 
					/*** RTX_OPENSTD ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static qse_ssize_t nwio_handler_open (
 | 
					static qse_ssize_t nwio_handler_open (
 | 
				
			||||||
	qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod, int flags, qse_nwad_t* nwad)
 | 
						qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod, int flags, 
 | 
				
			||||||
 | 
						qse_nwad_t* nwad, qse_nwio_tmout_t* tmout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qse_nwio_t* handle;
 | 
						qse_nwio_t* handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	handle = qse_nwio_open (
 | 
						handle = qse_nwio_open (
 | 
				
			||||||
		qse_awk_rtx_getmmgr(rtx), 0, nwad, 
 | 
							qse_awk_rtx_getmmgr(rtx), 0, nwad, 
 | 
				
			||||||
		flags | QSE_NWIO_TEXT | QSE_NWIO_IGNOREMBWCERR |
 | 
							flags | QSE_NWIO_TEXT | QSE_NWIO_IGNOREMBWCERR |
 | 
				
			||||||
		QSE_NWIO_REUSEADDR | QSE_NWIO_READNORETRY | QSE_NWIO_WRITENORETRY
 | 
							QSE_NWIO_REUSEADDR | QSE_NWIO_READNORETRY | QSE_NWIO_WRITENORETRY,
 | 
				
			||||||
 | 
							tmout
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
	if (handle == QSE_NULL) return -1;
 | 
						if (handle == QSE_NULL) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1031,9 +1035,30 @@ static qse_ssize_t awk_rio_pipe (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if (riod->mode != QSE_AWK_RIO_PIPE_RW ||
 | 
							if (riod->mode != QSE_AWK_RIO_PIPE_RW ||
 | 
				
			||||||
		    parse_rwpipe_uri (riod->name, &flags, &nwad) <= -1) 
 | 
							    parse_rwpipe_uri (riod->name, &flags, &nwad) <= -1) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			return pio_handler_open (rtx, riod);
 | 
								return pio_handler_open (rtx, riod);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			return nwio_handler_open (rtx, riod, flags, &nwad);
 | 
							{
 | 
				
			||||||
 | 
								qse_nwio_tmout_t tmout_buf;
 | 
				
			||||||
 | 
								qse_nwio_tmout_t* tmout = QSE_NULL;
 | 
				
			||||||
 | 
								ioattr_t* ioattr;
 | 
				
			||||||
 | 
								rxtn_t* rxtn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								rxtn = (rxtn_t*) QSE_XTN (rtx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ioattr = get_ioattr (&rxtn->cmgrtab, riod->name, qse_strlen(riod->name));
 | 
				
			||||||
 | 
								if (ioattr)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									tmout = &tmout_buf;
 | 
				
			||||||
 | 
									tmout->r = ioattr->tmout[0];
 | 
				
			||||||
 | 
									tmout->w = ioattr->tmout[1];
 | 
				
			||||||
 | 
									tmout->c = ioattr->tmout[2];
 | 
				
			||||||
 | 
									tmout->a = ioattr->tmout[3];
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return nwio_handler_open (rtx, riod, flags, &nwad, tmout);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (riod->handle2)
 | 
						else if (riod->handle2)
 | 
				
			||||||
		return nwio_handler_rest (rtx, cmd, riod, data, size);
 | 
							return nwio_handler_rest (rtx, cmd, riod, data, size);
 | 
				
			||||||
@ -1715,32 +1740,12 @@ static int fnc_time (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qse_cmgr_t* qse_awk_rtx_getcmgrstd (
 | 
					 | 
				
			||||||
	qse_awk_rtx_t* rtx, const qse_char_t* ioname)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#if defined(QSE_CHAR_IS_WCHAR)
 | 
					 | 
				
			||||||
	rxtn_t* rxtn;
 | 
					 | 
				
			||||||
	qse_htb_pair_t* pair;
 | 
					 | 
				
			||||||
	ioattr_t* ioattr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rxtn = (rxtn_t*) QSE_XTN (rtx);
 | 
					 | 
				
			||||||
	QSE_ASSERT (rxtn->cmgrtab_inited == 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pair = qse_htb_search (&rxtn->cmgrtab, ioname, qse_strlen(ioname));
 | 
					 | 
				
			||||||
	if (pair) 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ioattr = (ioattr_t*)QSE_HTB_VPTR(pair);
 | 
					 | 
				
			||||||
		return ioattr->cmgr;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	return QSE_NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int timeout_code (const qse_char_t* name)
 | 
					static int timeout_code (const qse_char_t* name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (qse_strcmp (name, QSE_T("rtimeout")) == 0) return 0;
 | 
						if (qse_strcmp (name, QSE_T("rtimeout")) == 0) return 0;
 | 
				
			||||||
	if (qse_strcmp (name, QSE_T("wtimeout")) == 0) return 1;
 | 
						if (qse_strcmp (name, QSE_T("wtimeout")) == 0) return 1;
 | 
				
			||||||
	if (qse_strcmp (name, QSE_T("ctimeout")) == 0) return 2;
 | 
						if (qse_strcmp (name, QSE_T("ctimeout")) == 0) return 2;
 | 
				
			||||||
 | 
						if (qse_strcmp (name, QSE_T("atimeout")) == 0) return 3;
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1748,13 +1753,24 @@ static QSE_INLINE void init_ioattr (ioattr_t* ioattr)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	QSE_MEMSET (ioattr, 0, QSE_SIZEOF(*ioattr));
 | 
						QSE_MEMSET (ioattr, 0, QSE_SIZEOF(*ioattr));
 | 
				
			||||||
	for (i = 0; i < QSE_COUNTOF(ioattr->timeout); i++) 
 | 
						for (i = 0; i < QSE_COUNTOF(ioattr->tmout); i++) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* a negative number for no timeout */
 | 
							/* a negative number for no timeout */
 | 
				
			||||||
		ioattr->timeout[i] = -999;
 | 
							ioattr->tmout[i] = -999;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ioattr_t* get_ioattr (
 | 
				
			||||||
 | 
						qse_htb_t* tab, const qse_char_t* ptr, qse_size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						qse_htb_pair_t* pair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pair = qse_htb_search (tab, ptr, len);
 | 
				
			||||||
 | 
						if (pair) return QSE_HTB_VPTR(pair);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return QSE_NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static qse_htb_pair_t* find_or_make_ioattr (
 | 
					static qse_htb_pair_t* find_or_make_ioattr (
 | 
				
			||||||
	qse_awk_rtx_t* rtx, qse_htb_t* tab, const qse_char_t* ptr, qse_size_t len)
 | 
						qse_awk_rtx_t* rtx, qse_htb_t* tab, const qse_char_t* ptr, qse_size_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1767,7 +1783,7 @@ static qse_htb_pair_t* find_or_make_ioattr (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		init_ioattr (&ioattr);
 | 
							init_ioattr (&ioattr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pair = qse_htb_insert (tab, ptr, len, &ioattr, QSE_SIZEOF(ioattr));
 | 
							pair = qse_htb_insert (tab, (void*)ptr, len, (void*)&ioattr, QSE_SIZEOF(ioattr));
 | 
				
			||||||
		if (pair == QSE_NULL)
 | 
							if (pair == QSE_NULL)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
 | 
								qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
 | 
				
			||||||
@ -1841,7 +1857,7 @@ static int fnc_setioattr (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ioattr = QSE_HTB_VPTR(pair);
 | 
							ioattr = QSE_HTB_VPTR(pair);
 | 
				
			||||||
		ioattr->timeout[tmout] = l;
 | 
							ioattr->tmout[tmout] = l;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#if defined(QSE_CHAR_IS_WCHAR)
 | 
					#if defined(QSE_CHAR_IS_WCHAR)
 | 
				
			||||||
	else if (qse_strcmp (ptr[1], QSE_T("codepage")) == 0)
 | 
						else if (qse_strcmp (ptr[1], QSE_T("codepage")) == 0)
 | 
				
			||||||
@ -1955,7 +1971,7 @@ static int fnc_getioattr (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ((tmout = timeout_code (ptr[1])) >= 0)
 | 
						if ((tmout = timeout_code (ptr[1])) >= 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		rv = qse_awk_rtx_makeintval (rtx, ioattr->timeout[tmout]);
 | 
							rv = qse_awk_rtx_makeintval (rtx, ioattr->tmout[tmout]);
 | 
				
			||||||
		if (rv == QSE_NULL) 
 | 
							if (rv == QSE_NULL) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			ret = -1;
 | 
								ret = -1;
 | 
				
			||||||
@ -1999,6 +2015,22 @@ done:
 | 
				
			|||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qse_cmgr_t* qse_awk_rtx_getcmgrstd (
 | 
				
			||||||
 | 
						qse_awk_rtx_t* rtx, const qse_char_t* ioname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(QSE_CHAR_IS_WCHAR)
 | 
				
			||||||
 | 
						rxtn_t* rxtn;
 | 
				
			||||||
 | 
						ioattr_t* ioattr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rxtn = (rxtn_t*) QSE_XTN (rtx);
 | 
				
			||||||
 | 
						QSE_ASSERT (rxtn->cmgrtab_inited == 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ioattr = get_ioattr (&rxtn->cmgrtab, ioname, qse_strlen(ioname));
 | 
				
			||||||
 | 
						if (ioattr) return ioattr->cmgr;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						return QSE_NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ADDFNC(awk,name,min,max,fnc,valid) \
 | 
					#define ADDFNC(awk,name,min,max,fnc,valid) \
 | 
				
			||||||
        if (qse_awk_addfnc (\
 | 
					        if (qse_awk_addfnc (\
 | 
				
			||||||
		(awk), (name), qse_strlen(name), \
 | 
							(awk), (name), qse_strlen(name), \
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <qse/cmn/nwio.h>
 | 
					#include <qse/cmn/nwio.h>
 | 
				
			||||||
 | 
					#include <qse/cmn/time.h>
 | 
				
			||||||
#include "mem.h"
 | 
					#include "mem.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32)
 | 
					#if defined(_WIN32)
 | 
				
			||||||
@ -37,6 +38,7 @@
 | 
				
			|||||||
#	include "syscall.h"
 | 
					#	include "syscall.h"
 | 
				
			||||||
#	include <sys/socket.h>
 | 
					#	include <sys/socket.h>
 | 
				
			||||||
#	include <netinet/in.h>
 | 
					#	include <netinet/in.h>
 | 
				
			||||||
 | 
					#	include <sys/time.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QSE_IMPLEMENT_COMMON_FUNCTIONS (nwio)
 | 
					QSE_IMPLEMENT_COMMON_FUNCTIONS (nwio)
 | 
				
			||||||
@ -249,14 +251,15 @@ static qse_nwio_errnum_t tio_errnum_to_nwio_errnum (qse_tio_t* tio)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qse_nwio_t* qse_nwio_open (
 | 
					qse_nwio_t* qse_nwio_open (
 | 
				
			||||||
	qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_nwad_t* nwad, int flags)
 | 
						qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_nwad_t* nwad, 
 | 
				
			||||||
 | 
						int flags, const qse_nwio_tmout_t* tmout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qse_nwio_t* nwio;
 | 
						qse_nwio_t* nwio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nwio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_nwio_t) + xtnsize);
 | 
						nwio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_nwio_t) + xtnsize);
 | 
				
			||||||
	if (nwio == QSE_NULL) return QSE_NULL;
 | 
						if (nwio == QSE_NULL) return QSE_NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (qse_nwio_init (nwio, mmgr, nwad, flags) <= -1)
 | 
						if (qse_nwio_init (nwio, mmgr, nwad, flags, tmout) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		QSE_MMGR_FREE (mmgr, nwio);
 | 
							QSE_MMGR_FREE (mmgr, nwio);
 | 
				
			||||||
		return QSE_NULL;
 | 
							return QSE_NULL;
 | 
				
			||||||
@ -272,7 +275,8 @@ void qse_nwio_close (qse_nwio_t* nwio)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int qse_nwio_init (
 | 
					int qse_nwio_init (
 | 
				
			||||||
	qse_nwio_t* nwio, qse_mmgr_t* mmgr, const qse_nwad_t* nwad, int flags)
 | 
						qse_nwio_t* nwio, qse_mmgr_t* mmgr, const qse_nwad_t* nwad, 
 | 
				
			||||||
 | 
						int flags, const qse_nwio_tmout_t* tmout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined(AF_INET)
 | 
					#if defined(AF_INET)
 | 
				
			||||||
	union sockaddr_t addr;
 | 
						union sockaddr_t addr;
 | 
				
			||||||
@ -289,6 +293,14 @@ int qse_nwio_init (
 | 
				
			|||||||
	nwio->mmgr = mmgr;
 | 
						nwio->mmgr = mmgr;
 | 
				
			||||||
	nwio->flags = flags;
 | 
						nwio->flags = flags;
 | 
				
			||||||
	nwio->errnum = QSE_NWIO_ENOERR;
 | 
						nwio->errnum = QSE_NWIO_ENOERR;
 | 
				
			||||||
 | 
						if (tmout) nwio->tmout = *tmout;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							nwio->tmout.r = -1;
 | 
				
			||||||
 | 
							nwio->tmout.w = -1;
 | 
				
			||||||
 | 
							nwio->tmout.c = -1;
 | 
				
			||||||
 | 
							nwio->tmout.a = -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
#if defined(AF_INET)
 | 
					#if defined(AF_INET)
 | 
				
			||||||
	tmp = nwad_to_sockaddr (nwad, &family, &addr);
 | 
						tmp = nwad_to_sockaddr (nwad, &family, &addr);
 | 
				
			||||||
@ -504,10 +516,82 @@ int qse_nwio_init (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (connect (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1)
 | 
							int orgfl, xret;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if (nwio->tmout.c >= 0 && (flags & QSE_NWIO_TCP))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			nwio->errnum = syserr_to_errnum (errno);
 | 
								orgfl = fcntl (nwio->handle, F_GETFL, 0);
 | 
				
			||||||
			goto oops;
 | 
								if (orgfl <= -1 ||
 | 
				
			||||||
 | 
								    fcntl (nwio->handle, F_SETFL, orgfl | O_NONBLOCK) <= -1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									nwio->errnum = syserr_to_errnum (errno);
 | 
				
			||||||
 | 
									goto oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							xret = connect (nwio->handle, (struct sockaddr*)&addr, addrlen);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if (nwio->tmout.c >= 0 && (flags & QSE_NWIO_TCP))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								fd_set wfds;
 | 
				
			||||||
 | 
								struct timeval tv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ((xret <= -1 && errno != EINPROGRESS) ||
 | 
				
			||||||
 | 
								    fcntl (nwio->handle, F_SETFL, orgfl) <= -1) 
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									nwio->errnum = syserr_to_errnum (errno);
 | 
				
			||||||
 | 
									goto oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								FD_ZERO (&wfds);
 | 
				
			||||||
 | 
								FD_SET (nwio->handle, &wfds);
 | 
				
			||||||
 | 
								tv.tv_sec = nwio->tmout.c / QSE_MSECS_PER_SEC;
 | 
				
			||||||
 | 
								tv.tv_usec = (nwio->tmout.c % QSE_MSECS_PER_SEC) * 
 | 
				
			||||||
 | 
								             QSE_USECS_PER_MSEC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								xret = select (nwio->handle + 1, 
 | 
				
			||||||
 | 
									QSE_NULL, &wfds, QSE_NULL, &tv);
 | 
				
			||||||
 | 
								if (xret <= -1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									nwio->errnum = syserr_to_errnum (errno);
 | 
				
			||||||
 | 
									goto oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (xret == 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									nwio->errnum = QSE_NWIO_ETMOUT;
 | 
				
			||||||
 | 
									goto oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (!FD_ISSET (nwio->handle, &wfds))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									nwio->errnum = QSE_NWIO_ECONN;
 | 
				
			||||||
 | 
									goto oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else 
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								#if defined(HAVE_SOCKLEN_T)
 | 
				
			||||||
 | 
									socklen_t xlen;
 | 
				
			||||||
 | 
								#else
 | 
				
			||||||
 | 
									int xlen;
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
									if (getsockopt (nwio->handle, SOL_SOCKET, SO_ERROR, (char*)&xret, &xlen) <= -1)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										nwio->errnum = syserr_to_errnum (errno);
 | 
				
			||||||
 | 
										goto oops;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else if (xret != 0)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										nwio->errnum = syserr_to_errnum (xret);
 | 
				
			||||||
 | 
										goto oops;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (xret <= -1)
 | 
				
			||||||
 | 
								{	
 | 
				
			||||||
 | 
									nwio->errnum = syserr_to_errnum (errno);
 | 
				
			||||||
 | 
									goto oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -640,6 +724,33 @@ void qse_nwio_purge (qse_nwio_t* nwio)
 | 
				
			|||||||
	if (nwio->tio) qse_tio_purge (nwio->tio);
 | 
						if (nwio->tio) qse_tio_purge (nwio->tio);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int wait_for_data (qse_nwio_t* nwio, int tmout, int what)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int xret;
 | 
				
			||||||
 | 
						fd_set fds[2];
 | 
				
			||||||
 | 
						struct timeval tv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FD_ZERO (&fds[0]);
 | 
				
			||||||
 | 
						FD_ZERO (&fds[1]);
 | 
				
			||||||
 | 
						FD_SET (nwio->handle, &fds[what]);
 | 
				
			||||||
 | 
						tv.tv_sec = tmout / QSE_MSECS_PER_SEC;
 | 
				
			||||||
 | 
						tv.tv_usec = (tmout % QSE_MSECS_PER_SEC) * 
 | 
				
			||||||
 | 
						             QSE_USECS_PER_MSEC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xret = select (nwio->handle + 1, &fds[0], &fds[1], QSE_NULL, &tv);
 | 
				
			||||||
 | 
						if (xret <= -1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							nwio->errnum = syserr_to_errnum (errno);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (xret == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							nwio->errnum = QSE_NWIO_ETMOUT;
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
/* ---------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
 | 
					static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
 | 
				
			||||||
@ -749,6 +860,10 @@ reread:
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		addrlen = QSE_SIZEOF(addr);
 | 
							addrlen = QSE_SIZEOF(addr);
 | 
				
			||||||
 | 
							/* it's similar to accept for tcp. 
 | 
				
			||||||
 | 
							 * since i'm expecting the first sender and call
 | 
				
			||||||
 | 
							 * connect() to it below.
 | 
				
			||||||
 | 
							 * TODO: do i have apply tmout.a instead of tmout.r??? */
 | 
				
			||||||
		n = recvfrom (
 | 
							n = recvfrom (
 | 
				
			||||||
			nwio->handle, buf, size, 0, 
 | 
								nwio->handle, buf, size, 0, 
 | 
				
			||||||
			(struct sockaddr*)&addr, &addrlen);
 | 
								(struct sockaddr*)&addr, &addrlen);
 | 
				
			||||||
@ -779,6 +894,11 @@ reread:
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							if (nwio->tmout.r >= 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (wait_for_data (nwio, nwio->tmout.r, 0) <= -1) return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		n = recv (nwio->handle, buf, size, 0);
 | 
							n = recv (nwio->handle, buf, size, 0);
 | 
				
			||||||
		if (n <= -1) 
 | 
							if (n <= -1) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user