diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 1c21c095..80d941c0 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -55,6 +56,10 @@ # include #endif + + +#include + 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) { @@ -1012,6 +1117,8 @@ static int awk_main (int argc, qse_char_t* argv[]) print_awkerr (awk); goto oops; } + + extend_pipe_handler (rtx); app_rtx = rtx; #ifdef ENABLE_CALLBACK diff --git a/qse/configure b/qse/configure index 3ebfb13b..b91098fb 100755 --- a/qse/configure +++ b/qse/configure @@ -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 " @@ -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 : diff --git a/qse/configure.ac b/qse/configure.ac index 2286d723..c0679957 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -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 diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 9a9fc6e8..14f834e0 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -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, diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index ab10d2c1..dbbb5ea6 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -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 diff --git a/qse/include/qse/cmn/Makefile.am b/qse/include/qse/cmn/Makefile.am index 00881183..a78916ec 100644 --- a/qse/include/qse/cmn/Makefile.am +++ b/qse/include/qse/cmn/Makefile.am @@ -21,6 +21,7 @@ pkginclude_HEADERS = \ mbwc.h \ mem.h \ nwad.h \ + nwio.h \ oht.h \ opt.h \ path.h \ diff --git a/qse/include/qse/cmn/Makefile.in b/qse/include/qse/cmn/Makefile.in index de6dc6f8..ce829a7d 100644 --- a/qse/include/qse/cmn/Makefile.in +++ b/qse/include/qse/cmn/Makefile.in @@ -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: diff --git a/qse/include/qse/cmn/nwio.h b/qse/include/qse/cmn/nwio.h new file mode 100644 index 00000000..ecb50860 --- /dev/null +++ b/qse/include/qse/cmn/nwio.h @@ -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 . + */ + +#ifndef _QSE_CMN_NWIO_H_ +#define _QSE_CMN_NWIO_H_ + +/** @file + * This file defines a generic text I/O interface. + */ + +#include +#include +#include +#include + +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 diff --git a/qse/include/qse/cmn/pio.h b/qse/include/qse/cmn/pio.h index 3155f2f9..bee3ee1c 100644 --- a/qse/include/qse/cmn/pio.h +++ b/qse/include/qse/cmn/pio.h @@ -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 */ diff --git a/qse/include/qse/cmn/sio.h b/qse/include/qse/cmn/sio.h index 1593cb69..3e527436 100644 --- a/qse/include/qse/cmn/sio.h +++ b/qse/include/qse/cmn/sio.h @@ -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; + qse_fio_t file; 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 diff --git a/qse/include/qse/conf_vms.h b/qse/include/qse/conf_vms.h index 5617baf2..a8c4d73e 100644 --- a/qse/include/qse/conf_vms.h +++ b/qse/include/qse/conf_vms.h @@ -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 */ diff --git a/qse/include/qse/config.h.in b/qse/include/qse/config.h.in index 5d1c67da..6deddba9 100644 --- a/qse/include/qse/config.h.in +++ b/qse/include/qse/config.h.in @@ -55,6 +55,15 @@ /* Define to 1 if you have the 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 header file. */ #undef HAVE_ERRNO_H @@ -263,6 +272,9 @@ */ #undef HAVE_SYS_DIR_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_EPOLL_H + /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H diff --git a/qse/lib/awk/rio.c b/qse/lib/awk/rio.c index 739d80db..a4bffda7 100644 --- a/qse/lib/awk/rio.c +++ b/qse/lib/awk/rio.c @@ -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); @@ -718,6 +722,8 @@ int qse_awk_rtx_writeio_str ( qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL); 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); diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 65464c90..76dc9a4b 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -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; diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 4a5b789e..45e16e1d 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -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; diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index aa4c909a..d0c80524 100644 --- a/qse/lib/cmn/Makefile.am +++ b/qse/lib/cmn/Makefile.am @@ -47,6 +47,7 @@ libqsecmn_la_SOURCES = \ mbwc-str.c \ mem.c \ nwad.c \ + nwio.c \ oht.c \ opt.c \ path-basename.c \ diff --git a/qse/lib/cmn/Makefile.in b/qse/lib/cmn/Makefile.in index fd2a96f8..fce9e5db 100644 --- a/qse/lib/cmn/Makefile.in +++ b/qse/lib/cmn/Makefile.in @@ -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@ diff --git a/qse/lib/cmn/assert.c b/qse/lib/cmn/assert.c index cc564d9b..4f0d9bec 100644 --- a/qse/lib/cmn/assert.c +++ b/qse/lib/cmn/assert.c @@ -40,6 +40,9 @@ #elif defined(__DOS__) # include # include +#elif defined(vms) || defined(__vms) +# include /* (SYS$...) */ +# include /* (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); diff --git a/qse/lib/cmn/nwio.c b/qse/lib/cmn/nwio.c new file mode 100644 index 00000000..e2e179c6 --- /dev/null +++ b/qse/lib/cmn/nwio.c @@ -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 . + */ + +#include +#include "mem.h" + +#if defined(_WIN32) +/* TODO: */ +#elif defined(__OS2__) +/* TODO: */ +#elif defined(__DOS__) +/* TODO: */ +#else +# include "syscall.h" +# include +# include +#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; +} + diff --git a/qse/lib/cmn/pio.c b/qse/lib/cmn/pio.c index 6ba91fab..02563559 100644 --- a/qse/lib/cmn/pio.c +++ b/qse/lib/cmn/pio.c @@ -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 */ diff --git a/qse/lib/cmn/sio.c b/qse/lib/cmn/sio.c index cbd250fc..6bf2565c 100644 --- a/qse/lib/cmn/sio.c +++ b/qse/lib/cmn/sio.c @@ -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 -#else -# include -#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 diff --git a/qse/lib/sed/err.c b/qse/lib/sed/err.c index a2278263..79e8015b 100644 --- a/qse/lib/sed/err.c +++ b/qse/lib/sed/err.c @@ -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[] = { diff --git a/qse/lib/sed/sed.h b/qse/lib/sed/sed.h index 0e74d5f5..4d116278 100644 --- a/qse/lib/sed/sed.h +++ b/qse/lib/sed/sed.h @@ -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. diff --git a/qse/samples/net/http01.c b/qse/samples/net/http01.c index ec81b61e..b4e67069 100644 --- a/qse/samples/net/http01.c +++ b/qse/samples/net/http01.c @@ -19,7 +19,12 @@ # include # include # include -# include +#endif + +#if defined(HAVE_EPOLL) +# if defined(HAVE_SYS_EPOLL_H) +# include +# endif #endif #if defined(__linux__) @@ -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