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/mbwc.h>
#include <qse/cmn/xma.h>
#include <qse/cmn/nwio.h>
#include <string.h>
#include <signal.h>
@ -55,6 +56,10 @@
# include <errno.h>
#endif
#include <sys/socket.h>
static qse_awk_rtx_t* app_rtx = QSE_NULL;
static int app_debug = 0;
@ -93,6 +98,11 @@ struct gvmv_t
qse_size_t len;
};
struct rtx_xtn_t
{
qse_awk_rio_fun_t old_pipe_handler;
};
static void dprint (const qse_char_t* fmt, ...)
{
if (app_debug)
@ -884,6 +894,101 @@ static qse_mmgr_t debug_mmgr =
};
#endif
static qse_ssize_t nwio_handler (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size, qse_nwad_t* nwad)
{
switch (cmd)
{
case QSE_AWK_RIO_OPEN:
{
qse_nwio_t* handle;
handle = qse_nwio_open (
qse_awk_rtx_getmmgr(rtx), 0, nwad,
QSE_NWIO_TEXT | QSE_NWIO_IGNOREMBWCERR |
QSE_NWIO_READNORETRY | QSE_NWIO_WRITENORETRY
);
if (handle == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
if (cmgr) qse_nwio_setcmgr (handle, cmgr);
}
#endif
riod->handle = (void*)handle;
return 1;
}
case QSE_AWK_RIO_CLOSE:
{
qse_nwio_close ((qse_nwio_t*)riod->handle);
riod->handle = QSE_NULL;
return 0;
}
case QSE_AWK_RIO_READ:
{
return qse_nwio_read ((qse_nwio_t*)riod->handle, data, size);
}
case QSE_AWK_RIO_WRITE:
{
return qse_nwio_write ((qse_nwio_t*)riod->handle, data, size);
}
case QSE_AWK_RIO_FLUSH:
{
/*if (riod->mode == QSE_AWK_RIO_PIPE_READ) return -1;*/
return qse_nwio_flush ((qse_nwio_t*)riod->handle);
}
case QSE_AWK_RIO_NEXT:
{
return -1;
}
}
return -1;
}
static qse_ssize_t new_pipe_handler (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
struct rtx_xtn_t* xtn;
qse_nwad_t nwad;
xtn = qse_awk_rtx_getxtnstd (rtx);
if (qse_strtonwad (riod->name, &nwad) >= 0)
return nwio_handler (rtx, cmd, riod, data, size, &nwad);
return xtn->old_pipe_handler (rtx, cmd, riod, data, size);
}
static void extend_pipe_handler (qse_awk_rtx_t* rtx)
{
struct rtx_xtn_t* xtn;
qse_awk_rio_t rio;
xtn = qse_awk_rtx_getxtnstd (rtx);
/* get the previous handler functions */
qse_awk_rtx_getrio (rtx, &rio);
/* remember the old pipe handler function */
xtn->old_pipe_handler = rio.pipe;
/* change the pipe handler to a new one */
rio.pipe = new_pipe_handler;
/* changes the handlers with a new set */
qse_awk_rtx_setrio (rtx, &rio);
}
static int awk_main (int argc, qse_char_t* argv[])
{
qse_awk_t* awk = QSE_NULL;
@ -999,7 +1104,7 @@ static int awk_main (int argc, qse_char_t* argv[])
#endif
rtx = qse_awk_rtx_openstd (
awk, 0, QSE_T("qseawk"),
awk, QSE_SIZEOF(struct rtx_xtn_t), QSE_T("qseawk"),
(const qse_char_t*const*)arg.icf, QSE_NULL, arg.console_cmgr);
if (rtx == QSE_NULL)
{
@ -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

37
qse/configure vendored
View File

@ -16002,7 +16002,7 @@ fi
done
for ac_header in time.h sys/time.h utime.h spawn.h
for ac_header in time.h sys/time.h utime.h spawn.h execinfo.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -16015,7 +16015,7 @@ fi
done
for ac_header in sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h
for ac_header in sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h sys/epoll.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -16028,18 +16028,6 @@ fi
done
for ac_header in execinfo.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
if test "x$ac_cv_header_execinfo_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_EXECINFO_H 1
_ACEOF
fi
done
ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "#include <stddef.h>
"
@ -16542,6 +16530,27 @@ fi
fi
$as_echo "#define HAVE_EPOLL /**/" >>confdefs.h
for ac_func in epoll_create epoll_create1
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
if test "$ac_cv_func_epoll_create" = "yes"
then
$as_echo "#define HAVE_EPOLL 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lunicows" >&5
$as_echo_n "checking for main in -lunicows... " >&6; }
if ${ac_cv_lib_unicows_main+:} false; then :

View File

@ -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

View File

@ -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,

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 (
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

View File

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

View File

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

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

View File

@ -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

View File

@ -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 */

View File

@ -55,6 +55,15 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* epoll support */
#undef HAVE_EPOLL
/* Define to 1 if you have the `epoll_create' function. */
#undef HAVE_EPOLL_CREATE
/* Define to 1 if you have the `epoll_create1' function. */
#undef HAVE_EPOLL_CREATE1
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
@ -263,6 +272,9 @@
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/epoll.h> header file. */
#undef HAVE_SYS_EPOLL_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H

View File

@ -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);

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);
}
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;

View File

@ -91,11 +91,10 @@ typedef struct xtn_t
} str;
} u;
} out;
} s; /* script/source handling */
} s;
} xtn_t;
typedef struct rxtn_t
{
unsigned int seed;
@ -124,11 +123,6 @@ typedef struct rxtn_t
#endif
} rxtn_t;
#if defined(QSE_CHAR_IS_WCHAR)
static qse_cmgr_t* getcmgr_from_cmgrtab (
qse_awk_rtx_t* rtx, const qse_char_t* ioname);
#endif
static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y)
{
#if defined(HAVE_POWL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
@ -798,6 +792,7 @@ int qse_awk_parsestd (
}
/*** RTX_OPENSTD ***/
static qse_ssize_t awk_rio_pipe (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
@ -811,7 +806,7 @@ static qse_ssize_t awk_rio_pipe (
if (riod->mode == QSE_AWK_RIO_PIPE_READ)
{
/* TODO: should we specify ERRTOOUT? */
/* TODO: should ERRTOOUT be unset? */
flags = QSE_PIO_READOUT |
QSE_PIO_ERRTOOUT;
}
@ -825,7 +820,12 @@ static qse_ssize_t awk_rio_pipe (
QSE_PIO_ERRTOOUT |
QSE_PIO_WRITEIN;
}
else return -1; /* TODO: any way to set the error number? */
else
{
/* this must not happen */
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
handle = qse_pio_open (
rtx->awk->mmgr,
@ -838,7 +838,7 @@ static qse_ssize_t awk_rio_pipe (
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = getcmgr_from_cmgrtab (rtx, riod->name);
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
if (cmgr)
{
qse_pio_setcmgr (handle, QSE_PIO_IN, cmgr);
@ -951,7 +951,7 @@ static qse_ssize_t awk_rio_file (
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = getcmgr_from_cmgrtab (rtx, riod->name);
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
if (cmgr) qse_sio_setcmgr (handle, cmgr);
}
#endif
@ -1587,7 +1587,7 @@ static int fnc_time (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
}
#if defined(QSE_CHAR_IS_WCHAR)
static qse_cmgr_t* getcmgr_from_cmgrtab (
qse_cmgr_t* qse_awk_rtx_getcmgrstd (
qse_awk_rtx_t* rtx, const qse_char_t* ioname)
{
rxtn_t* rxtn;

View File

@ -47,6 +47,7 @@ libqsecmn_la_SOURCES = \
mbwc-str.c \
mem.c \
nwad.c \
nwio.c \
oht.c \
opt.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 \
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@

View File

@ -40,6 +40,9 @@
#elif defined(__DOS__)
# include <dos.h>
# include <dosfunc.h>
#elif defined(vms) || defined(__vms)
# include <starlet.h> /* (SYS$...) */
# include <ssdef.h> /* (SS$...) */
#else
# include "syscall.h"
#endif
@ -165,6 +168,9 @@ void qse_assert_failed (
regs.h.al = 249;
intdos (&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
QSE_KILL (QSE_GETPID(), SIGABRT);
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));
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 */

View File

@ -44,11 +44,6 @@ static qse_ssize_t file_input (
static qse_ssize_t file_output (
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
static qse_ssize_t socket_input (
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
static qse_ssize_t socket_output (
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size);
static qse_sio_errnum_t fio_errnum_to_sio_errnum (qse_fio_t* fio)
{
switch (fio->errnum)
@ -129,7 +124,7 @@ qse_sio_t* qse_sio_openstd (
if (sio)
{
DWORD mode;
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE &&
if (GetConsoleMode (sio->file.handle, &mode) == TRUE &&
GetConsoleOutputCP() == CP_UTF8)
{
sio->status |= STATUS_UTF8_CONSOLE;
@ -163,10 +158,10 @@ int qse_sio_init (
* this function, a user can specify a sio flag enumerator not
* present in the fio flag enumerator. mask off such an enumerator. */
if (qse_fio_init (
&sio->u.file, mmgr, file,
&sio->file, mmgr, file,
(flags & ~QSE_FIO_RESERVED), mode) <= -1)
{
sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
return -1;
}
@ -176,7 +171,7 @@ int qse_sio_init (
if (qse_tio_init(&sio->tio.io, mmgr, topt) <= -1)
{
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
qse_fio_fini (&sio->u.file);
qse_fio_fini (&sio->file);
return -1;
}
/* store the back-reference to sio in the extension area.*/
@ -189,7 +184,7 @@ int qse_sio_init (
if (sio->errnum == QSE_SIO_ENOERR)
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
qse_tio_fini (&sio->tio.io);
qse_fio_fini (&sio->u.file);
qse_fio_fini (&sio->file);
return -1;
}
@ -211,7 +206,7 @@ int qse_sio_initstd (
if (n >= 0)
{
DWORD mode;
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE &&
if (GetConsoleMode (sio->file.handle, &mode) == TRUE &&
GetConsoleOutputCP() == CP_UTF8)
{
sio->status |= STATUS_UTF8_CONSOLE;
@ -227,7 +222,7 @@ void qse_sio_fini (qse_sio_t* sio)
/*if (qse_sio_flush (sio) <= -1) return -1;*/
qse_sio_flush (sio);
qse_tio_fini (&sio->tio.io);
qse_fio_fini (&sio->u.file);
qse_fio_fini (&sio->file);
}
qse_sio_errnum_t qse_sio_geterrnum (const qse_sio_t* sio)
@ -247,13 +242,13 @@ void qse_sio_setcmgr (qse_sio_t* sio, qse_cmgr_t* cmgr)
qse_sio_hnd_t qse_sio_gethandle (const qse_sio_t* sio)
{
/*return qse_fio_gethandle (&sio->u.file);*/
return QSE_FIO_HANDLE(&sio->u.file);
/*return qse_fio_gethandle (&sio->file);*/
return QSE_FIO_HANDLE(&sio->file);
}
qse_ubi_t qse_sio_gethandleasubi (const qse_sio_t* sio)
{
return qse_fio_gethandleasubi (&sio->u.file);
return qse_fio_gethandleasubi (&sio->file);
}
qse_ssize_t qse_sio_flush (qse_sio_t* sio)
@ -453,7 +448,7 @@ qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str)
for (cur = str, left = qse_wcslen(str); left > 0; cur += count, left -= count)
{
if (WriteConsoleW (
sio->u.file.handle, cur, left,
sio->file.handle, cur, left,
&count, QSE_NULL) == FALSE)
{
sio->errnum = QSE_SIO_ESYSERR;
@ -506,7 +501,7 @@ qse_ssize_t qse_sio_putwcsn (
for (cur = str, left = size; left > 0; cur += count, left -= count)
{
if (WriteConsoleW (
sio->u.file.handle, cur, left,
sio->file.handle, cur, left,
&count, QSE_NULL) == FALSE)
{
sio->errnum = QSE_SIO_ESYSERR;
@ -544,10 +539,10 @@ int qse_sio_getpos (qse_sio_t* sio, qse_sio_pos_t* pos)
{
qse_fio_off_t off;
off = qse_fio_seek (&sio->u.file, 0, QSE_FIO_CURRENT);
off = qse_fio_seek (&sio->file, 0, QSE_FIO_CURRENT);
if (off == (qse_fio_off_t)-1)
{
sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
return -1;
}
@ -560,10 +555,10 @@ int qse_sio_setpos (qse_sio_t* sio, qse_sio_pos_t pos)
qse_fio_off_t off;
if (qse_sio_flush(sio) <= -1) return -1;
off = qse_fio_seek (&sio->u.file, pos, QSE_FIO_BEGIN);
off = qse_fio_seek (&sio->file, pos, QSE_FIO_BEGIN);
if (off == (qse_fio_off_t)-1)
{
sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
return -1;
}
@ -577,12 +572,12 @@ int qse_sio_seek (qse_sio_t* sio, qse_sio_seek_t pos)
* can move to the end of the stream also.... */
if (qse_sio_flush(sio) <= -1) return -1;
return (qse_fio_seek (&sio->u.file,
return (qse_fio_seek (&sio->file,
0, QSE_FIO_END) == (qse_fio_off_t)-1)? -1: 0;
/* TODO: write this function */
if (qse_sio_flush(sio) <= -1) return -1;
return (qse_fio_seek (&sio->u.file,
return (qse_fio_seek (&sio->file,
0, QSE_FIO_BEGIN) == (qse_fio_off_t)-1)? -1: 0;
}
@ -600,8 +595,8 @@ static qse_ssize_t file_input (
sio = *(qse_sio_t**)QSE_XTN(tio);
QSE_ASSERT (sio != QSE_NULL);
n = qse_fio_read (&sio->u.file, buf, size);
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
n = qse_fio_read (&sio->file, buf, size);
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
return n;
}
@ -619,61 +614,11 @@ static qse_ssize_t file_output (
sio = *(qse_sio_t**)QSE_XTN(tio);
QSE_ASSERT (sio != QSE_NULL);
n = qse_fio_write (&sio->u.file, buf, size);
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
n = qse_fio_write (&sio->file, buf, size);
if (n <= -1) sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
return n;
}
return 0;
}
/* ---------------------------------------------------------- */
#if 0
#if defined(_WIN32)
# include <winsock2.h>
#else
# include <sys/socket.h>
#endif
static qse_ssize_t socket_input (
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size)
{
if (cmd == QSE_TIO_DATA)
{
qse_ssize_t n;
qse_sio_t* sio;
sio = *(qse_sio_t**)QSE_XTN(tio);
QSE_ASSERT (sio != QSE_NULL);
n = recv (sio->u.sck, buf, size, 0);
if (n <= -1) sio->errnum = syserr_to_errnum (errno);
return n;
}
return 0;
}
static qse_ssize_t socket_output (
qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size)
{
if (cmd == QSE_TIO_DATA)
{
qse_ssize_t n;
qse_sio_t* sio;
sio = *(qse_sio_t**)QSE_XTN(tio);
QSE_ASSERT (sio != QSE_NULL);
n = send (sio->u.sck, buf, size, 0);
if (n <= -1) sio->errnum = syserr_to_errnum (errno);
return n;
}
return 0;
}
#endif

View File

@ -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[] =
{

View File

@ -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.

View File

@ -19,7 +19,12 @@
# include <sys/stat.h>
# include <sys/socket.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
#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