started adding nwio

This commit is contained in:
hyung-hwan 2012-04-27 14:33:14 +00:00
parent 4488041fd3
commit 005471b505
24 changed files with 1216 additions and 229 deletions

View File

@ -29,6 +29,7 @@
#include <qse/cmn/main.h> #include <qse/cmn/main.h>
#include <qse/cmn/mbwc.h> #include <qse/cmn/mbwc.h>
#include <qse/cmn/xma.h> #include <qse/cmn/xma.h>
#include <qse/cmn/nwio.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
@ -55,6 +56,10 @@
# include <errno.h> # include <errno.h>
#endif #endif
#include <sys/socket.h>
static qse_awk_rtx_t* app_rtx = QSE_NULL; static qse_awk_rtx_t* app_rtx = QSE_NULL;
static int app_debug = 0; static int app_debug = 0;
@ -93,6 +98,11 @@ struct gvmv_t
qse_size_t len; qse_size_t len;
}; };
struct rtx_xtn_t
{
qse_awk_rio_fun_t old_pipe_handler;
};
static void dprint (const qse_char_t* fmt, ...) static void dprint (const qse_char_t* fmt, ...)
{ {
if (app_debug) if (app_debug)
@ -884,6 +894,101 @@ static qse_mmgr_t debug_mmgr =
}; };
#endif #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[]) static int awk_main (int argc, qse_char_t* argv[])
{ {
qse_awk_t* awk = QSE_NULL; qse_awk_t* awk = QSE_NULL;
@ -999,7 +1104,7 @@ static int awk_main (int argc, qse_char_t* argv[])
#endif #endif
rtx = qse_awk_rtx_openstd ( 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); (const qse_char_t*const*)arg.icf, QSE_NULL, arg.console_cmgr);
if (rtx == QSE_NULL) if (rtx == QSE_NULL)
{ {
@ -1012,6 +1117,8 @@ static int awk_main (int argc, qse_char_t* argv[])
print_awkerr (awk); print_awkerr (awk);
goto oops; goto oops;
} }
extend_pipe_handler (rtx);
app_rtx = rtx; app_rtx = rtx;
#ifdef ENABLE_CALLBACK #ifdef ENABLE_CALLBACK

37
qse/configure vendored
View File

@ -16002,7 +16002,7 @@ fi
done 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 : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` 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" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -16015,7 +16015,7 @@ fi
done 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 : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` 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" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -16028,18 +16028,6 @@ fi
done 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> ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "#include <stddef.h>
" "
@ -16542,6 +16530,27 @@ fi
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 "$as_me:${as_lineno-$LINENO}: checking for main in -lunicows" >&5
$as_echo_n "checking for main in -lunicows... " >&6; } $as_echo_n "checking for main in -lunicows... " >&6; }
if ${ac_cv_lib_unicows_main+:} false; then : if ${ac_cv_lib_unicows_main+:} false; then :

View File

@ -83,9 +83,8 @@ AC_SUBST(LIBM, $LIBM)
dnl check header files. dnl check header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h]) 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([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]) AC_CHECK_HEADERS([sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h sys/epoll.h])
AC_CHECK_HEADERS([execinfo.h])
dnl check data types dnl check data types
AC_CHECK_TYPE([wchar_t], AC_CHECK_TYPE([wchar_t],
@ -173,6 +172,13 @@ then
fi fi
AC_SUBST(SENDFILE_LIBS) 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 check is the import library for unicows.dll exists
dnl this check doesn't look for a particular symbol dnl this check doesn't look for a particular symbol
dnl but for the symbol 'main' since i want to check dnl but for the symbol 'main' since i want to check

View File

@ -1674,6 +1674,24 @@ void qse_awk_rtx_stop (
qse_awk_rtx_t* rtx /**< runtime context */ 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 * The qse_awk_rtx_poprcb() function pops a runtime callback set
* and returns the pointer to it. If no callback set can be popped, * and returns the pointer to it. If no callback set can be popped,

View File

@ -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 ( void* qse_awk_rtx_getxtnstd (
qse_awk_rtx_t* rtx 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -21,6 +21,7 @@ pkginclude_HEADERS = \
mbwc.h \ mbwc.h \
mem.h \ mem.h \
nwad.h \ nwad.h \
nwio.h \
oht.h \ oht.h \
opt.h \ opt.h \
path.h \ path.h \

View File

@ -53,9 +53,9 @@ SOURCES =
DIST_SOURCES = DIST_SOURCES =
am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dll.h env.h \ 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 \ 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 \ map.h mbwc.h mem.h nwad.h nwio.h oht.h opt.h path.h pio.h \
rex.h sio.h sll.h slmb.h stdio.h str.h time.h tio.h tre.h \ pma.h rbt.h rex.h sio.h sll.h slmb.h stdio.h str.h time.h \
utf8.h xma.h Mmgr.hpp StdMmgr.hpp Mmged.hpp 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_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \ am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@ -231,9 +231,9 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
pkginclude_HEADERS = alg.h chr.h cp949.h cp950.h dll.h env.h fio.h \ 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 \ 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 \ mbwc.h mem.h nwad.h nwio.h oht.h opt.h path.h pio.h pma.h \
sio.h sll.h slmb.h stdio.h str.h time.h tio.h tre.h utf8.h \ rbt.h rex.h sio.h sll.h slmb.h stdio.h str.h time.h tio.h \
xma.h $(am__append_1) tre.h utf8.h xma.h $(am__append_1)
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:

201
qse/include/qse/cmn/nwio.h Normal file
View 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

View File

@ -83,7 +83,16 @@ enum qse_pio_flag_t
/** drop stdout */ /** drop stdout */
QSE_PIO_DROPOUT = (1 << 17), QSE_PIO_DROPOUT = (1 << 17),
/** drop stderr */ /** 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; 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. * The qse_pio_errnum_t type defines error numbers.
*/ */
@ -190,7 +176,7 @@ struct qse_pio_pin_t
struct qse_pio_t struct qse_pio_t
{ {
QSE_DEFINE_COMMON_FIELDS(pio) QSE_DEFINE_COMMON_FIELDS(pio)
int option; /**< options */ int flags; /**< options */
qse_pio_errnum_t errnum; /**< error number */ qse_pio_errnum_t errnum; /**< error number */
qse_pio_pid_t child; /**< handle to a child process */ qse_pio_pid_t child; /**< handle to a child process */
qse_pio_pin_t pin[3]; 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 */ /** access the @a errnum field of the #qse_pio_t structure */
#define QSE_PIO_ERRNUM(pio) ((pio)->errnum) #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 */ /** access the @a child field of the #qse_pio_t structure */
#define QSE_PIO_CHILD(pio) ((pio)->child) #define QSE_PIO_CHILD(pio) ((pio)->child)
/** get the native handle from the #qse_pio_t structure */ /** 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 */ 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. * The qse_pio_getcmgr() function returns the current character manager.
* It returns #QSE_NULL is @a pio is not opened with #QSE_PIO_TEXT. * 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 */ 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 * The qse_pio_end() function closes a pipe to a child process
*/ */

View File

@ -99,15 +99,7 @@ struct qse_sio_t
QSE_DEFINE_COMMON_FIELDS (sio) QSE_DEFINE_COMMON_FIELDS (sio)
qse_sio_errnum_t errnum; qse_sio_errnum_t errnum;
/* qse_fio_t file;
depending on the stream type... FILE, FIFO, TCP, UDP
qse_sio_type_t type;
*/
union
{
qse_fio_t file;
int sck;
} u;
struct struct
{ {
@ -126,30 +118,6 @@ struct qse_sio_t
/** access the @a errnum field of the #qse_sio_t structure */ /** access the @a errnum field of the #qse_sio_t structure */
#define QSE_SIO_ERRNUM(sio) ((sio)->errnum) #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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -101,7 +101,19 @@
#endif #endif
#define QSE_SIZEOF_WCHAR_T 4 #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 /* make sure you change these when you change
* the version in configure.ac */ * the version in configure.ac */

View File

@ -55,6 +55,15 @@
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H #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. */ /* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H #undef HAVE_ERRNO_H
@ -263,6 +272,9 @@
*/ */
#undef HAVE_SYS_DIR_H #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'. /* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/ */
#undef HAVE_SYS_NDIR_H #undef HAVE_SYS_NDIR_H

View File

@ -135,6 +135,8 @@ static int find_rio_in (
return -1; return -1;
} }
QSE_MEMSET (p, 0, QSE_SIZEOF(*p));
p->name = QSE_AWK_STRDUP (run->awk, name); p->name = QSE_AWK_STRDUP (run->awk, name);
if (p->name == QSE_NULL) if (p->name == QSE_NULL)
{ {
@ -146,6 +148,7 @@ static int find_rio_in (
p->type = (io_type | io_mask); p->type = (io_type | io_mask);
p->mode = io_mode; p->mode = io_mode;
p->rwcmode = QSE_AWK_RIO_CLOSE_FULL; p->rwcmode = QSE_AWK_RIO_CLOSE_FULL;
/*
p->handle = QSE_NULL; p->handle = QSE_NULL;
p->next = QSE_NULL; p->next = QSE_NULL;
p->rwcstate = 0; p->rwcstate = 0;
@ -155,6 +158,7 @@ static int find_rio_in (
p->in.len = 0; p->in.len = 0;
p->in.eof = 0; p->in.eof = 0;
p->in.eos = 0; p->in.eos = 0;
*/
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL); 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); qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
return -1; return -1;
} }
QSE_MEMSET (p, 0, QSE_SIZEOF(*p));
p->name = QSE_AWK_STRDUP (run->awk, name); p->name = QSE_AWK_STRDUP (run->awk, name);
if (p->name == QSE_NULL) if (p->name == QSE_NULL)
@ -730,12 +736,14 @@ int qse_awk_rtx_writeio_str (
p->type = (io_type | io_mask); p->type = (io_type | io_mask);
p->mode = io_mode; p->mode = io_mode;
p->rwcmode = QSE_AWK_RIO_CLOSE_FULL; p->rwcmode = QSE_AWK_RIO_CLOSE_FULL;
/*
p->handle = QSE_NULL; p->handle = QSE_NULL;
p->next = QSE_NULL; p->next = QSE_NULL;
p->rwcstate = 0; p->rwcstate = 0;
p->out.eof = 0; p->out.eof = 0;
p->out.eos = 0; p->out.eos = 0;
*/
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL); qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL);
n = handler (run, QSE_AWK_RIO_OPEN, p, QSE_NULL, 0); n = handler (run, QSE_AWK_RIO_OPEN, p, QSE_NULL, 0);

View File

@ -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); 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* qse_awk_rtx_poprcb (qse_awk_rtx_t* rtx)
{ {
qse_awk_rcb_t* top = rtx->rcb; 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; 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_PIPE] = rio->pipe;
rtx->rio.handler[QSE_AWK_RIO_FILE] = rio->file; rtx->rio.handler[QSE_AWK_RIO_FILE] = rio->file;

View File

@ -91,11 +91,10 @@ typedef struct xtn_t
} str; } str;
} u; } u;
} out; } out;
} s; /* script/source handling */
} s;
} xtn_t; } xtn_t;
typedef struct rxtn_t typedef struct rxtn_t
{ {
unsigned int seed; unsigned int seed;
@ -124,11 +123,6 @@ typedef struct rxtn_t
#endif #endif
} rxtn_t; } 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) static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y)
{ {
#if defined(HAVE_POWL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE) #if defined(HAVE_POWL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
@ -798,6 +792,7 @@ int qse_awk_parsestd (
} }
/*** RTX_OPENSTD ***/ /*** RTX_OPENSTD ***/
static qse_ssize_t awk_rio_pipe ( 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_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_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) if (riod->mode == QSE_AWK_RIO_PIPE_READ)
{ {
/* TODO: should we specify ERRTOOUT? */ /* TODO: should ERRTOOUT be unset? */
flags = QSE_PIO_READOUT | flags = QSE_PIO_READOUT |
QSE_PIO_ERRTOOUT; QSE_PIO_ERRTOOUT;
} }
@ -825,7 +820,12 @@ static qse_ssize_t awk_rio_pipe (
QSE_PIO_ERRTOOUT | QSE_PIO_ERRTOOUT |
QSE_PIO_WRITEIN; 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 ( handle = qse_pio_open (
rtx->awk->mmgr, rtx->awk->mmgr,
@ -838,7 +838,7 @@ static qse_ssize_t awk_rio_pipe (
#if defined(QSE_CHAR_IS_WCHAR) #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) if (cmgr)
{ {
qse_pio_setcmgr (handle, QSE_PIO_IN, 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) #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); if (cmgr) qse_sio_setcmgr (handle, cmgr);
} }
#endif #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) #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) qse_awk_rtx_t* rtx, const qse_char_t* ioname)
{ {
rxtn_t* rxtn; rxtn_t* rxtn;

View File

@ -47,6 +47,7 @@ libqsecmn_la_SOURCES = \
mbwc-str.c \ mbwc-str.c \
mem.c \ mem.c \
nwad.c \ nwad.c \
nwio.c \
oht.c \ oht.c \
opt.c \ opt.c \
path-basename.c \ path-basename.c \

View File

@ -82,17 +82,18 @@ libqsecmn_la_LIBADD =
am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \ 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 \ 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 \ 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 \ ipad.lo main.lo mbwc.lo mbwc-str.lo mem.lo nwad.lo nwio.lo \
opt.lo path-basename.lo path-canon.lo pio.lo pma.lo rbt.lo \ oht.lo opt.lo path-basename.lo path-canon.lo pio.lo pma.lo \
rex.lo sio.lo sll.lo slmb.lo stdio.lo str-beg.lo str-cat.lo \ rbt.lo rex.lo sio.lo sll.lo slmb.lo stdio.lo str-beg.lo \
str-chr.lo str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo \ str-cat.lo str-chr.lo str-cnv.lo str-cmp.lo str-cpy.lo \
str-dup.lo str-dynm.lo str-dynw.lo str-end.lo str-excl.lo \ str-del.lo str-dup.lo str-dynm.lo str-dynw.lo str-end.lo \
str-fcpy.lo str-fnmat.lo str-incl.lo str-len.lo str-pac.lo \ str-excl.lo str-fcpy.lo str-fnmat.lo str-incl.lo str-len.lo \
str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \ str-pac.lo str-pbrk.lo str-put.lo str-rev.lo str-rot.lo \
str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \ str-set.lo str-spl.lo str-spn.lo str-str.lo str-subst.lo \
str-trm.lo str-word.lo time.lo tio.lo tio-get.lo tio-put.lo \ str-tok.lo str-trm.lo str-word.lo time.lo tio.lo tio-get.lo \
tre.lo tre-ast.lo tre-compile.lo tre-match-backtrack.lo \ tio-put.lo tre.lo tre-ast.lo tre-compile.lo \
tre-match-parallel.lo tre-parse.lo tre-stack.lo utf8.lo xma.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_OBJECTS = $(am_libqsecmn_la_OBJECTS)
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -326,6 +327,7 @@ libqsecmn_la_SOURCES = \
mbwc-str.c \ mbwc-str.c \
mem.c \ mem.c \
nwad.c \ nwad.c \
nwio.c \
oht.c \ oht.c \
opt.c \ opt.c \
path-basename.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)/mbwc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.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)/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)/oht.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.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@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-basename.Plo@am__quote@

View File

@ -40,6 +40,9 @@
#elif defined(__DOS__) #elif defined(__DOS__)
# include <dos.h> # include <dos.h>
# include <dosfunc.h> # include <dosfunc.h>
#elif defined(vms) || defined(__vms)
# include <starlet.h> /* (SYS$...) */
# include <ssdef.h> /* (SS$...) */
#else #else
# include "syscall.h" # include "syscall.h"
#endif #endif
@ -165,6 +168,9 @@ void qse_assert_failed (
regs.h.al = 249; regs.h.al = 249;
intdos (&regs, &regs); intdos (&regs, &regs);
} }
#elif defined(vms) || defined(__vms)
sys$exit (SS$_ABORT); /* this condition code can be shown with
* 'show symbol $status' from the command-line. */
#else #else
QSE_KILL (QSE_GETPID(), SIGABRT); QSE_KILL (QSE_GETPID(), SIGABRT);
QSE_EXIT (1); QSE_EXIT (1);

659
qse/lib/cmn/nwio.c Normal file
View 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;
}

View File

@ -575,6 +575,7 @@ int qse_pio_init (
QSE_MEMSET (pio, 0, QSE_SIZEOF(*pio)); QSE_MEMSET (pio, 0, QSE_SIZEOF(*pio));
pio->mmgr = mmgr; pio->mmgr = mmgr;
pio->flags = flags;
#if defined(_WIN32) #if defined(_WIN32)
/* http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx */ /* http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx */
@ -1886,7 +1887,6 @@ create_process:
} }
} }
pio->option = 0;
return 0; return 0;
oops: 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_OUT);
qse_pio_end (pio, QSE_PIO_IN); qse_pio_end (pio, QSE_PIO_IN);
pio->option &= ~QSE_PIO_WAIT_NOBLOCK; /* when closing, enable blocking and retrying */
pio->option &= ~QSE_PIO_WAIT_NORETRY; pio->flags &= ~QSE_PIO_WAITNOBLOCK;
pio->flags &= ~QSE_PIO_WAITNORETRY;
qse_pio_wait (pio); qse_pio_wait (pio);
} }
@ -1971,16 +1972,6 @@ qse_pio_errnum_t qse_pio_geterrnum (const qse_pio_t* pio)
return pio->errnum; 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) qse_cmgr_t* qse_pio_getcmgr (qse_pio_t* pio, qse_pio_hid_t hid)
{ {
return pio->pin[hid].tio? return pio->pin[hid].tio?
@ -2090,7 +2081,7 @@ reread:
{ {
if (errno == EINTR) if (errno == EINTR)
{ {
if (pio->option & QSE_PIO_READ_NORETRY) if (pio->flags & QSE_PIO_READNORETRY)
pio->errnum = QSE_PIO_EINTR; pio->errnum = QSE_PIO_EINTR;
else goto reread; else goto reread;
} }
@ -2188,7 +2179,7 @@ rewrite:
{ {
if (errno == EINTR) if (errno == EINTR)
{ {
if (pio->option & QSE_PIO_WRITE_NORETRY) if (pio->flags & QSE_PIO_WRITENORETRY)
pio->errnum = QSE_PIO_EINTR; pio->errnum = QSE_PIO_EINTR;
else goto rewrite; else goto rewrite;
} }
@ -2235,9 +2226,14 @@ qse_ssize_t qse_pio_flush (qse_pio_t* pio, qse_pio_hid_t hid)
return n; 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) 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); qse_tio_close (pio->pin[hid].tio);
pio->pin[hid].tio = QSE_NULL; pio->pin[hid].tio = QSE_NULL;
@ -2271,7 +2267,7 @@ int qse_pio_wait (qse_pio_t* pio)
} }
w = WaitForSingleObject (pio->child, w = WaitForSingleObject (pio->child,
((pio->option & QSE_PIO_WAIT_NOBLOCK)? 0: INFINITE) ((pio->flags & QSE_PIO_WAITNOBLOCK)? 0: INFINITE)
); );
if (w == WAIT_TIMEOUT) if (w == WAIT_TIMEOUT)
{ {
@ -2327,7 +2323,7 @@ int qse_pio_wait (qse_pio_t* pio)
rc = DosWaitChild ( rc = DosWaitChild (
DCWA_PROCESSTREE, DCWA_PROCESSTREE,
((pio->option & QSE_PIO_WAIT_NOBLOCK)? DCWW_NOWAIT: DCWW_WAIT), ((pio->flags & QSE_PIO_WAITNOBLOCK)? DCWW_NOWAIT: DCWW_WAIT),
&child_rc, &child_rc,
&ppid, &ppid,
pio->child pio->child
@ -2367,7 +2363,7 @@ int qse_pio_wait (qse_pio_t* pio)
return -1; return -1;
} }
if (pio->option & QSE_PIO_WAIT_NOBLOCK) opt |= WNOHANG; if (pio->flags & QSE_PIO_WAITNOBLOCK) opt |= WNOHANG;
while (1) while (1)
{ {
@ -2385,7 +2381,7 @@ int qse_pio_wait (qse_pio_t* pio)
} }
else if (errno == EINTR) else if (errno == EINTR)
{ {
if (pio->option & QSE_PIO_WAIT_NORETRY) if (pio->flags & QSE_PIO_WAITNORETRY)
pio->errnum = QSE_PIO_EINTR; pio->errnum = QSE_PIO_EINTR;
else continue; else continue;
} }
@ -2397,7 +2393,7 @@ int qse_pio_wait (qse_pio_t* pio)
if (n == 0) if (n == 0)
{ {
/* when WNOHANG is not specified, 0 can't be returned */ /* 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; ret = 255 + 1;
/* the child process is still alive */ /* the child process is still alive */

View File

@ -44,11 +44,6 @@ static qse_ssize_t file_input (
static qse_ssize_t file_output ( static qse_ssize_t file_output (
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size); 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) static qse_sio_errnum_t fio_errnum_to_sio_errnum (qse_fio_t* fio)
{ {
switch (fio->errnum) switch (fio->errnum)
@ -129,7 +124,7 @@ qse_sio_t* qse_sio_openstd (
if (sio) if (sio)
{ {
DWORD mode; DWORD mode;
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE && if (GetConsoleMode (sio->file.handle, &mode) == TRUE &&
GetConsoleOutputCP() == CP_UTF8) GetConsoleOutputCP() == CP_UTF8)
{ {
sio->status |= STATUS_UTF8_CONSOLE; sio->status |= STATUS_UTF8_CONSOLE;
@ -163,10 +158,10 @@ int qse_sio_init (
* this function, a user can specify a sio flag enumerator not * this function, a user can specify a sio flag enumerator not
* present in the fio flag enumerator. mask off such an enumerator. */ * present in the fio flag enumerator. mask off such an enumerator. */
if (qse_fio_init ( if (qse_fio_init (
&sio->u.file, mmgr, file, &sio->file, mmgr, file,
(flags & ~QSE_FIO_RESERVED), mode) <= -1) (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; return -1;
} }
@ -176,7 +171,7 @@ int qse_sio_init (
if (qse_tio_init(&sio->tio.io, mmgr, topt) <= -1) if (qse_tio_init(&sio->tio.io, mmgr, topt) <= -1)
{ {
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
qse_fio_fini (&sio->u.file); qse_fio_fini (&sio->file);
return -1; return -1;
} }
/* store the back-reference to sio in the extension area.*/ /* store the back-reference to sio in the extension area.*/
@ -189,7 +184,7 @@ int qse_sio_init (
if (sio->errnum == QSE_SIO_ENOERR) if (sio->errnum == QSE_SIO_ENOERR)
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
qse_tio_fini (&sio->tio.io); qse_tio_fini (&sio->tio.io);
qse_fio_fini (&sio->u.file); qse_fio_fini (&sio->file);
return -1; return -1;
} }
@ -211,7 +206,7 @@ int qse_sio_initstd (
if (n >= 0) if (n >= 0)
{ {
DWORD mode; DWORD mode;
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE && if (GetConsoleMode (sio->file.handle, &mode) == TRUE &&
GetConsoleOutputCP() == CP_UTF8) GetConsoleOutputCP() == CP_UTF8)
{ {
sio->status |= STATUS_UTF8_CONSOLE; 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;*/ /*if (qse_sio_flush (sio) <= -1) return -1;*/
qse_sio_flush (sio); qse_sio_flush (sio);
qse_tio_fini (&sio->tio.io); 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) 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) qse_sio_hnd_t qse_sio_gethandle (const qse_sio_t* sio)
{ {
/*return qse_fio_gethandle (&sio->u.file);*/ /*return qse_fio_gethandle (&sio->file);*/
return QSE_FIO_HANDLE(&sio->u.file); return QSE_FIO_HANDLE(&sio->file);
} }
qse_ubi_t qse_sio_gethandleasubi (const qse_sio_t* sio) 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) 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) for (cur = str, left = qse_wcslen(str); left > 0; cur += count, left -= count)
{ {
if (WriteConsoleW ( if (WriteConsoleW (
sio->u.file.handle, cur, left, sio->file.handle, cur, left,
&count, QSE_NULL) == FALSE) &count, QSE_NULL) == FALSE)
{ {
sio->errnum = QSE_SIO_ESYSERR; 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) for (cur = str, left = size; left > 0; cur += count, left -= count)
{ {
if (WriteConsoleW ( if (WriteConsoleW (
sio->u.file.handle, cur, left, sio->file.handle, cur, left,
&count, QSE_NULL) == FALSE) &count, QSE_NULL) == FALSE)
{ {
sio->errnum = QSE_SIO_ESYSERR; 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; 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) 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; return -1;
} }
@ -560,10 +555,10 @@ int qse_sio_setpos (qse_sio_t* sio, qse_sio_pos_t pos)
qse_fio_off_t off; qse_fio_off_t off;
if (qse_sio_flush(sio) <= -1) return -1; 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) 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; 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.... */ * can move to the end of the stream also.... */
if (qse_sio_flush(sio) <= -1) return -1; 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; 0, QSE_FIO_END) == (qse_fio_off_t)-1)? -1: 0;
/* TODO: write this function */ /* TODO: write this function */
if (qse_sio_flush(sio) <= -1) return -1; 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; 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); sio = *(qse_sio_t**)QSE_XTN(tio);
QSE_ASSERT (sio != QSE_NULL); QSE_ASSERT (sio != QSE_NULL);
n = qse_fio_read (&sio->u.file, buf, size); n = qse_fio_read (&sio->file, buf, size);
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file); if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
return n; return n;
} }
@ -619,61 +614,11 @@ static qse_ssize_t file_output (
sio = *(qse_sio_t**)QSE_XTN(tio); sio = *(qse_sio_t**)QSE_XTN(tio);
QSE_ASSERT (sio != QSE_NULL); QSE_ASSERT (sio != QSE_NULL);
n = qse_fio_write (&sio->u.file, buf, size); n = qse_fio_write (&sio->file, buf, size);
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file); if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
return n; return n;
} }
return 0; 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

View File

@ -21,7 +21,8 @@
#include "sed.h" #include "sed.h"
#include "../cmn/mem.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[] = static const qse_char_t* errstr[] =
{ {

View File

@ -233,11 +233,10 @@ void qse_sed_fini (
); );
const qse_char_t* qse_sed_dflerrstr ( const qse_char_t* qse_sed_dflerrstr (
qse_sed_t* sed, const qse_sed_t* sed,
qse_sed_errnum_t errnum qse_sed_errnum_t errnum
); );
#ifdef USE_REX #ifdef USE_REX
/** /**
* The qse_sed_getmaxdepth() gets the maximum processing depth. * The qse_sed_getmaxdepth() gets the maximum processing depth.

View File

@ -19,7 +19,12 @@
# include <sys/stat.h> # include <sys/stat.h>
# include <sys/socket.h> # include <sys/socket.h>
# include <netinet/in.h> # include <netinet/in.h>
# include <sys/epoll.h> #endif
#if defined(HAVE_EPOLL)
# if defined(HAVE_SYS_EPOLL_H)
# include <sys/epoll.h>
# endif
#endif #endif
#if defined(__linux__) #if defined(__linux__)
@ -332,12 +337,20 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
flag = 1; flag = 1;
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &flag, QSE_SIZEOF(flag)); 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 /* Solaris 8 returns EINVAL if QSE_SIZEOF(addr) is passed in as the
* address size for AF_INET. */ * address size for AF_INET. */
/*if (bind (s, (struct sockaddr*)&addr, QSE_SIZEOF(addr)) <= -1) goto oops_esocket;*/ /*if (bind (s, (struct sockaddr*)&addr, QSE_SIZEOF(addr)) <= -1) goto oops_esocket;*/
if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1) if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1)
{ {
#ifdef IPV6_V6ONLY #if defined(IPV6_V6ONLY)
if (errno == EADDRINUSE && addr.ss_family == AF_INET6) if (errno == EADDRINUSE && addr.ss_family == AF_INET6)
{ {
int on = 1; int on = 1;
@ -561,7 +574,11 @@ static void* mux_open (qse_httpd_t* httpd)
memset (mux, 0, QSE_SIZEOF(*mux)); memset (mux, 0, QSE_SIZEOF(*mux));
#if defined(HAVE_EPOLL_CREATE1)
mux->fd = epoll_create1 (O_CLOEXEC);
#else
mux->fd = epoll_create (100); mux->fd = epoll_create (100);
#endif
if (mux->fd <= -1) if (mux->fd <= -1)
{ {
qse_httpd_freemem (httpd, mux); qse_httpd_freemem (httpd, mux);
@ -569,6 +586,13 @@ static void* mux_open (qse_httpd_t* httpd)
return QSE_NULL; 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; return mux;
} }
@ -1188,6 +1212,7 @@ qse_printf (QSE_T("Entasking chunked CGI...\n"));
} }
else else
{ {
#if 0
if (!peek) if (!peek)
{ {
/* file or directory */ /* file or directory */
@ -1195,6 +1220,15 @@ qse_printf (QSE_T("Entasking chunked CGI...\n"));
httpd, client, QSE_NULL, qpath, req); httpd, client, QSE_NULL, qpath, req);
if (task == QSE_NULL) goto oops; 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 else