started adding nwio
This commit is contained in:
parent
4488041fd3
commit
005471b505
@ -29,6 +29,7 @@
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/cmn/xma.h>
|
||||
#include <qse/cmn/nwio.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
@ -55,6 +56,10 @@
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
static qse_awk_rtx_t* app_rtx = QSE_NULL;
|
||||
static int app_debug = 0;
|
||||
|
||||
@ -93,6 +98,11 @@ struct gvmv_t
|
||||
qse_size_t len;
|
||||
};
|
||||
|
||||
struct rtx_xtn_t
|
||||
{
|
||||
qse_awk_rio_fun_t old_pipe_handler;
|
||||
};
|
||||
|
||||
static void dprint (const qse_char_t* fmt, ...)
|
||||
{
|
||||
if (app_debug)
|
||||
@ -884,6 +894,101 @@ static qse_mmgr_t debug_mmgr =
|
||||
};
|
||||
#endif
|
||||
|
||||
static qse_ssize_t nwio_handler (
|
||||
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
|
||||
qse_char_t* data, qse_size_t size, qse_nwad_t* nwad)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case QSE_AWK_RIO_OPEN:
|
||||
{
|
||||
qse_nwio_t* handle;
|
||||
|
||||
handle = qse_nwio_open (
|
||||
qse_awk_rtx_getmmgr(rtx), 0, nwad,
|
||||
QSE_NWIO_TEXT | QSE_NWIO_IGNOREMBWCERR |
|
||||
QSE_NWIO_READNORETRY | QSE_NWIO_WRITENORETRY
|
||||
);
|
||||
if (handle == QSE_NULL) return -1;
|
||||
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
{
|
||||
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
|
||||
if (cmgr) qse_nwio_setcmgr (handle, cmgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
riod->handle = (void*)handle;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case QSE_AWK_RIO_CLOSE:
|
||||
{
|
||||
qse_nwio_close ((qse_nwio_t*)riod->handle);
|
||||
riod->handle = QSE_NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case QSE_AWK_RIO_READ:
|
||||
{
|
||||
return qse_nwio_read ((qse_nwio_t*)riod->handle, data, size);
|
||||
}
|
||||
|
||||
case QSE_AWK_RIO_WRITE:
|
||||
{
|
||||
return qse_nwio_write ((qse_nwio_t*)riod->handle, data, size);
|
||||
}
|
||||
|
||||
case QSE_AWK_RIO_FLUSH:
|
||||
{
|
||||
/*if (riod->mode == QSE_AWK_RIO_PIPE_READ) return -1;*/
|
||||
return qse_nwio_flush ((qse_nwio_t*)riod->handle);
|
||||
}
|
||||
|
||||
case QSE_AWK_RIO_NEXT:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static qse_ssize_t new_pipe_handler (
|
||||
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
|
||||
qse_char_t* data, qse_size_t size)
|
||||
{
|
||||
struct rtx_xtn_t* xtn;
|
||||
qse_nwad_t nwad;
|
||||
|
||||
xtn = qse_awk_rtx_getxtnstd (rtx);
|
||||
|
||||
if (qse_strtonwad (riod->name, &nwad) >= 0)
|
||||
return nwio_handler (rtx, cmd, riod, data, size, &nwad);
|
||||
|
||||
return xtn->old_pipe_handler (rtx, cmd, riod, data, size);
|
||||
}
|
||||
|
||||
static void extend_pipe_handler (qse_awk_rtx_t* rtx)
|
||||
{
|
||||
struct rtx_xtn_t* xtn;
|
||||
qse_awk_rio_t rio;
|
||||
|
||||
xtn = qse_awk_rtx_getxtnstd (rtx);
|
||||
|
||||
/* get the previous handler functions */
|
||||
qse_awk_rtx_getrio (rtx, &rio);
|
||||
|
||||
/* remember the old pipe handler function */
|
||||
xtn->old_pipe_handler = rio.pipe;
|
||||
|
||||
/* change the pipe handler to a new one */
|
||||
rio.pipe = new_pipe_handler;
|
||||
|
||||
/* changes the handlers with a new set */
|
||||
qse_awk_rtx_setrio (rtx, &rio);
|
||||
}
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
@ -999,7 +1104,7 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
#endif
|
||||
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk, 0, QSE_T("qseawk"),
|
||||
awk, QSE_SIZEOF(struct rtx_xtn_t), QSE_T("qseawk"),
|
||||
(const qse_char_t*const*)arg.icf, QSE_NULL, arg.console_cmgr);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
@ -1013,6 +1118,8 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
goto oops;
|
||||
}
|
||||
|
||||
extend_pipe_handler (rtx);
|
||||
|
||||
app_rtx = rtx;
|
||||
#ifdef ENABLE_CALLBACK
|
||||
qse_awk_rtx_pushrcb (rtx, &rcb);
|
||||
|
37
qse/configure
vendored
37
qse/configure
vendored
@ -16002,7 +16002,7 @@ fi
|
||||
|
||||
done
|
||||
|
||||
for ac_header in time.h sys/time.h utime.h spawn.h
|
||||
for ac_header in time.h sys/time.h utime.h spawn.h execinfo.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"
|
||||
@ -16015,7 +16015,7 @@ fi
|
||||
|
||||
done
|
||||
|
||||
for ac_header in sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h
|
||||
for ac_header in sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h sys/epoll.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"
|
||||
@ -16028,18 +16028,6 @@ fi
|
||||
|
||||
done
|
||||
|
||||
for ac_header in execinfo.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_execinfo_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_EXECINFO_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "#include <stddef.h>
|
||||
"
|
||||
@ -16542,6 +16530,27 @@ fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
$as_echo "#define HAVE_EPOLL /**/" >>confdefs.h
|
||||
|
||||
for ac_func in epoll_create epoll_create1
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
if test "$ac_cv_func_epoll_create" = "yes"
|
||||
then
|
||||
$as_echo "#define HAVE_EPOLL 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lunicows" >&5
|
||||
$as_echo_n "checking for main in -lunicows... " >&6; }
|
||||
if ${ac_cv_lib_unicows_main+:} false; then :
|
||||
|
@ -83,9 +83,8 @@ AC_SUBST(LIBM, $LIBM)
|
||||
dnl check header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h])
|
||||
AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h])
|
||||
AC_CHECK_HEADERS([sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h])
|
||||
AC_CHECK_HEADERS([execinfo.h])
|
||||
AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h])
|
||||
AC_CHECK_HEADERS([sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h sys/epoll.h])
|
||||
|
||||
dnl check data types
|
||||
AC_CHECK_TYPE([wchar_t],
|
||||
@ -173,6 +172,13 @@ then
|
||||
fi
|
||||
AC_SUBST(SENDFILE_LIBS)
|
||||
|
||||
AC_DEFINE(HAVE_EPOLL, [], [epoll support])
|
||||
AC_CHECK_FUNCS([epoll_create epoll_create1])
|
||||
if test "$ac_cv_func_epoll_create" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_EPOLL, 1)
|
||||
fi
|
||||
|
||||
dnl check is the import library for unicows.dll exists
|
||||
dnl this check doesn't look for a particular symbol
|
||||
dnl but for the symbol 'main' since i want to check
|
||||
|
@ -1674,6 +1674,24 @@ void qse_awk_rtx_stop (
|
||||
qse_awk_rtx_t* rtx /**< runtime context */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_rtx_getrio() function copies runtime I/O handlers
|
||||
* to the memory buffer pointed to by @a rio.
|
||||
*/
|
||||
void qse_awk_rtx_getrio (
|
||||
qse_awk_rtx_t* rtx,
|
||||
qse_awk_rio_t* rio
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_rtx_getrio() function sets runtime I/O handlers
|
||||
* with the functions pointed to by @a rio.
|
||||
*/
|
||||
void qse_awk_rtx_setrio (
|
||||
qse_awk_rtx_t* rtx,
|
||||
const qse_awk_rio_t* rio
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_rtx_poprcb() function pops a runtime callback set
|
||||
* and returns the pointer to it. If no callback set can be popped,
|
||||
|
@ -166,12 +166,23 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_rtx_getxtnstd() gets the pointer to extension space.
|
||||
* The qse_awk_rtx_getxtnstd() function gets the pointer to extension space.
|
||||
*/
|
||||
void* qse_awk_rtx_getxtnstd (
|
||||
qse_awk_rtx_t* rtx
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* The qse_awk_rtx_getcmgrstd() function gets the current character
|
||||
* manager associated with a particular I/O target indicated by the name
|
||||
* @a ioname.
|
||||
*/
|
||||
qse_cmgr_t* qse_awk_rtx_getcmgrstd (
|
||||
qse_awk_rtx_t* rtx,
|
||||
const qse_char_t* ioname
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@ pkginclude_HEADERS = \
|
||||
mbwc.h \
|
||||
mem.h \
|
||||
nwad.h \
|
||||
nwio.h \
|
||||
oht.h \
|
||||
opt.h \
|
||||
path.h \
|
||||
|
@ -53,9 +53,9 @@ SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dll.h env.h \
|
||||
fio.h fma.h fmt.h fs.h gdl.h htb.h hton.h ipad.h lda.h main.h \
|
||||
map.h mbwc.h mem.h nwad.h oht.h opt.h path.h pio.h pma.h rbt.h \
|
||||
rex.h sio.h sll.h slmb.h stdio.h str.h time.h tio.h tre.h \
|
||||
utf8.h xma.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
||||
map.h mbwc.h mem.h nwad.h nwio.h oht.h opt.h path.h pio.h \
|
||||
pma.h rbt.h rex.h sio.h sll.h slmb.h stdio.h str.h time.h \
|
||||
tio.h tre.h utf8.h xma.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
@ -231,9 +231,9 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
pkginclude_HEADERS = alg.h chr.h cp949.h cp950.h dll.h env.h fio.h \
|
||||
fma.h fmt.h fs.h gdl.h htb.h hton.h ipad.h lda.h main.h map.h \
|
||||
mbwc.h mem.h nwad.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h \
|
||||
sio.h sll.h slmb.h stdio.h str.h time.h tio.h tre.h utf8.h \
|
||||
xma.h $(am__append_1)
|
||||
mbwc.h mem.h nwad.h nwio.h oht.h opt.h path.h pio.h pma.h \
|
||||
rbt.h rex.h sio.h sll.h slmb.h stdio.h str.h time.h tio.h \
|
||||
tre.h utf8.h xma.h $(am__append_1)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
201
qse/include/qse/cmn/nwio.h
Normal file
201
qse/include/qse/cmn/nwio.h
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
|
||||
QSE 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 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
QSE 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_CMN_NWIO_H_
|
||||
#define _QSE_CMN_NWIO_H_
|
||||
|
||||
/** @file
|
||||
* This file defines a generic text I/O interface.
|
||||
*/
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/cmn/tio.h>
|
||||
#include <qse/cmn/nwad.h>
|
||||
|
||||
enum qse_nwio_flag_t
|
||||
{
|
||||
QSE_NWIO_TEXT = (1 << 0),
|
||||
QSE_NWIO_IGNOREMBWCERR = (1 << 1),
|
||||
QSE_NWIO_NOAUTOFLUSH = (1 << 2),
|
||||
|
||||
/* normal open flags */
|
||||
QSE_NWIO_READ = (1 << 8),
|
||||
QSE_NWIO_WRITE = (1 << 9),
|
||||
|
||||
/** do not reread if read has been interrupted */
|
||||
QSE_NWIO_READNORETRY = (1 << 10),
|
||||
/** do not rewrite if write has been interrupted */
|
||||
QSE_NWIO_WRITENORETRY = (1 << 11),
|
||||
QSE_NWIO_LISTEN = (1 << 12)
|
||||
};
|
||||
|
||||
enum qse_nwio_errnum_t
|
||||
{
|
||||
QSE_NWIO_ENOERR = 0, /**< no error */
|
||||
|
||||
QSE_NWIO_ENOMEM, /**< out of memory */
|
||||
QSE_NWIO_EINVAL, /**< invalid parameter */
|
||||
QSE_NWIO_EACCES, /**< access denied */
|
||||
QSE_NWIO_ENOENT, /**< no such file */
|
||||
QSE_NWIO_EEXIST, /**< already exist */
|
||||
QSE_NWIO_EINTR, /**< interrupted */
|
||||
QSE_NWIO_EPIPE, /**< broken pipe */
|
||||
QSE_NWIO_ECONN, /**< connection refused */
|
||||
QSE_NWIO_EILSEQ, /**< illegal sequence */
|
||||
QSE_NWIO_EICSEQ, /**< incomplete sequence */
|
||||
QSE_NWIO_EILCHR, /**< illegal character */
|
||||
QSE_NWIO_ESYSERR, /**< subsystem(system call) error */
|
||||
QSE_NWIO_ENOIMPL, /**< not implemented */
|
||||
|
||||
QSE_NWIO_EOTHER /**< other error */
|
||||
};
|
||||
typedef enum qse_nwio_errnum_t qse_nwio_errnum_t;
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* TODO: */
|
||||
#elif defined(__OS2__)
|
||||
/* TODO: */
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
typedef int qse_nwio_hnd_t; /**< defines a pipe handle type */
|
||||
# define QSE_NWIO_HND_NIL ((qse_nwio_hnd_t)-1)
|
||||
#endif
|
||||
|
||||
typedef struct qse_nwio_t qse_nwio_t;
|
||||
|
||||
struct qse_nwio_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (nwio)
|
||||
int flags;
|
||||
qse_nwio_errnum_t errnum;
|
||||
qse_nwio_hnd_t handle;
|
||||
qse_tio_t* tio;
|
||||
};
|
||||
|
||||
#define QSE_NWIO_HANDLE(nwio) ((nwio)->handle)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (nwio)
|
||||
|
||||
/**
|
||||
* The qse_nwio_open() function opens a file.
|
||||
* To open a file, you should set the flags with at least one of
|
||||
* QSE_NWIO_READ, QSE_NWIO_WRITE, QSE_NWIO_APPEND.
|
||||
*
|
||||
* If the #QSE_NWIO_HANDLE flag is set, the @a nwad parameter is interpreted
|
||||
* as a pointer to qse_nwio_hnd_t.
|
||||
*/
|
||||
qse_nwio_t* qse_nwio_open (
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t ext,
|
||||
const qse_nwad_t* nwad,
|
||||
int flags
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_nwio_close() function closes a file.
|
||||
*/
|
||||
void qse_nwio_close (
|
||||
qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_nwio_close() function opens a file into @a nwio.
|
||||
*/
|
||||
int qse_nwio_init (
|
||||
qse_nwio_t* nwio,
|
||||
qse_mmgr_t* mmgr,
|
||||
const qse_nwad_t* nwad,
|
||||
int flags
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_nwio_close() function finalizes a file by closing the handle
|
||||
* stored in @a nwio.
|
||||
*/
|
||||
void qse_nwio_fini (
|
||||
qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
qse_nwio_errnum_t qse_nwio_geterrnum (
|
||||
const qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_nwio_gethandle() function returns the native file handle.
|
||||
*/
|
||||
qse_nwio_hnd_t qse_nwio_gethandle (
|
||||
const qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
qse_ubi_t qse_nwio_gethandleasubi (
|
||||
const qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
|
||||
qse_cmgr_t* qse_nwio_getcmgr (
|
||||
qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
void qse_nwio_setcmgr (
|
||||
qse_nwio_t* nwio,
|
||||
qse_cmgr_t* cmgr
|
||||
);
|
||||
|
||||
|
||||
qse_ssize_t qse_nwio_flush (
|
||||
qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
void qse_nwio_purge (
|
||||
qse_nwio_t* nwio
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_nwio_read() function reads data.
|
||||
*/
|
||||
qse_ssize_t qse_nwio_read (
|
||||
qse_nwio_t* nwio,
|
||||
void* buf,
|
||||
qse_size_t size
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_nwio_write() function writes data.
|
||||
* If QSE_NWIO_TEXT is used and the size parameter is (qse_size_t)-1,
|
||||
* the function treats the data parameter as a pointer to a null-terminated
|
||||
* string.
|
||||
*/
|
||||
qse_ssize_t qse_nwio_write (
|
||||
qse_nwio_t* nwio,
|
||||
const void* data,
|
||||
qse_size_t size
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -83,7 +83,16 @@ enum qse_pio_flag_t
|
||||
/** drop stdout */
|
||||
QSE_PIO_DROPOUT = (1 << 17),
|
||||
/** drop stderr */
|
||||
QSE_PIO_DROPERR = (1 << 18)
|
||||
QSE_PIO_DROPERR = (1 << 18),
|
||||
|
||||
/** do not reread if read has been interrupted */
|
||||
QSE_PIO_READNORETRY = (1 << 21),
|
||||
/** do not rewrite if write has been interrupted */
|
||||
QSE_PIO_WRITENORETRY = (1 << 22),
|
||||
/** return immediately from qse_pio_wait() if a child has not exited */
|
||||
QSE_PIO_WAITNOBLOCK = (1 << 23),
|
||||
/** do not wait again if waitpid has been interrupted */
|
||||
QSE_PIO_WAITNORETRY = (1 << 24)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -97,29 +106,6 @@ enum qse_pio_hid_t
|
||||
};
|
||||
typedef enum qse_pio_hid_t qse_pio_hid_t;
|
||||
|
||||
/**
|
||||
* The qse_pio_option_t type defines options to change the behavior of
|
||||
* qse_pio_xxx functions.
|
||||
*/
|
||||
enum qse_pio_option_t
|
||||
{
|
||||
/*QSE_PIO_READ_NOBLOCK = (1 << 0),*/
|
||||
|
||||
/** do not reread if read has been interrupted */
|
||||
QSE_PIO_READ_NORETRY = (1 << 1),
|
||||
|
||||
/*QSE_PIO_WRITE_NOBLOCK = (1 << 2),*/
|
||||
|
||||
/** do not rewrite if write has been interrupted */
|
||||
QSE_PIO_WRITE_NORETRY = (1 << 3),
|
||||
|
||||
/** return immediately from qse_pio_wait() if a child has not exited */
|
||||
QSE_PIO_WAIT_NOBLOCK = (1 << 4),
|
||||
|
||||
/** do not wait again if waitpid has been interrupted */
|
||||
QSE_PIO_WAIT_NORETRY = (1 << 5)
|
||||
};
|
||||
|
||||
/**
|
||||
* The qse_pio_errnum_t type defines error numbers.
|
||||
*/
|
||||
@ -190,7 +176,7 @@ struct qse_pio_pin_t
|
||||
struct qse_pio_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS(pio)
|
||||
int option; /**< options */
|
||||
int flags; /**< options */
|
||||
qse_pio_errnum_t errnum; /**< error number */
|
||||
qse_pio_pid_t child; /**< handle to a child process */
|
||||
qse_pio_pin_t pin[3];
|
||||
@ -198,8 +184,6 @@ struct qse_pio_t
|
||||
|
||||
/** access the @a errnum field of the #qse_pio_t structure */
|
||||
#define QSE_PIO_ERRNUM(pio) ((pio)->errnum)
|
||||
/** access the @a option field of the #qse_pio_t structure */
|
||||
#define QSE_PIO_OPTION(pio) ((pio)->option)
|
||||
/** access the @a child field of the #qse_pio_t structure */
|
||||
#define QSE_PIO_CHILD(pio) ((pio)->child)
|
||||
/** get the native handle from the #qse_pio_t structure */
|
||||
@ -272,23 +256,6 @@ qse_pio_errnum_t qse_pio_geterrnum (
|
||||
const qse_pio_t* pio /**< pio object */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_pio_getoption() function gets the current option.
|
||||
* @return option number OR'ed of #qse_pio_option_t enumerators
|
||||
*/
|
||||
int qse_pio_getoption (
|
||||
const qse_pio_t* pio /**< pio object */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_pio_setoption() function sets the option.
|
||||
*/
|
||||
void qse_pio_setoption (
|
||||
qse_pio_t* pio, /**< pio object */
|
||||
int opt /**< 0 or a number OR'ed of #qse_pio_option_t
|
||||
enumerators */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_pio_getcmgr() function returns the current character manager.
|
||||
* It returns #QSE_NULL is @a pio is not opened with #QSE_PIO_TEXT.
|
||||
@ -368,6 +335,15 @@ qse_ssize_t qse_pio_flush (
|
||||
qse_pio_hid_t hid /**< handle ID */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_pio_purge() drops unflushed input and output data in the
|
||||
* buffer.
|
||||
*/
|
||||
void qse_pio_purge (
|
||||
qse_pio_t* pio, /**< pio object */
|
||||
qse_pio_hid_t hid /**< handle ID */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_pio_end() function closes a pipe to a child process
|
||||
*/
|
||||
|
@ -99,15 +99,7 @@ struct qse_sio_t
|
||||
QSE_DEFINE_COMMON_FIELDS (sio)
|
||||
qse_sio_errnum_t errnum;
|
||||
|
||||
/*
|
||||
depending on the stream type... FILE, FIFO, TCP, UDP
|
||||
qse_sio_type_t type;
|
||||
*/
|
||||
union
|
||||
{
|
||||
qse_fio_t file;
|
||||
int sck;
|
||||
} u;
|
||||
|
||||
struct
|
||||
{
|
||||
@ -126,30 +118,6 @@ struct qse_sio_t
|
||||
/** access the @a errnum field of the #qse_sio_t structure */
|
||||
#define QSE_SIO_ERRNUM(sio) ((sio)->errnum)
|
||||
|
||||
#if 0
|
||||
typedef struct qse_sio_uri_t qse_sio_uri_t;
|
||||
struct qse_sio_uri_t
|
||||
{
|
||||
enum
|
||||
{
|
||||
QSE_SIO_FILE,
|
||||
QSE_SIO_FIFO,
|
||||
QSE_SIO_PIPE,
|
||||
QSE_SIO_TCP,
|
||||
QSE_SIO_UDP
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
const qse_char_t* file;
|
||||
const qse_char_t* fifo;
|
||||
/* nothing needed for pipe */
|
||||
/* qse_ipap_t tcp;
|
||||
qse_ipap_t udp; */
|
||||
} u;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -101,7 +101,19 @@
|
||||
#endif
|
||||
|
||||
#define QSE_SIZEOF_WCHAR_T 4
|
||||
#define QSE_CHAR_IS_WCHAR
|
||||
|
||||
#if defined(vax) || defined(__vax)
|
||||
# define QSE_SIZEOF_OFF_T 4
|
||||
#elif defined(_LARGEFILE)
|
||||
# define QSE_SIZEOF_OFF_T 8
|
||||
#else
|
||||
# define QSE_SIZEOF_OFF_T 4
|
||||
#endif
|
||||
|
||||
#define QSE_SIZEOF_OFF64_T 0
|
||||
#define QSE_SIZEOF_MBSTATE_T 24
|
||||
#define QSE_MBLEN_MAX 8
|
||||
|
||||
/* make sure you change these when you change
|
||||
* the version in configure.ac */
|
||||
|
@ -55,6 +55,15 @@
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* epoll support */
|
||||
#undef HAVE_EPOLL
|
||||
|
||||
/* Define to 1 if you have the `epoll_create' function. */
|
||||
#undef HAVE_EPOLL_CREATE
|
||||
|
||||
/* Define to 1 if you have the `epoll_create1' function. */
|
||||
#undef HAVE_EPOLL_CREATE1
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#undef HAVE_ERRNO_H
|
||||
|
||||
@ -263,6 +272,9 @@
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
@ -135,6 +135,8 @@ static int find_rio_in (
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSE_MEMSET (p, 0, QSE_SIZEOF(*p));
|
||||
|
||||
p->name = QSE_AWK_STRDUP (run->awk, name);
|
||||
if (p->name == QSE_NULL)
|
||||
{
|
||||
@ -146,6 +148,7 @@ static int find_rio_in (
|
||||
p->type = (io_type | io_mask);
|
||||
p->mode = io_mode;
|
||||
p->rwcmode = QSE_AWK_RIO_CLOSE_FULL;
|
||||
/*
|
||||
p->handle = QSE_NULL;
|
||||
p->next = QSE_NULL;
|
||||
p->rwcstate = 0;
|
||||
@ -155,6 +158,7 @@ static int find_rio_in (
|
||||
p->in.len = 0;
|
||||
p->in.eof = 0;
|
||||
p->in.eos = 0;
|
||||
*/
|
||||
|
||||
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL);
|
||||
|
||||
@ -719,6 +723,8 @@ int qse_awk_rtx_writeio_str (
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSE_MEMSET (p, 0, QSE_SIZEOF(*p));
|
||||
|
||||
p->name = QSE_AWK_STRDUP (run->awk, name);
|
||||
if (p->name == QSE_NULL)
|
||||
{
|
||||
@ -730,12 +736,14 @@ int qse_awk_rtx_writeio_str (
|
||||
p->type = (io_type | io_mask);
|
||||
p->mode = io_mode;
|
||||
p->rwcmode = QSE_AWK_RIO_CLOSE_FULL;
|
||||
/*
|
||||
p->handle = QSE_NULL;
|
||||
p->next = QSE_NULL;
|
||||
p->rwcstate = 0;
|
||||
|
||||
p->out.eof = 0;
|
||||
p->out.eos = 0;
|
||||
*/
|
||||
|
||||
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL);
|
||||
n = handler (run, QSE_AWK_RIO_OPEN, p, QSE_NULL, 0);
|
||||
|
@ -765,6 +765,20 @@ qse_bool_t qse_awk_rtx_isstop (qse_awk_rtx_t* rtx)
|
||||
return (rtx->exit_level == EXIT_ABORT || rtx->awk->stopall);
|
||||
}
|
||||
|
||||
void qse_awk_rtx_getrio (qse_awk_rtx_t* rtx, qse_awk_rio_t* rio)
|
||||
{
|
||||
rio->pipe = rtx->rio.handler[QSE_AWK_RIO_PIPE];
|
||||
rio->file = rtx->rio.handler[QSE_AWK_RIO_FILE];
|
||||
rio->console = rtx->rio.handler[QSE_AWK_RIO_CONSOLE];
|
||||
}
|
||||
|
||||
void qse_awk_rtx_setrio (qse_awk_rtx_t* rtx, const qse_awk_rio_t* rio)
|
||||
{
|
||||
rtx->rio.handler[QSE_AWK_RIO_PIPE] = rio->pipe;
|
||||
rtx->rio.handler[QSE_AWK_RIO_FILE] = rio->file;
|
||||
rtx->rio.handler[QSE_AWK_RIO_CONSOLE] = rio->console;
|
||||
}
|
||||
|
||||
qse_awk_rcb_t* qse_awk_rtx_poprcb (qse_awk_rtx_t* rtx)
|
||||
{
|
||||
qse_awk_rcb_t* top = rtx->rcb;
|
||||
@ -917,7 +931,7 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio)
|
||||
}
|
||||
else rtx->pattern_range_state = QSE_NULL;
|
||||
|
||||
if (rio != QSE_NULL)
|
||||
if (rio)
|
||||
{
|
||||
rtx->rio.handler[QSE_AWK_RIO_PIPE] = rio->pipe;
|
||||
rtx->rio.handler[QSE_AWK_RIO_FILE] = rio->file;
|
||||
|
@ -91,11 +91,10 @@ typedef struct xtn_t
|
||||
} str;
|
||||
} u;
|
||||
} out;
|
||||
} s; /* script/source handling */
|
||||
|
||||
} s;
|
||||
} xtn_t;
|
||||
|
||||
|
||||
typedef struct rxtn_t
|
||||
{
|
||||
unsigned int seed;
|
||||
@ -124,11 +123,6 @@ typedef struct rxtn_t
|
||||
#endif
|
||||
} rxtn_t;
|
||||
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
static qse_cmgr_t* getcmgr_from_cmgrtab (
|
||||
qse_awk_rtx_t* rtx, const qse_char_t* ioname);
|
||||
#endif
|
||||
|
||||
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)
|
||||
@ -798,6 +792,7 @@ int qse_awk_parsestd (
|
||||
}
|
||||
|
||||
/*** RTX_OPENSTD ***/
|
||||
|
||||
static qse_ssize_t awk_rio_pipe (
|
||||
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
|
||||
qse_char_t* data, qse_size_t size)
|
||||
@ -811,7 +806,7 @@ static qse_ssize_t awk_rio_pipe (
|
||||
|
||||
if (riod->mode == QSE_AWK_RIO_PIPE_READ)
|
||||
{
|
||||
/* TODO: should we specify ERRTOOUT? */
|
||||
/* TODO: should ERRTOOUT be unset? */
|
||||
flags = QSE_PIO_READOUT |
|
||||
QSE_PIO_ERRTOOUT;
|
||||
}
|
||||
@ -825,7 +820,12 @@ static qse_ssize_t awk_rio_pipe (
|
||||
QSE_PIO_ERRTOOUT |
|
||||
QSE_PIO_WRITEIN;
|
||||
}
|
||||
else return -1; /* TODO: any way to set the error number? */
|
||||
else
|
||||
{
|
||||
/* this must not happen */
|
||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle = qse_pio_open (
|
||||
rtx->awk->mmgr,
|
||||
@ -838,7 +838,7 @@ static qse_ssize_t awk_rio_pipe (
|
||||
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
{
|
||||
qse_cmgr_t* cmgr = getcmgr_from_cmgrtab (rtx, riod->name);
|
||||
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
|
||||
if (cmgr)
|
||||
{
|
||||
qse_pio_setcmgr (handle, QSE_PIO_IN, cmgr);
|
||||
@ -951,7 +951,7 @@ static qse_ssize_t awk_rio_file (
|
||||
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
{
|
||||
qse_cmgr_t* cmgr = getcmgr_from_cmgrtab (rtx, riod->name);
|
||||
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
|
||||
if (cmgr) qse_sio_setcmgr (handle, cmgr);
|
||||
}
|
||||
#endif
|
||||
@ -1587,7 +1587,7 @@ static int fnc_time (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
}
|
||||
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
static qse_cmgr_t* getcmgr_from_cmgrtab (
|
||||
qse_cmgr_t* qse_awk_rtx_getcmgrstd (
|
||||
qse_awk_rtx_t* rtx, const qse_char_t* ioname)
|
||||
{
|
||||
rxtn_t* rxtn;
|
||||
|
@ -47,6 +47,7 @@ libqsecmn_la_SOURCES = \
|
||||
mbwc-str.c \
|
||||
mem.c \
|
||||
nwad.c \
|
||||
nwio.c \
|
||||
oht.c \
|
||||
opt.c \
|
||||
path-basename.c \
|
||||
|
@ -82,17 +82,18 @@ libqsecmn_la_LIBADD =
|
||||
am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \
|
||||
assert.lo chr.lo cp949.lo cp950.lo dll.lo env.lo gdl.lo htb.lo \
|
||||
lda.lo fio.lo fma.lo fmt.lo fs.lo fs-err.lo fs-move.lo hton.lo \
|
||||
ipad.lo main.lo mbwc.lo mbwc-str.lo mem.lo nwad.lo oht.lo \
|
||||
opt.lo path-basename.lo path-canon.lo pio.lo pma.lo rbt.lo \
|
||||
rex.lo sio.lo sll.lo slmb.lo stdio.lo str-beg.lo str-cat.lo \
|
||||
str-chr.lo str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo \
|
||||
str-dup.lo str-dynm.lo str-dynw.lo str-end.lo str-excl.lo \
|
||||
str-fcpy.lo str-fnmat.lo str-incl.lo str-len.lo str-pac.lo \
|
||||
str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \
|
||||
str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \
|
||||
str-trm.lo str-word.lo time.lo tio.lo tio-get.lo tio-put.lo \
|
||||
tre.lo tre-ast.lo tre-compile.lo tre-match-backtrack.lo \
|
||||
tre-match-parallel.lo tre-parse.lo tre-stack.lo utf8.lo xma.lo
|
||||
ipad.lo main.lo mbwc.lo mbwc-str.lo mem.lo nwad.lo nwio.lo \
|
||||
oht.lo opt.lo path-basename.lo path-canon.lo pio.lo pma.lo \
|
||||
rbt.lo rex.lo sio.lo sll.lo slmb.lo stdio.lo str-beg.lo \
|
||||
str-cat.lo str-chr.lo str-cnv.lo str-cmp.lo str-cpy.lo \
|
||||
str-del.lo str-dup.lo str-dynm.lo str-dynw.lo str-end.lo \
|
||||
str-excl.lo str-fcpy.lo str-fnmat.lo str-incl.lo str-len.lo \
|
||||
str-pac.lo str-pbrk.lo str-put.lo str-rev.lo str-rot.lo \
|
||||
str-set.lo str-spl.lo str-spn.lo str-str.lo str-subst.lo \
|
||||
str-tok.lo str-trm.lo str-word.lo time.lo tio.lo tio-get.lo \
|
||||
tio-put.lo tre.lo tre-ast.lo tre-compile.lo \
|
||||
tre-match-backtrack.lo tre-match-parallel.lo tre-parse.lo \
|
||||
tre-stack.lo utf8.lo xma.lo
|
||||
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
||||
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
@ -326,6 +327,7 @@ libqsecmn_la_SOURCES = \
|
||||
mbwc-str.c \
|
||||
mem.c \
|
||||
nwad.c \
|
||||
nwio.c \
|
||||
oht.c \
|
||||
opt.c \
|
||||
path-basename.c \
|
||||
@ -489,6 +491,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbwc.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwad.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-basename.Plo@am__quote@
|
||||
|
@ -40,6 +40,9 @@
|
||||
#elif defined(__DOS__)
|
||||
# include <dos.h>
|
||||
# include <dosfunc.h>
|
||||
#elif defined(vms) || defined(__vms)
|
||||
# include <starlet.h> /* (SYS$...) */
|
||||
# include <ssdef.h> /* (SS$...) */
|
||||
#else
|
||||
# include "syscall.h"
|
||||
#endif
|
||||
@ -165,6 +168,9 @@ void qse_assert_failed (
|
||||
regs.h.al = 249;
|
||||
intdos (®s, ®s);
|
||||
}
|
||||
#elif defined(vms) || defined(__vms)
|
||||
sys$exit (SS$_ABORT); /* this condition code can be shown with
|
||||
* 'show symbol $status' from the command-line. */
|
||||
#else
|
||||
QSE_KILL (QSE_GETPID(), SIGABRT);
|
||||
QSE_EXIT (1);
|
||||
|
659
qse/lib/cmn/nwio.c
Normal file
659
qse/lib/cmn/nwio.c
Normal file
@ -0,0 +1,659 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
|
||||
QSE 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 vernwion 3 of
|
||||
the License, or (at your option) any later vernwion.
|
||||
|
||||
QSE 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <qse/cmn/nwio.h>
|
||||
#include "mem.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* TODO: */
|
||||
#elif defined(__OS2__)
|
||||
/* TODO: */
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
# include "syscall.h"
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
|
||||
static qse_ssize_t socket_input (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
|
||||
static qse_ssize_t socket_output (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
|
||||
|
||||
static int nwad_to_sockaddr (const qse_nwad_t* nwad, int* family, void* addr)
|
||||
{
|
||||
int addrsize = -1;
|
||||
|
||||
switch (nwad->type)
|
||||
{
|
||||
case QSE_NWAD_IN4:
|
||||
{
|
||||
struct sockaddr_in* in;
|
||||
|
||||
in = (struct sockaddr_in*)addr;
|
||||
addrsize = QSE_SIZEOF(*in);
|
||||
QSE_MEMSET (in, 0, addrsize);
|
||||
|
||||
*family = AF_INET;
|
||||
in->sin_family = AF_INET;
|
||||
in->sin_addr.s_addr = nwad->u.in4.addr.value;
|
||||
in->sin_port = nwad->u.in4.port;
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_NWAD_IN6:
|
||||
{
|
||||
#if defined(AF_INET6)
|
||||
struct sockaddr_in6* in;
|
||||
|
||||
in = (struct sockaddr_in6*)addr;
|
||||
addrsize = QSE_SIZEOF(*in);
|
||||
QSE_MEMSET (in, 0, addrsize);
|
||||
|
||||
*family = AF_INET6;
|
||||
in->sin6_family = AF_INET6;
|
||||
memcpy (&in->sin6_addr, &nwad->u.in6.addr, QSE_SIZEOF(nwad->u.in6.addr));
|
||||
in->sin6_scope_id = nwad->u.in6.scope;
|
||||
in->sin6_port = nwad->u.in6.port;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return addrsize;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
static qse_nwio_errnum_t syserr_to_errnum (DWORD e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
case ERROR_OUTOFMEMORY:
|
||||
return QSE_NWIO_ENOMEM;
|
||||
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
case ERROR_INVALID_HANDLE:
|
||||
case ERROR_INVALID_NAME:
|
||||
return QSE_NWIO_EINVAL;
|
||||
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return QSE_NWIO_EACCES;
|
||||
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
return QSE_NWIO_ENOENT;
|
||||
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
case ERROR_FILE_EXISTS:
|
||||
return QSE_NWIO_EEXIST;
|
||||
|
||||
case ERROR_BROKEN_PIPE:
|
||||
return QSE_NWIO_EPIPE;
|
||||
|
||||
default:
|
||||
return QSE_NWIO_ESYSERR;
|
||||
}
|
||||
}
|
||||
#elif defined(__OS2__)
|
||||
static qse_nwio_errnum_t syserr_to_errnum (APIRET e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
return QSE_NWIO_ENOMEM;
|
||||
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
case ERROR_INVALID_HANDLE:
|
||||
case ERROR_INVALID_NAME:
|
||||
return QSE_NWIO_EINVAL;
|
||||
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return QSE_NWIO_EACCES;
|
||||
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
return QSE_NWIO_ENOENT;
|
||||
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
return QSE_NWIO_EEXIST;
|
||||
|
||||
case ERROR_BROKEN_PIPE:
|
||||
return QSE_NWIO_EPIPE;
|
||||
|
||||
default:
|
||||
return QSE_NWIO_ESYSERR;
|
||||
}
|
||||
}
|
||||
#elif defined(__DOS__)
|
||||
static qse_nwio_errnum_t syserr_to_errnum (int e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case ENOMEM:
|
||||
return QSE_NWIO_ENOMEM;
|
||||
|
||||
case EINVAL:
|
||||
return QSE_NWIO_EINVAL;
|
||||
|
||||
case EACCES:
|
||||
return QSE_NWIO_EACCES;
|
||||
|
||||
case ENOENT:
|
||||
return QSE_NWIO_ENOENT;
|
||||
|
||||
case EEXIST:
|
||||
return QSE_NWIO_EEXIST;
|
||||
|
||||
|
||||
default:
|
||||
return QSE_NWIO_ESYSERR;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static qse_nwio_errnum_t syserr_to_errnum (int e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case ENOMEM:
|
||||
return QSE_NWIO_ENOMEM;
|
||||
|
||||
case EINVAL:
|
||||
return QSE_NWIO_EINVAL;
|
||||
|
||||
case EACCES:
|
||||
return QSE_NWIO_EACCES;
|
||||
|
||||
case ENOENT:
|
||||
return QSE_NWIO_ENOENT;
|
||||
|
||||
case EEXIST:
|
||||
return QSE_NWIO_EEXIST;
|
||||
|
||||
case EINTR:
|
||||
return QSE_NWIO_EINTR;
|
||||
|
||||
case EPIPE:
|
||||
return QSE_NWIO_EPIPE;
|
||||
|
||||
#if defined(ECONNREFUSED) || defined(ENETUNREACH)
|
||||
#if defined(ECONNREFUSED)
|
||||
case ECONNREFUSED:
|
||||
#endif
|
||||
#if defined(ENETUNREACH)
|
||||
case ENETUNREACH:
|
||||
#endif
|
||||
return QSE_NWIO_ECONN;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return QSE_NWIO_ESYSERR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static qse_nwio_errnum_t tio_errnum_to_nwio_errnum (qse_tio_t* tio)
|
||||
{
|
||||
switch (tio->errnum)
|
||||
{
|
||||
case QSE_TIO_ENOMEM:
|
||||
return QSE_NWIO_ENOMEM;
|
||||
case QSE_TIO_EINVAL:
|
||||
return QSE_NWIO_EINVAL;
|
||||
case QSE_TIO_EACCES:
|
||||
return QSE_NWIO_EACCES;
|
||||
case QSE_TIO_ENOENT:
|
||||
return QSE_NWIO_ENOENT;
|
||||
case QSE_TIO_EILSEQ:
|
||||
return QSE_NWIO_EILSEQ;
|
||||
case QSE_TIO_EICSEQ:
|
||||
return QSE_NWIO_EICSEQ;
|
||||
case QSE_TIO_EILCHR:
|
||||
return QSE_NWIO_EILCHR;
|
||||
default:
|
||||
return QSE_NWIO_EOTHER;
|
||||
}
|
||||
}
|
||||
|
||||
qse_nwio_t* qse_nwio_open (
|
||||
qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_nwad_t* nwad, int flags)
|
||||
{
|
||||
qse_nwio_t* nwio;
|
||||
|
||||
nwio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_nwio_t) + xtnsize);
|
||||
if (nwio == QSE_NULL) return QSE_NULL;
|
||||
|
||||
if (qse_nwio_init (nwio, mmgr, nwad, flags) <= -1)
|
||||
{
|
||||
QSE_MMGR_FREE (mmgr, nwio);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
return nwio;
|
||||
}
|
||||
|
||||
void qse_nwio_close (qse_nwio_t* nwio)
|
||||
{
|
||||
qse_nwio_fini (nwio);
|
||||
QSE_MMGR_FREE (nwio->mmgr, nwio);
|
||||
}
|
||||
|
||||
int qse_nwio_init (
|
||||
qse_nwio_t* nwio, qse_mmgr_t* mmgr, const qse_nwad_t* nwad, int flags)
|
||||
{
|
||||
union
|
||||
{
|
||||
struct sockaddr_in in4;
|
||||
struct sockaddr_in6 in6;
|
||||
} addr;
|
||||
int addrlen;
|
||||
int family;
|
||||
|
||||
QSE_MEMSET (nwio, 0, QSE_SIZEOF(*nwio));
|
||||
nwio->mmgr = mmgr;
|
||||
nwio->flags = flags;
|
||||
|
||||
addrlen = nwad_to_sockaddr (nwad, &family, &addr);
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* TODO: */
|
||||
#elif defined(__OS2__)
|
||||
/* TODO: */
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
nwio->handle = socket (family, SOCK_STREAM, 0);
|
||||
if (nwio->handle <= -1)
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
#if defined(FD_CLOEXEC)
|
||||
{
|
||||
int tmp = fcntl (nwio->handle, F_GETFD);
|
||||
if (tmp >= 0) fcntl (nwio->handle, F_SETFD, tmp | FD_CLOEXEC);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & QSE_NWIO_LISTEN)
|
||||
{
|
||||
qse_nwio_hnd_t handle;
|
||||
|
||||
if (bind (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1 ||
|
||||
listen (nwio->handle, 10) <= -1)
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* TODO: socklen_t */
|
||||
handle = accept (nwio->handle, &addr, &addrlen);
|
||||
if (handle <= -1)
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
close (nwio->handle);
|
||||
nwio->handle = handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (connect (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1)
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & QSE_NWIO_TEXT)
|
||||
{
|
||||
int topt = 0;
|
||||
|
||||
if (flags & QSE_NWIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR;
|
||||
if (flags & QSE_NWIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH;
|
||||
|
||||
nwio->tio = qse_tio_open (mmgr, QSE_SIZEOF(qse_nwio_t*), topt);
|
||||
if (nwio->tio == QSE_NULL)
|
||||
{
|
||||
nwio->errnum = QSE_NWIO_ENOMEM;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* store the back-reference to nwio in the extension area.*/
|
||||
*(qse_nwio_t**)QSE_XTN(nwio->tio) = nwio;
|
||||
|
||||
if (qse_tio_attachin (nwio->tio, socket_input, QSE_NULL, 4096) <= -1 ||
|
||||
qse_tio_attachout (nwio->tio, socket_output, QSE_NULL, 4096) <= -1)
|
||||
{
|
||||
if (nwio->errnum == QSE_NWIO_ENOERR)
|
||||
nwio->errnum = tio_errnum_to_nwio_errnum (nwio->tio);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (nwio->tio) qse_tio_close (nwio->tio);
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* TODO: */
|
||||
#elif defined(__OS2__)
|
||||
/* TODO: */
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
close (nwio->handle);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
void qse_nwio_fini (qse_nwio_t* nwio)
|
||||
{
|
||||
/*if (qse_nwio_flush (nwio) <= -1) return -1;*/
|
||||
qse_nwio_flush (nwio);
|
||||
if (nwio->tio)
|
||||
{
|
||||
qse_tio_close (nwio->tio);
|
||||
nwio->tio = QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
qse_nwio_errnum_t qse_nwio_geterrnum (const qse_nwio_t* nwio)
|
||||
{
|
||||
return nwio->errnum;
|
||||
}
|
||||
|
||||
qse_cmgr_t* qse_nwio_getcmgr (qse_nwio_t* nwio)
|
||||
{
|
||||
return nwio->tio? qse_tio_getcmgr (nwio->tio): QSE_NULL;
|
||||
}
|
||||
|
||||
void qse_nwio_setcmgr (qse_nwio_t* nwio, qse_cmgr_t* cmgr)
|
||||
{
|
||||
if (nwio->tio) qse_tio_setcmgr (nwio->tio, cmgr);
|
||||
}
|
||||
|
||||
qse_nwio_hnd_t qse_nwio_gethandle (const qse_nwio_t* nwio)
|
||||
{
|
||||
return QSE_NWIO_HANDLE(nwio);
|
||||
}
|
||||
|
||||
qse_ubi_t qse_nwio_gethandleasubi (const qse_nwio_t* nwio)
|
||||
{
|
||||
qse_ubi_t ubi;
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* TODO: */
|
||||
#elif defined(__OS2__)
|
||||
/* TODO: */
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
ubi.i = nwio->handle;
|
||||
#endif
|
||||
return ubi;
|
||||
}
|
||||
|
||||
qse_ssize_t qse_nwio_flush (qse_nwio_t* nwio)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
if (nwio->tio)
|
||||
{
|
||||
nwio->errnum = QSE_NWIO_ENOERR;
|
||||
n = qse_tio_flush (nwio->tio);
|
||||
if (n <= -1 && nwio->errnum == QSE_NWIO_ENOERR)
|
||||
nwio->errnum = tio_errnum_to_nwio_errnum (nwio->tio);
|
||||
}
|
||||
else n = 0;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void qse_nwio_purge (qse_nwio_t* nwio)
|
||||
{
|
||||
if (nwio->tio) qse_tio_purge (nwio->tio);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
DWORD count;
|
||||
#elif defined(__OS2__)
|
||||
ULONG count;
|
||||
APIRET rc;
|
||||
#elif defined(__DOS__)
|
||||
int n;
|
||||
#else
|
||||
qse_ssize_t n;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD)))
|
||||
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD);
|
||||
|
||||
if (ReadFile(nwio->handle, buf, (DWORD)size, &count, QSE_NULL) == FALSE)
|
||||
{
|
||||
/* ReadFile receives ERROR_BROKEN_PIPE when the write end
|
||||
* is closed in the child process */
|
||||
if (GetLastError() == ERROR_BROKEN_PIPE) return 0;
|
||||
nwio->errnum = syserr_to_errnum(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
return (qse_ssize_t)count;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG)))
|
||||
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG);
|
||||
|
||||
rc = DosRead (nwio->handle, buf, (ULONG)size, &count);
|
||||
if (rc != NO_ERROR)
|
||||
{
|
||||
if (rc == ERROR_BROKEN_PIPE) return 0; /* TODO: check this */
|
||||
nwio->errnum = syserr_to_errnum(rc);
|
||||
return -1;
|
||||
}
|
||||
return (qse_ssize_t)count;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: verify this */
|
||||
|
||||
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int)))
|
||||
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int);
|
||||
|
||||
n = read (nwio->handle, buf, size);
|
||||
if (n <= -1) nwio->errnum = syserr_to_errnum(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);
|
||||
|
||||
reread:
|
||||
n = recv (nwio->handle, buf, size, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
if (nwio->flags & QSE_NWIO_READNORETRY)
|
||||
nwio->errnum = QSE_NWIO_EINTR;
|
||||
else goto reread;
|
||||
}
|
||||
else
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum (errno);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
||||
qse_ssize_t qse_nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
|
||||
{
|
||||
if (nwio->tio == QSE_NULL)
|
||||
return nwio_read (nwio, buf, size);
|
||||
else
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
nwio->errnum = QSE_NWIO_ENOERR;
|
||||
n = qse_tio_read (nwio->tio, buf, size);
|
||||
if (n <= -1 && nwio->errnum == QSE_NWIO_ENOERR)
|
||||
nwio->errnum = tio_errnum_to_nwio_errnum (nwio->tio);
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
static qse_ssize_t nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t size)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
DWORD count;
|
||||
#elif defined(__OS2__)
|
||||
ULONG count;
|
||||
APIRET rc;
|
||||
#elif defined(__DOS__)
|
||||
int n;
|
||||
#else
|
||||
qse_ssize_t n;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD)))
|
||||
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD);
|
||||
|
||||
if (WriteFile (nwio->handle, data, (DWORD)size, &count, QSE_NULL) == FALSE)
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
return (qse_ssize_t)count;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG)))
|
||||
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG);
|
||||
|
||||
rc = DosWrite (nwio->handle, (PVOID)data, (ULONG)size, &count);
|
||||
if (rc != NO_ERROR)
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum(rc);
|
||||
return -1;
|
||||
}
|
||||
return (qse_ssize_t)count;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
|
||||
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int)))
|
||||
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int);
|
||||
|
||||
n = write (nwio->handle, data, size);
|
||||
if (n <= -1) nwio->errnum = syserr_to_errnum (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);
|
||||
|
||||
rewrite:
|
||||
n = send (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 = syserr_to_errnum (errno);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
qse_ssize_t qse_nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t size)
|
||||
{
|
||||
if (nwio->tio == QSE_NULL)
|
||||
return nwio_write (nwio, data, size);
|
||||
else
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
nwio->errnum = QSE_NWIO_ENOERR;
|
||||
n = qse_tio_write (nwio->tio, data, size);
|
||||
if (n <= -1 && nwio->errnum == QSE_NWIO_ENOERR)
|
||||
nwio->errnum = tio_errnum_to_nwio_errnum (nwio->tio);
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
static qse_ssize_t socket_input (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size)
|
||||
{
|
||||
if (cmd == QSE_TIO_DATA)
|
||||
{
|
||||
qse_nwio_t* nwio;
|
||||
|
||||
nwio = *(qse_nwio_t**)QSE_XTN(tio);
|
||||
QSE_ASSERT (nwio != QSE_NULL);
|
||||
|
||||
return nwio_read (nwio, buf, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qse_ssize_t socket_output (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size)
|
||||
{
|
||||
if (cmd == QSE_TIO_DATA)
|
||||
{
|
||||
qse_nwio_t* nwio;
|
||||
|
||||
nwio = *(qse_nwio_t**)QSE_XTN(tio);
|
||||
QSE_ASSERT (nwio != QSE_NULL);
|
||||
|
||||
return nwio_write (nwio, buf, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -575,6 +575,7 @@ int qse_pio_init (
|
||||
|
||||
QSE_MEMSET (pio, 0, QSE_SIZEOF(*pio));
|
||||
pio->mmgr = mmgr;
|
||||
pio->flags = flags;
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx */
|
||||
@ -1886,7 +1887,6 @@ create_process:
|
||||
}
|
||||
}
|
||||
|
||||
pio->option = 0;
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
@ -1961,8 +1961,9 @@ void qse_pio_fini (qse_pio_t* pio)
|
||||
qse_pio_end (pio, QSE_PIO_OUT);
|
||||
qse_pio_end (pio, QSE_PIO_IN);
|
||||
|
||||
pio->option &= ~QSE_PIO_WAIT_NOBLOCK;
|
||||
pio->option &= ~QSE_PIO_WAIT_NORETRY;
|
||||
/* when closing, enable blocking and retrying */
|
||||
pio->flags &= ~QSE_PIO_WAITNOBLOCK;
|
||||
pio->flags &= ~QSE_PIO_WAITNORETRY;
|
||||
qse_pio_wait (pio);
|
||||
}
|
||||
|
||||
@ -1971,16 +1972,6 @@ qse_pio_errnum_t qse_pio_geterrnum (const qse_pio_t* pio)
|
||||
return pio->errnum;
|
||||
}
|
||||
|
||||
int qse_pio_getoption (const qse_pio_t* pio)
|
||||
{
|
||||
return pio->option;
|
||||
}
|
||||
|
||||
void qse_pio_setoption (qse_pio_t* pio, int opt)
|
||||
{
|
||||
pio->option = opt;
|
||||
}
|
||||
|
||||
qse_cmgr_t* qse_pio_getcmgr (qse_pio_t* pio, qse_pio_hid_t hid)
|
||||
{
|
||||
return pio->pin[hid].tio?
|
||||
@ -2090,7 +2081,7 @@ reread:
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
if (pio->option & QSE_PIO_READ_NORETRY)
|
||||
if (pio->flags & QSE_PIO_READNORETRY)
|
||||
pio->errnum = QSE_PIO_EINTR;
|
||||
else goto reread;
|
||||
}
|
||||
@ -2188,7 +2179,7 @@ rewrite:
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
if (pio->option & QSE_PIO_WRITE_NORETRY)
|
||||
if (pio->flags & QSE_PIO_WRITENORETRY)
|
||||
pio->errnum = QSE_PIO_EINTR;
|
||||
else goto rewrite;
|
||||
}
|
||||
@ -2235,9 +2226,14 @@ qse_ssize_t qse_pio_flush (qse_pio_t* pio, qse_pio_hid_t hid)
|
||||
return n;
|
||||
}
|
||||
|
||||
void qse_pio_purge (qse_pio_t* pio, qse_pio_hid_t hid)
|
||||
{
|
||||
if (pio->pin[hid].tio) qse_tio_purge (pio->pin[hid].tio);
|
||||
}
|
||||
|
||||
void qse_pio_end (qse_pio_t* pio, qse_pio_hid_t hid)
|
||||
{
|
||||
if (pio->pin[hid].tio != QSE_NULL)
|
||||
if (pio->pin[hid].tio)
|
||||
{
|
||||
qse_tio_close (pio->pin[hid].tio);
|
||||
pio->pin[hid].tio = QSE_NULL;
|
||||
@ -2271,7 +2267,7 @@ int qse_pio_wait (qse_pio_t* pio)
|
||||
}
|
||||
|
||||
w = WaitForSingleObject (pio->child,
|
||||
((pio->option & QSE_PIO_WAIT_NOBLOCK)? 0: INFINITE)
|
||||
((pio->flags & QSE_PIO_WAITNOBLOCK)? 0: INFINITE)
|
||||
);
|
||||
if (w == WAIT_TIMEOUT)
|
||||
{
|
||||
@ -2327,7 +2323,7 @@ int qse_pio_wait (qse_pio_t* pio)
|
||||
|
||||
rc = DosWaitChild (
|
||||
DCWA_PROCESSTREE,
|
||||
((pio->option & QSE_PIO_WAIT_NOBLOCK)? DCWW_NOWAIT: DCWW_WAIT),
|
||||
((pio->flags & QSE_PIO_WAITNOBLOCK)? DCWW_NOWAIT: DCWW_WAIT),
|
||||
&child_rc,
|
||||
&ppid,
|
||||
pio->child
|
||||
@ -2367,7 +2363,7 @@ int qse_pio_wait (qse_pio_t* pio)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pio->option & QSE_PIO_WAIT_NOBLOCK) opt |= WNOHANG;
|
||||
if (pio->flags & QSE_PIO_WAITNOBLOCK) opt |= WNOHANG;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -2385,7 +2381,7 @@ int qse_pio_wait (qse_pio_t* pio)
|
||||
}
|
||||
else if (errno == EINTR)
|
||||
{
|
||||
if (pio->option & QSE_PIO_WAIT_NORETRY)
|
||||
if (pio->flags & QSE_PIO_WAITNORETRY)
|
||||
pio->errnum = QSE_PIO_EINTR;
|
||||
else continue;
|
||||
}
|
||||
@ -2397,7 +2393,7 @@ int qse_pio_wait (qse_pio_t* pio)
|
||||
if (n == 0)
|
||||
{
|
||||
/* when WNOHANG is not specified, 0 can't be returned */
|
||||
QSE_ASSERT (pio->option & QSE_PIO_WAIT_NOBLOCK);
|
||||
QSE_ASSERT (pio->flags & QSE_PIO_WAITNOBLOCK);
|
||||
|
||||
ret = 255 + 1;
|
||||
/* the child process is still alive */
|
||||
|
@ -44,11 +44,6 @@ static qse_ssize_t file_input (
|
||||
static qse_ssize_t file_output (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
|
||||
|
||||
static qse_ssize_t socket_input (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
|
||||
static qse_ssize_t socket_output (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
|
||||
|
||||
static qse_sio_errnum_t fio_errnum_to_sio_errnum (qse_fio_t* fio)
|
||||
{
|
||||
switch (fio->errnum)
|
||||
@ -129,7 +124,7 @@ qse_sio_t* qse_sio_openstd (
|
||||
if (sio)
|
||||
{
|
||||
DWORD mode;
|
||||
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE &&
|
||||
if (GetConsoleMode (sio->file.handle, &mode) == TRUE &&
|
||||
GetConsoleOutputCP() == CP_UTF8)
|
||||
{
|
||||
sio->status |= STATUS_UTF8_CONSOLE;
|
||||
@ -163,10 +158,10 @@ int qse_sio_init (
|
||||
* this function, a user can specify a sio flag enumerator not
|
||||
* present in the fio flag enumerator. mask off such an enumerator. */
|
||||
if (qse_fio_init (
|
||||
&sio->u.file, mmgr, file,
|
||||
&sio->file, mmgr, file,
|
||||
(flags & ~QSE_FIO_RESERVED), mode) <= -1)
|
||||
{
|
||||
sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
|
||||
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -176,7 +171,7 @@ int qse_sio_init (
|
||||
if (qse_tio_init(&sio->tio.io, mmgr, topt) <= -1)
|
||||
{
|
||||
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
|
||||
qse_fio_fini (&sio->u.file);
|
||||
qse_fio_fini (&sio->file);
|
||||
return -1;
|
||||
}
|
||||
/* store the back-reference to sio in the extension area.*/
|
||||
@ -189,7 +184,7 @@ int qse_sio_init (
|
||||
if (sio->errnum == QSE_SIO_ENOERR)
|
||||
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
|
||||
qse_tio_fini (&sio->tio.io);
|
||||
qse_fio_fini (&sio->u.file);
|
||||
qse_fio_fini (&sio->file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -211,7 +206,7 @@ int qse_sio_initstd (
|
||||
if (n >= 0)
|
||||
{
|
||||
DWORD mode;
|
||||
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE &&
|
||||
if (GetConsoleMode (sio->file.handle, &mode) == TRUE &&
|
||||
GetConsoleOutputCP() == CP_UTF8)
|
||||
{
|
||||
sio->status |= STATUS_UTF8_CONSOLE;
|
||||
@ -227,7 +222,7 @@ void qse_sio_fini (qse_sio_t* sio)
|
||||
/*if (qse_sio_flush (sio) <= -1) return -1;*/
|
||||
qse_sio_flush (sio);
|
||||
qse_tio_fini (&sio->tio.io);
|
||||
qse_fio_fini (&sio->u.file);
|
||||
qse_fio_fini (&sio->file);
|
||||
}
|
||||
|
||||
qse_sio_errnum_t qse_sio_geterrnum (const qse_sio_t* sio)
|
||||
@ -247,13 +242,13 @@ void qse_sio_setcmgr (qse_sio_t* sio, qse_cmgr_t* cmgr)
|
||||
|
||||
qse_sio_hnd_t qse_sio_gethandle (const qse_sio_t* sio)
|
||||
{
|
||||
/*return qse_fio_gethandle (&sio->u.file);*/
|
||||
return QSE_FIO_HANDLE(&sio->u.file);
|
||||
/*return qse_fio_gethandle (&sio->file);*/
|
||||
return QSE_FIO_HANDLE(&sio->file);
|
||||
}
|
||||
|
||||
qse_ubi_t qse_sio_gethandleasubi (const qse_sio_t* sio)
|
||||
{
|
||||
return qse_fio_gethandleasubi (&sio->u.file);
|
||||
return qse_fio_gethandleasubi (&sio->file);
|
||||
}
|
||||
|
||||
qse_ssize_t qse_sio_flush (qse_sio_t* sio)
|
||||
@ -453,7 +448,7 @@ qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str)
|
||||
for (cur = str, left = qse_wcslen(str); left > 0; cur += count, left -= count)
|
||||
{
|
||||
if (WriteConsoleW (
|
||||
sio->u.file.handle, cur, left,
|
||||
sio->file.handle, cur, left,
|
||||
&count, QSE_NULL) == FALSE)
|
||||
{
|
||||
sio->errnum = QSE_SIO_ESYSERR;
|
||||
@ -506,7 +501,7 @@ qse_ssize_t qse_sio_putwcsn (
|
||||
for (cur = str, left = size; left > 0; cur += count, left -= count)
|
||||
{
|
||||
if (WriteConsoleW (
|
||||
sio->u.file.handle, cur, left,
|
||||
sio->file.handle, cur, left,
|
||||
&count, QSE_NULL) == FALSE)
|
||||
{
|
||||
sio->errnum = QSE_SIO_ESYSERR;
|
||||
@ -544,10 +539,10 @@ int qse_sio_getpos (qse_sio_t* sio, qse_sio_pos_t* pos)
|
||||
{
|
||||
qse_fio_off_t off;
|
||||
|
||||
off = qse_fio_seek (&sio->u.file, 0, QSE_FIO_CURRENT);
|
||||
off = qse_fio_seek (&sio->file, 0, QSE_FIO_CURRENT);
|
||||
if (off == (qse_fio_off_t)-1)
|
||||
{
|
||||
sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
|
||||
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -560,10 +555,10 @@ int qse_sio_setpos (qse_sio_t* sio, qse_sio_pos_t pos)
|
||||
qse_fio_off_t off;
|
||||
|
||||
if (qse_sio_flush(sio) <= -1) return -1;
|
||||
off = qse_fio_seek (&sio->u.file, pos, QSE_FIO_BEGIN);
|
||||
off = qse_fio_seek (&sio->file, pos, QSE_FIO_BEGIN);
|
||||
if (off == (qse_fio_off_t)-1)
|
||||
{
|
||||
sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
|
||||
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -577,12 +572,12 @@ int qse_sio_seek (qse_sio_t* sio, qse_sio_seek_t pos)
|
||||
* can move to the end of the stream also.... */
|
||||
|
||||
if (qse_sio_flush(sio) <= -1) return -1;
|
||||
return (qse_fio_seek (&sio->u.file,
|
||||
return (qse_fio_seek (&sio->file,
|
||||
0, QSE_FIO_END) == (qse_fio_off_t)-1)? -1: 0;
|
||||
|
||||
/* TODO: write this function */
|
||||
if (qse_sio_flush(sio) <= -1) return -1;
|
||||
return (qse_fio_seek (&sio->u.file,
|
||||
return (qse_fio_seek (&sio->file,
|
||||
0, QSE_FIO_BEGIN) == (qse_fio_off_t)-1)? -1: 0;
|
||||
|
||||
}
|
||||
@ -600,8 +595,8 @@ static qse_ssize_t file_input (
|
||||
sio = *(qse_sio_t**)QSE_XTN(tio);
|
||||
QSE_ASSERT (sio != QSE_NULL);
|
||||
|
||||
n = qse_fio_read (&sio->u.file, buf, size);
|
||||
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
|
||||
n = qse_fio_read (&sio->file, buf, size);
|
||||
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -619,61 +614,11 @@ static qse_ssize_t file_output (
|
||||
sio = *(qse_sio_t**)QSE_XTN(tio);
|
||||
QSE_ASSERT (sio != QSE_NULL);
|
||||
|
||||
n = qse_fio_write (&sio->u.file, buf, size);
|
||||
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
|
||||
n = qse_fio_write (&sio->file, buf, size);
|
||||
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
|
||||
return n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
#if 0
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <winsock2.h>
|
||||
#else
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
static qse_ssize_t socket_input (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size)
|
||||
{
|
||||
|
||||
if (cmd == QSE_TIO_DATA)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
qse_sio_t* sio;
|
||||
|
||||
sio = *(qse_sio_t**)QSE_XTN(tio);
|
||||
QSE_ASSERT (sio != QSE_NULL);
|
||||
|
||||
n = recv (sio->u.sck, buf, size, 0);
|
||||
if (n <= -1) sio->errnum = syserr_to_errnum (errno);
|
||||
return n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qse_ssize_t socket_output (
|
||||
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size)
|
||||
{
|
||||
if (cmd == QSE_TIO_DATA)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
qse_sio_t* sio;
|
||||
|
||||
sio = *(qse_sio_t**)QSE_XTN(tio);
|
||||
QSE_ASSERT (sio != QSE_NULL);
|
||||
|
||||
n = send (sio->u.sck, buf, size, 0);
|
||||
if (n <= -1) sio->errnum = syserr_to_errnum (errno);
|
||||
return n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -21,7 +21,8 @@
|
||||
#include "sed.h"
|
||||
#include "../cmn/mem.h"
|
||||
|
||||
const qse_char_t* qse_sed_dflerrstr (qse_sed_t* sed, qse_sed_errnum_t errnum)
|
||||
const qse_char_t* qse_sed_dflerrstr (
|
||||
const qse_sed_t* sed, qse_sed_errnum_t errnum)
|
||||
{
|
||||
static const qse_char_t* errstr[] =
|
||||
{
|
||||
|
@ -233,11 +233,10 @@ void qse_sed_fini (
|
||||
);
|
||||
|
||||
const qse_char_t* qse_sed_dflerrstr (
|
||||
qse_sed_t* sed,
|
||||
const qse_sed_t* sed,
|
||||
qse_sed_errnum_t errnum
|
||||
);
|
||||
|
||||
|
||||
#ifdef USE_REX
|
||||
/**
|
||||
* The qse_sed_getmaxdepth() gets the maximum processing depth.
|
||||
|
@ -19,8 +19,13 @@
|
||||
# include <sys/stat.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EPOLL)
|
||||
# if defined(HAVE_SYS_EPOLL_H)
|
||||
# include <sys/epoll.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <limits.h>
|
||||
@ -332,12 +337,20 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||
flag = 1;
|
||||
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &flag, QSE_SIZEOF(flag));
|
||||
|
||||
#if defined(IP_TRANSPARENT)
|
||||
/* remove the ip routing restriction that a packet can only
|
||||
* be sent using a local ip address. this option is useful
|
||||
* if transparency is achieved with TPROXY */
|
||||
flag = 1;
|
||||
setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag));
|
||||
#endif
|
||||
|
||||
/* Solaris 8 returns EINVAL if QSE_SIZEOF(addr) is passed in as the
|
||||
* address size for AF_INET. */
|
||||
/*if (bind (s, (struct sockaddr*)&addr, QSE_SIZEOF(addr)) <= -1) goto oops_esocket;*/
|
||||
if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1)
|
||||
{
|
||||
#ifdef IPV6_V6ONLY
|
||||
#if defined(IPV6_V6ONLY)
|
||||
if (errno == EADDRINUSE && addr.ss_family == AF_INET6)
|
||||
{
|
||||
int on = 1;
|
||||
@ -561,7 +574,11 @@ static void* mux_open (qse_httpd_t* httpd)
|
||||
|
||||
memset (mux, 0, QSE_SIZEOF(*mux));
|
||||
|
||||
#if defined(HAVE_EPOLL_CREATE1)
|
||||
mux->fd = epoll_create1 (O_CLOEXEC);
|
||||
#else
|
||||
mux->fd = epoll_create (100);
|
||||
#endif
|
||||
if (mux->fd <= -1)
|
||||
{
|
||||
qse_httpd_freemem (httpd, mux);
|
||||
@ -569,6 +586,13 @@ static void* mux_open (qse_httpd_t* httpd)
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
#if defined(HAVE_EPOLL_CREATE1)
|
||||
/* nothing else to do */
|
||||
#else
|
||||
flag = fcntl (mux->fd, F_GETFD);
|
||||
if (flag >= 0) fcntl (mux->fd, F_SETFD, flag | FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
return mux;
|
||||
}
|
||||
|
||||
@ -1188,6 +1212,7 @@ qse_printf (QSE_T("Entasking chunked CGI...\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (!peek)
|
||||
{
|
||||
/* file or directory */
|
||||
@ -1195,6 +1220,15 @@ qse_printf (QSE_T("Entasking chunked CGI...\n"));
|
||||
httpd, client, QSE_NULL, qpath, req);
|
||||
if (task == QSE_NULL) goto oops;
|
||||
}
|
||||
#else
|
||||
if (peek)
|
||||
{
|
||||
qse_httpd_discardcontent (httpd, req);
|
||||
task = qse_httpd_entaskfile (
|
||||
httpd, client, QSE_NULL, qpath, req);
|
||||
if (task == QSE_NULL) goto oops;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user