From a2346f6e4b0599362eb4f975e99d8981a78274a1 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 12 Feb 2012 13:20:39 +0000 Subject: [PATCH] enhanced error handling of sio,pio,tio --- qse/configure | 4 +- qse/configure.ac | 4 +- qse/include/qse/cmn/fio.h | 107 ++++---- qse/include/qse/cmn/pio.h | 26 +- qse/include/qse/cmn/sio.h | 99 ++++++-- qse/include/qse/cmn/tio.h | 19 +- qse/include/qse/config.h.in | 6 + qse/include/qse/net/http.h | 54 +++- qse/lib/cmn/fio.c | 485 ++++++++++++++++++++++++------------ qse/lib/cmn/pio.c | 290 +++++++++++++++------ qse/lib/cmn/sio.c | 371 ++++++++++++++++++++++----- qse/lib/cmn/syscall.h | 3 + qse/lib/cmn/tio-get.c | 13 +- qse/lib/cmn/tio.c | 58 ++--- qse/lib/net/htrd.c | 6 +- qse/lib/net/htre.c | 5 +- qse/lib/net/http.c | 34 +-- qse/lib/net/httpd_task.c | 4 +- qse/samples/cmn/fio01.c | 23 +- qse/samples/cmn/pio.c | 16 +- qse/samples/net/http01.c | 2 + 21 files changed, 1104 insertions(+), 525 deletions(-) diff --git a/qse/configure b/qse/configure index b193d1be..a070bf41 100755 --- a/qse/configure +++ b/qse/configure @@ -15987,7 +15987,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi -for ac_header in stddef.h wchar.h wctype.h errno.h signal.h +for ac_header in stddef.h wchar.h wctype.h errno.h signal.h fcntl.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" @@ -16013,7 +16013,7 @@ fi done -for ac_header in sys/resource.h sys/syscall.h sys/sendfile.h +for ac_header in sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.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" diff --git a/qse/configure.ac b/qse/configure.ac index bbb5b2ae..6d9f47b1 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -78,9 +78,9 @@ AC_SUBST(LIBM, $LIBM) dnl check header files. AC_HEADER_STDC -AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.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([sys/resource.h sys/syscall.h sys/sendfile.h]) +AC_CHECK_HEADERS([sys/resource.h sys/wait.h sys/syscall.h sys/sendfile.h]) AC_CHECK_HEADERS([execinfo.h]) dnl check data types diff --git a/qse/include/qse/cmn/fio.h b/qse/include/qse/cmn/fio.h index d2ca3ae8..cc582aa9 100644 --- a/qse/include/qse/cmn/fio.h +++ b/qse/include/qse/cmn/fio.h @@ -28,49 +28,62 @@ #include #include -#include - -enum qse_fio_open_flag_t +enum qse_fio_flag_t { - /** request text-based based IO */ - QSE_FIO_TEXT = (1 << 0), - QSE_FIO_IGNOREMBWCERR = (1 << 1), /* useful if QSE_FIO_TEXT is set */ - QSE_FIO_NOAUTOFLUSH = (1 << 2), /* useful if QSE_FIO_TEXT is set */ + /* (1 << 0) to (1 << 7) reserved for qse_sio_flag_t. + * see . nerver use this value. */ + QSE_FIO_RESERVED = 0xFF, /** treat the file name pointer as a handle pointer */ - QSE_FIO_HANDLE = (1 << 3), + QSE_FIO_HANDLE = (1 << 8), /** treate the file name pointer as a pointer to file name * template to use when making a temporary file name */ - QSE_FIO_TEMPORARY = (1 << 4), + QSE_FIO_TEMPORARY = (1 << 9), /** don't close an I/O handle in qse_fio_fini() and qse_fio_close() */ - QSE_FIO_NOCLOSE = (1 << 5), + QSE_FIO_NOCLOSE = (1 << 10), /* normal open flags */ - QSE_FIO_READ = (1 << 8), - QSE_FIO_WRITE = (1 << 9), - QSE_FIO_APPEND = (1 << 10), + QSE_FIO_READ = (1 << 14), + QSE_FIO_WRITE = (1 << 15), + QSE_FIO_APPEND = (1 << 16), - QSE_FIO_CREATE = (1 << 11), - QSE_FIO_TRUNCATE = (1 << 12), - QSE_FIO_EXCLUSIVE = (1 << 13), - QSE_FIO_SYNC = (1 << 14), + QSE_FIO_CREATE = (1 << 17), + QSE_FIO_TRUNCATE = (1 << 18), + QSE_FIO_EXCLUSIVE = (1 << 19), + QSE_FIO_SYNC = (1 << 20), /* do not follow a symbolic link, only on a supported platform */ - QSE_FIO_NOFOLLOW = (1 << 15), + QSE_FIO_NOFOLLOW = (1 << 23), /* for WIN32 only. harmless(no effect) when used on other platforms */ - QSE_FIO_NOSHREAD = (1 << 20), - QSE_FIO_NOSHWRITE = (1 << 21), - QSE_FIO_NOSHDELETE = (1 << 22), + QSE_FIO_NOSHREAD = (1 << 24), + QSE_FIO_NOSHWRITE = (1 << 25), + QSE_FIO_NOSHDELETE = (1 << 26), /* hints to OS. harmless(no effect) when used on unsupported platforms */ - QSE_FIO_RANDOM = (1 << 23), /* hint that access be random */ - QSE_FIO_SEQUENTIAL = (1 << 24) /* hint that access is sequential */ - + QSE_FIO_RANDOM = (1 << 27), /* hint that access be random */ + QSE_FIO_SEQUENTIAL = (1 << 28) /* hint that access is sequential */ }; +enum qse_fio_errnum_t +{ + QSE_FIO_ENOERR = 0, /**< no error */ + + QSE_FIO_ENOMEM, /**< out of memory */ + QSE_FIO_EINVAL, /**< invalid parameter */ + QSE_FIO_EACCES, /**< access denied */ + QSE_FIO_ENOENT, /**< no such file */ + QSE_FIO_EEXIST, /**< already exist */ + QSE_FIO_EINTR, /**< interrupted */ + QSE_FIO_ENOIMPL, /**< not implemented */ + QSE_FIO_ESUBSYS, /**< subsystem(system call) error */ + + QSE_FIO_EOTHER /**< other error */ +}; +typedef enum qse_fio_errnum_t qse_fio_errnum_t; + enum qse_fio_std_t { QSE_FIO_STDIN = 0, @@ -126,13 +139,10 @@ typedef struct qse_fio_lck_t qse_fio_lck_t; struct qse_fio_t { - /* note that qse_fio_t is instantiated statically - * in sio.c. make sure that you update the static instantiation - * when you change the structure of qse_fio_t */ QSE_DEFINE_COMMON_FIELDS (fio) - qse_fio_hnd_t handle; - int flags; /* extra flags */ - qse_tio_t* tio; + qse_fio_errnum_t errnum; + qse_fio_hnd_t handle; + int flags; /* extra flags */ }; struct qse_fio_lck_t @@ -200,23 +210,6 @@ void qse_fio_fini ( qse_fio_t* fio ); -/** - * The qse_fio_getcmgr() funcfion returns the current character manager. - * It returns #QSE_NULL is @a fio is not opened with #QSE_FIO_TEXT. - */ -qse_cmgr_t* qse_fio_getcmgr ( - qse_fio_t* fio -); - -/** - * The qse_fio_setcmgr() funcfion changes the character manager to @a cmgr. - * The character manager is used only if @a fio is opened with #QSE_FIO_TEXT. - */ -void qse_fio_setcmgr ( - qse_fio_t* fio, - qse_cmgr_t* cmgr -); - /** * The qse_fio_gethandle() function returns the native file handle. */ @@ -224,15 +217,8 @@ qse_fio_hnd_t qse_fio_gethandle ( qse_fio_t* fio ); -/** - * The qse_fio_sethandle() function sets the file handle - * Avoid using this function if you don't know what you are doing. - * You may have to retrieve the previous handle using qse_fio_gethandle() - * to take relevant actions before resetting it with qse_fio_sethandle(). - */ -void qse_fio_sethandle ( - qse_fio_t* fio, - qse_fio_hnd_t handle +qse_ubi_t qse_fio_gethandleasubi ( + qse_fio_t* fio ); /** @@ -273,15 +259,6 @@ qse_ssize_t qse_fio_write ( qse_size_t size ); - -/** - * The qse_fio_flush() function flushes data. It is useful if #QSE_FIO_TEXT is - * set for the file handle @a fio. - */ -qse_ssize_t qse_fio_flush ( - qse_fio_t* fio -); - /** * The qse_fio_chmod() function changes the file mode. * diff --git a/qse/include/qse/cmn/pio.h b/qse/include/qse/cmn/pio.h index 056d0843..0792656d 100644 --- a/qse/include/qse/cmn/pio.h +++ b/qse/include/qse/cmn/pio.h @@ -126,15 +126,22 @@ enum qse_pio_option_t enum qse_pio_errnum_t { QSE_PIO_ENOERR = 0, /**< no error */ + QSE_PIO_ENOMEM, /**< out of memory */ QSE_PIO_EINVAL, /**< invalid parameter */ - QSE_PIO_ENOHND, /**< no handle available */ - QSE_PIO_ECHILD, /**< the child is not valid */ - QSE_PIO_EINTR, /**< interrupted */ - QSE_PIO_EPIPE, /**< broken pipe */ QSE_PIO_EACCES, /**< access denied */ QSE_PIO_ENOENT, /**< no such file */ - QSE_PIO_ESUBSYS /**< subsystem(system call) error */ + QSE_PIO_EEXIST, /**< already exist */ + QSE_PIO_EINTR, /**< interrupted */ + QSE_PIO_ENOHND, /**< no handle available */ + QSE_PIO_ECHILD, /**< the child is not valid */ + QSE_PIO_EPIPE, /**< broken pipe */ + QSE_PIO_EILSEQ, /**< illegal sequence */ + QSE_PIO_EICSEQ, /**< incomplete sequence */ + QSE_PIO_EILCHR, /**< illegal character */ + QSE_PIO_ESUBSYS, /**< subsystem error */ + + QSE_PIO_EOTHER /**< unknown error */ }; typedef enum qse_pio_errnum_t qse_pio_errnum_t; @@ -281,15 +288,6 @@ qse_pio_errnum_t qse_pio_geterrnum ( qse_pio_t* pio /**< pio object */ ); -/** - * The qse_pio_geterrmsg() function returns the pointer to a constant string - * describing the last error occurred. - * @return error message - */ -const qse_char_t* qse_pio_geterrmsg ( - qse_pio_t* pio /**< pio object */ -); - /** * The qse_pio_getcmgr() function returns the current character manager. * It returns #QSE_NULL is @a pio is not opened with #QSE_PIO_TEXT. diff --git a/qse/include/qse/cmn/sio.h b/qse/include/qse/cmn/sio.h index 5e9625d5..08ee9227 100644 --- a/qse/include/qse/cmn/sio.h +++ b/qse/include/qse/cmn/sio.h @@ -32,39 +32,52 @@ enum qse_sio_flag_t { - QSE_SIO_IGNOREMBWCERR = QSE_FIO_IGNOREMBWCERR, - QSE_SIO_NOAUTOFLUSH = QSE_FIO_NOAUTOFLUSH, + /* ensure that these enumerators never overlap with + * qse_fio_flag_t enumerators. you can use values between + * (1<<0) and (1<<7) inclusive reserved in qse_fio_flag_t. + * the range is represented by QSE_FIO_RESERVED. */ + QSE_SIO_URI = (1 << 0), + QSE_SIO_IGNOREMBWCERR = (1 << 1), + QSE_SIO_NOAUTOFLUSH = (1 << 2), + /* ensure that the following enumerators are one of + * qse_fio_flags_t enumerators */ QSE_SIO_HANDLE = QSE_FIO_HANDLE, QSE_SIO_TEMPORARY = QSE_FIO_TEMPORARY, QSE_SIO_NOCLOSE = QSE_FIO_NOCLOSE, - QSE_SIO_READ = QSE_FIO_READ, QSE_SIO_WRITE = QSE_FIO_WRITE, QSE_SIO_APPEND = QSE_FIO_APPEND, - QSE_SIO_CREATE = QSE_FIO_CREATE, QSE_SIO_TRUNCATE = QSE_FIO_TRUNCATE, QSE_SIO_EXCLUSIVE = QSE_FIO_EXCLUSIVE, QSE_SIO_SYNC = QSE_FIO_SYNC, QSE_SIO_NOFOLLOW = QSE_FIO_NOFOLLOW, - QSE_SIO_NOSHREAD = QSE_FIO_NOSHREAD, QSE_SIO_NOSHWRITE = QSE_FIO_NOSHWRITE, QSE_SIO_NOSHDELETE = QSE_FIO_NOSHDELETE, - QSE_SIO_RANDOM = QSE_FIO_RANDOM, QSE_SIO_SEQUENTIAL = QSE_FIO_SEQUENTIAL }; -typedef qse_tio_errnum_t qse_sio_errnum_t; -#define QSE_SIO_ENOERR QSE_TIO_ENOERR -#define QSE_SIO_ENOMEM QSE_TIO_ENOMEM -#define QSE_SIO_ENOSPC QSE_TIO_ENOSPC -#define QSE_SIO_EILSEQ QSE_TIO_EILSEQ -#define QSE_SIO_EICSEQ QSE_TIO_EICSEQ -#define QSE_SIO_EILCHR QSE_TIO_EILCHR -#define QSE_SIO_ERRNUM(sio) QSE_TIO_ERRNUM(&((sio)->tio)) +enum qse_sio_errnum_t +{ + QSE_SIO_ENOERR = 0, /**< no error */ + + QSE_SIO_ENOMEM, /**< out of memory */ + QSE_SIO_EINVAL, /**< invalid parameter */ + QSE_SIO_EACCES, /**< access denied */ + QSE_SIO_ENOENT, /**< no such file */ + QSE_SIO_EEXIST, /**< already exist */ + QSE_SIO_EINTR, /**< already exist */ + QSE_SIO_EILSEQ, /**< illegal sequence */ + QSE_SIO_EICSEQ, /**< incomplete sequence */ + QSE_SIO_EILCHR, /**< illegal character */ + QSE_SIO_ESUBSYS, /**< subsystem(system call) error */ + + QSE_SIO_EOTHER /**< other error */ +}; +typedef enum qse_sio_errnum_t qse_sio_errnum_t; typedef qse_fio_off_t qse_sio_pos_t; typedef qse_fio_hnd_t qse_sio_hnd_t; @@ -82,18 +95,60 @@ typedef struct qse_sio_t qse_sio_t; struct qse_sio_t { - QSE_DEFINE_COMMON_FIELDS (tio) - qse_fio_t fio; - qse_tio_t tio; + QSE_DEFINE_COMMON_FIELDS (sio) + qse_sio_errnum_t errnum; - qse_mchar_t inbuf[2048]; - qse_mchar_t outbuf[2048]; + /* + depending on the stream type... FILE, FIFO, TCP, UDP + qse_sio_type_t type; + */ + union + { + qse_fio_t file; + int sck; + } u; + + struct + { + qse_tio_t io; + qse_sio_t* xtn; /* static extension for tio */ + } tio; + + qse_mchar_t inbuf[2048]; + qse_mchar_t outbuf[2048]; #if defined(_WIN32) - int status; + int status; #endif }; +/** 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 @@ -157,6 +212,10 @@ qse_sio_hnd_t qse_sio_gethandle ( qse_sio_t* sio ); +qse_ubi_t qse_sio_gethandleasubi ( + qse_sio_t* sio +); + qse_ssize_t qse_sio_flush ( qse_sio_t* sio ); diff --git a/qse/include/qse/cmn/tio.h b/qse/include/qse/cmn/tio.h index 016611da..4832bf73 100644 --- a/qse/include/qse/cmn/tio.h +++ b/qse/include/qse/cmn/tio.h @@ -33,15 +33,19 @@ enum qse_tio_errnum_t { QSE_TIO_ENOERR = 0, + QSE_TIO_ENOMEM, /* out of memory */ QSE_TIO_EINVAL, /* invalid parameter */ + QSE_TIO_EACCES, /**< access denied */ + QSE_TIO_ENOENT, /**< no such file */ QSE_TIO_ENOSPC, /* no more space */ QSE_TIO_EILSEQ, /* illegal sequence */ QSE_TIO_EICSEQ, /* incomplete sequence */ QSE_TIO_EILCHR, /* illegal character */ QSE_TIO_ENINPF, /* no input function attached */ QSE_TIO_ENOUTF, /* no output function attached */ - QSE_TIO_EIOERR /* I/O error */ + + QSE_TIO_EOTHER /* other error */ }; typedef enum qse_tio_errnum_t qse_tio_errnum_t; @@ -82,8 +86,8 @@ typedef struct qse_tio_t qse_tio_t; * The qse_tio_io_fun_t types define a text I/O handler. */ typedef qse_ssize_t (*qse_tio_io_fun_t) ( + qse_tio_t* tio, qse_tio_cmd_t cmd, - void* arg, void* data, qse_size_t size ); @@ -91,7 +95,6 @@ typedef qse_ssize_t (*qse_tio_io_fun_t) ( struct qse_tio_io_t { qse_tio_io_fun_t fun; - void* arg; struct { qse_size_t capa; @@ -169,14 +172,6 @@ qse_tio_errnum_t qse_tio_geterrnum ( qse_tio_t* tio ); -/** - * The qse_tio_geterrmsg() function translates an error code to a string. - * @return pointer to a constant string describing the last error occurred. - */ -const qse_char_t* qse_tio_geterrmsg ( - qse_tio_t* tio -); - /** * The qse_tio_getcmgr() function returns the character manager. */ @@ -199,7 +194,6 @@ void qse_tio_setcmgr ( int qse_tio_attachin ( qse_tio_t* tio, qse_tio_io_fun_t input, - void* arg, qse_mchar_t* bufptr, qse_size_t bufcapa ); @@ -219,7 +213,6 @@ int qse_tio_detachin ( int qse_tio_attachout ( qse_tio_t* tio, qse_tio_io_fun_t output, - void* arg, qse_mchar_t* bufptr, qse_size_t bufcapa ); diff --git a/qse/include/qse/config.h.in b/qse/include/qse/config.h.in index 1afb7774..452a52e2 100644 --- a/qse/include/qse/config.h.in +++ b/qse/include/qse/config.h.in @@ -70,6 +70,9 @@ /* Define to 1 if you have the `expl' function. */ #undef HAVE_EXPL +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + /* Define to 1 if you have the `fdopendir' function. */ #undef HAVE_FDOPENDIR @@ -279,6 +282,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + /* Define to 1 if you have the `tan' function. */ #undef HAVE_TAN diff --git a/qse/include/qse/net/http.h b/qse/include/qse/net/http.h index c9c34ac7..f60956d7 100644 --- a/qse/include/qse/net/http.h +++ b/qse/include/qse/net/http.h @@ -53,14 +53,52 @@ typedef struct qse_http_version_t qse_http_version_t; */ enum qse_http_method_t { - QSE_HTTP_GET, + QSE_HTTP_OTHER, + + /* rfc 2616 */ QSE_HTTP_HEAD, + QSE_HTTP_GET, QSE_HTTP_POST, QSE_HTTP_PUT, QSE_HTTP_DELETE, - QSE_HTTP_TRACE, QSE_HTTP_OPTIONS, + QSE_HTTP_TRACE, QSE_HTTP_CONNECT + +#if 0 + /* rfc 2518 */ + QSE_HTTP_PROPFIND, + QSE_HTTP_PROPPATCH, + QSE_HTTP_MKCOL, + QSE_HTTP_COPY, + QSE_HTTP_MOVE, + QSE_HTTP_LOCK, + QSE_HTTP_UNLOCK, + + /* rfc 3253 */ + QSE_HTTP_VERSION_CONTROL, + QSE_HTTP_REPORT, + QSE_HTTP_CHECKOUT, + QSE_HTTP_CHECKIN, + QSE_HTTP_UNCHECKOUT, + QSE_HTTP_MKWORKSPACE, + QSE_HTTP_UPDATE, + QSE_HTTP_LABEL, + QSE_HTTP_MERGE, + QSE_HTTP_BASELINE_CONTROL, + QSE_HTTP_MKACTIVITY, + + /* microsoft */ + QSE_HTTP_BPROPFIND, + QSE_HTTP_BPROPPATCH, + QSE_HTTP_BCOPY, + QSE_HTTP_BDELETE, + QSE_HTTP_BMOVE, + QSE_HTTP_NOTIFY, + QSE_HTTP_POLL, + QSE_HTTP_SUBSCRIBE, + QSE_HTTP_UNSUBSCRIBE, +#endif }; typedef enum qse_http_method_t qse_http_method_t; @@ -125,18 +163,16 @@ int qse_comparehttpversions ( const qse_http_version_t* v2 ); -const qse_mchar_t* qse_gethttpmethodname ( +const qse_mchar_t* qse_httpmethodtombs ( qse_http_method_t type ); -int qse_gethttpmethodtype ( - const qse_mchar_t* name, - qse_http_method_t* method +qse_http_method_t qse_mbstohttpmethod ( + const qse_mchar_t* name ); -int qse_gethttpmethodtypefromstr ( - const qse_mcstr_t* name, - qse_http_method_t* type +qse_http_method_t qse_mcstrtohttpmethod ( + const qse_mcstr_t* name ); int qse_parsehttprange ( diff --git a/qse/lib/cmn/fio.c b/qse/lib/cmn/fio.c index 96a12a07..4a91b417 100644 --- a/qse/lib/cmn/fio.c +++ b/qse/lib/cmn/fio.c @@ -20,10 +20,10 @@ #include #include -#include #include #include #include +#include #include "mem.h" #if defined(_WIN32) @@ -39,16 +39,120 @@ # include #else # include "syscall.h" -# include -# include #endif + QSE_IMPLEMENT_COMMON_FUNCTIONS (fio) -static qse_ssize_t fio_input ( - qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); -static qse_ssize_t fio_output ( - qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); +#if defined(_WIN32) +static qse_fio_errnum_t syserr_to_errnum (DWORD e) +{ + + switch (e) + { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_NAME: + return QSE_FIO_EINVAL; + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + return QSE_FIO_ENOENT; + + case ERROR_ACCESS_DENIED: + return QSE_FIO_EACCES; + + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_OUTOFMEMORY: + return QSE_FIO_ENOMEM; + + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + return QSE_FIO_EEXIST; + + default: + return QSE_FIO_ESUBSYS; + } +} +#elif defined(__OS2__) +static qse_fio_errnum_t syserr_to_errnum (APIRET e) +{ + switch (e) + { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_NAME: + return QSE_FIO_EINVAL; + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + return QSE_FIO_ENOENT; + + case ERROR_ACCESS_DENIED: + return QSE_FIO_EACCES; + + case ERROR_NOT_ENOUGH_MEMORY: + return QSE_FIO_ENOMEM; + + case ERROR_ALREADY_EXISTS: + return QSE_FIO_EEXIST; + + default: + return QSE_FIO_ESUBSYS; + } +} +#elif defined(__DOS__) +static qse_fio_errnum_t syserr_to_errnum (int e) +{ + switch (e) + { + case ENOMEM: + return QSE_FIO_ENOMEM; + + case EINVAL: + return QSE_FIO_EINVAL; + + case ENOENT: + return QSE_FIO_ENOENT; + + case EACCES: + return QSE_FIO_EACCES; + + case EEXIST: + return QSE_FIO_EEXIST; + + default: + return QSE_FIO_ESUBSYS; + } +} +#else +static qse_fio_errnum_t syserr_to_errnum (int e) +{ + switch (e) + { + case ENOMEM: + return QSE_FIO_ENOMEM; + + case EINVAL: + return QSE_FIO_EINVAL; + + case ENOENT: + return QSE_FIO_ENOENT; + + case EACCES: + return QSE_FIO_EACCES; + + case EEXIST: + return QSE_FIO_EEXIST; + + case EINTR: + return QSE_FIO_EINTR; + + default: + return QSE_FIO_ESUBSYS; + } +} +#endif qse_fio_t* qse_fio_open ( qse_mmgr_t* mmgr, qse_size_t ext, @@ -108,7 +212,11 @@ int qse_fio_init ( /* The path name template must be at least 4 characters long * excluding the terminating null. this function fails if not */ - if (temp_ptr - path < 4) return -1; + if (temp_ptr - path < 4) + { + fio->errnum = QSE_FIO_EINVAL; + return -1; + } qse_gettime (&now); temp_no += (now & 0xFFFFFFFFlu); @@ -120,7 +228,11 @@ int qse_fio_init ( temp_tries++; /* Fails after 5000 tries. 5000 randomly chosen */ - if (temp_tries > 5000) return -1; + if (temp_tries > 5000) + { + fio->errnum = QSE_FIO_EINVAL; + return -1; + } /* Generate the next random number to use to make a * new path name */ @@ -210,6 +322,7 @@ int qse_fio_init ( if (handle == INVALID_HANDLE_VALUE) { if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; + fio->errnum = syserr_to_errnum(GetLastError()); return -1; } @@ -217,6 +330,7 @@ int qse_fio_init ( #if 0 if (GetFileType(handle) == FILE_TYPE_UNKNOWN) { + fio->errnum = syserr_to_errnum(GetLastError()); CloseHandle (handle); return -1; } @@ -250,10 +364,20 @@ int qse_fio_init ( px = qse_wcstombs (path, &wl, path_mb, &ml); if (px == -2) { + /* the static buffer is too small. + * dynamically allocate a buffer */ path_mb = qse_wcstombsdup (path, mmgr); - if (path_mb == QSE_NULL) return -1; + if (path_mb == QSE_NULL) + { + fio->errnum = QSE_FIO_ENOMEM; + return -1; + } + } + else if (px <= -1) + { + fio->errnum = QSE_FIO_EINVAL; + return -1; } - else if (px <= -1) return -1; #endif zero.ulLo = 0; @@ -329,6 +453,7 @@ int qse_fio_init ( if (ret != NO_ERROR) { if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; + fio->errnum = syserr_to_errnum(ret); return -1; } } @@ -358,9 +483,17 @@ int qse_fio_init ( if (px == -2) { path_mb = qse_wcstombsdup (path, mmgr); - if (path_mb == QSE_NULL) return -1; + if (path_mb == QSE_NULL) + { + fio->errnum = QSE_FIO_ENOMEM; + return -1; + } + } + else if (px <= -1) + { + fio->errnum = QSE_FIO_EINVAL; + return -1; } - else if (px <= -1) return -1; #endif if (flags & QSE_FIO_APPEND) @@ -401,6 +534,7 @@ int qse_fio_init ( if (handle <= -1) { if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; + fio->errnum = syserr_to_errnum (errno); return -1; } } @@ -428,10 +562,20 @@ int qse_fio_init ( px = qse_wcstombs (path, &wl, path_mb, &ml); if (px == -2) { + /* the static buffer is too small. + * allocate a buffer */ path_mb = qse_wcstombsdup (path, mmgr); - if (path_mb == QSE_NULL) return -1; + if (path_mb == QSE_NULL) + { + fio->errnum = QSE_FIO_ENOMEM; + return -1; + } + } + else if (px <= -1) + { + fio->errnum = QSE_FIO_EINVAL; + return -1; } - else if (px <= -1) return -1; #endif /* * rwa -> RDWR | APPEND @@ -481,6 +625,7 @@ int qse_fio_init ( if (handle == -1) { if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; + fio->errnum = syserr_to_errnum (errno); return -1; } @@ -496,50 +641,12 @@ int qse_fio_init ( #endif - if (flags & QSE_FIO_TEXT) - { - qse_tio_t* tio; - int opt = 0; - - if (fio->flags & QSE_FIO_IGNOREMBWCERR) opt |= QSE_TIO_IGNOREMBWCERR; - if (fio->flags & QSE_FIO_NOAUTOFLUSH) opt |= QSE_TIO_NOAUTOFLUSH; - - tio = qse_tio_open (fio->mmgr, 0, opt); - if (tio == QSE_NULL) QSE_THROW_ERR (tio); - - if (qse_tio_attachin (tio, fio_input, fio, QSE_NULL, 4096) <= -1 || - qse_tio_attachout (tio, fio_output, fio, QSE_NULL, 4096) <= -1) - { - qse_tio_close (tio); - QSE_THROW_ERR (tio); - } - - QSE_CATCH_ERR (tio) - { - #if defined(_WIN32) - CloseHandle (handle); - #elif defined(__OS2__) - DosClose (handle); - #elif defined(__DOS__) - close (handle); - #else - QSE_CLOSE (handle); - #endif - return -1; - } - - fio->tio = tio; - } - fio->handle = handle; - return 0; } void qse_fio_fini (qse_fio_t* fio) { - if (fio->tio != QSE_NULL) qse_tio_close (fio->tio); - if (!(fio->flags & QSE_FIO_NOCLOSE)) { #if defined(_WIN32) @@ -554,24 +661,26 @@ void qse_fio_fini (qse_fio_t* fio) } } -qse_cmgr_t* qse_fio_getcmgr (qse_fio_t* fio) -{ - return fio->tio? qse_tio_getcmgr (fio->tio): QSE_NULL; -} - -void qse_fio_setcmgr (qse_fio_t* fio, qse_cmgr_t* cmgr) -{ - if (fio->tio) qse_tio_setcmgr (fio->tio, cmgr); -} - qse_fio_hnd_t qse_fio_gethandle (qse_fio_t* fio) { return fio->handle; } -void qse_fio_sethandle (qse_fio_t* fio, qse_fio_hnd_t handle) +qse_ubi_t qse_fio_gethandleasubi (qse_fio_t* fio) { - fio->handle = handle; + qse_ubi_t handle; + +#if defined(_WIN32) + handle.ptr = fio->handle; +#elif defined(__OS2__) + handle.ul = fio->handle; +#elif defined(__DOS__) + handle.i = fio->handle; +#else + handle.i = fio->handle; +#endif + + return handle; } qse_fio_off_t qse_fio_seek ( @@ -607,6 +716,7 @@ qse_fio_off_t qse_fio_seek ( fio->handle, x.LowPart, &x.HighPart, seek_map[origin]); if (x.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { + fio->errnum = syserr_to_errnum (GetLastError()); return (qse_fio_off_t)-1; } return (qse_fio_off_t)x.QuadPart; @@ -628,7 +738,11 @@ qse_fio_off_t qse_fio_seek ( pos.ulHi = (ULONG)(offset>>32); ret = DosSetFilePtrL (fio->handle, pos, seek_map[origin], &newpos); - if (ret != NO_ERROR) return (qse_fio_off_t)-1; + if (ret != NO_ERROR) + { + fio->errnum = syserr_to_errnum (ret); + return (qse_fio_off_t)-1; + } return ((qse_fio_off_t)pos.ulHi << 32) | pos.ulLo; #elif defined(__DOS__) @@ -657,6 +771,7 @@ qse_fio_off_t qse_fio_seek ( &tmp, seek_map[origin]) == -1) { + fio->errnum = syserr_to_errnum (errno); return (qse_fio_off_t)-1; } @@ -679,7 +794,11 @@ int qse_fio_truncate (qse_fio_t* fio, qse_fio_off_t size) SetEndOfFile(fio->handle) == FALSE) return -1; #endif if (qse_fio_seek (fio, size, QSE_FIO_BEGIN) == (qse_fio_off_t)-1) return -1; - if (SetEndOfFile(fio->handle) == FALSE) return -1; + if (SetEndOfFile(fio->handle) == FALSE) + { + fio->errnum = syserr_to_errnum (GetLastError()); + return -1; + } return 0; #elif defined(__OS2__) @@ -691,18 +810,30 @@ int qse_fio_truncate (qse_fio_t* fio, qse_fio_off_t size) sz.ulHi = (ULONG)(size>>32); ret = DosSetFileSizeL (fio->handle, sz); - return (ret == NO_ERROR)? 0: -1; + if (ret != NO_ERROR) + { + fio->errnum = syserr_to_errnum (ret); + return -1; + + } + return 0; #elif defined(__DOS__) - return chsize (fio->handle, size); + int n; + n = chsize (fio->handle, size); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #else - return QSE_FTRUNCATE (fio->handle, size); + int n; + n = QSE_FTRUNCATE (fio->handle, size); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #endif } -static qse_ssize_t fio_read (qse_fio_t* fio, void* buf, qse_size_t size) +qse_ssize_t qse_fio_read (qse_fio_t* fio, void* buf, qse_size_t size) { #if defined(_WIN32) @@ -710,41 +841,48 @@ static qse_ssize_t fio_read (qse_fio_t* fio, void* buf, qse_size_t size) 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 (fio->handle, - buf, (DWORD)size, &count, QSE_NULL) == FALSE) return -1; + buf, (DWORD)size, &count, QSE_NULL) == FALSE) + { + fio->errnum = syserr_to_errnum (GetLastError()); + return -1; + } return (qse_ssize_t)count; #elif defined(__OS2__) + APIRET ret; ULONG count; if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG))) size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG); - if (DosRead (fio->handle, - buf, (ULONG)size, &count) != NO_ERROR) return -1; + ret = DosRead (fio->handle, buf, (ULONG)size, &count); + if (ret != NO_ERROR) + { + fio->errnum = syserr_to_errnum (ret); + return -1; + } return (qse_ssize_t)count; #elif defined(__DOS__) - 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); - return read (fio->handle, buf, size); + int n; + 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 (fio->handle, buf, size); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #else + ssize_t n; 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); - return QSE_READ (fio->handle, buf, size); + n = QSE_READ (fio->handle, buf, size); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #endif } -qse_ssize_t qse_fio_read (qse_fio_t* fio, void* buf, qse_size_t size) -{ - if (fio->tio == QSE_NULL) - return fio_read (fio, buf, size); - else - return qse_tio_read (fio->tio, buf, size); -} - -static qse_ssize_t fio_write (qse_fio_t* fio, const void* data, qse_size_t size) +qse_ssize_t qse_fio_write (qse_fio_t* fio, const void* data, qse_size_t size) { #if defined(_WIN32) @@ -752,37 +890,18 @@ static qse_ssize_t fio_write (qse_fio_t* fio, const void* data, qse_size_t size) 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 (fio->handle, - data, (DWORD)size, &count, QSE_NULL) == FALSE) return -1; + data, (DWORD)size, &count, QSE_NULL) == FALSE) + { + fio->errnum = syserr_to_errnum (GetLastError()); + return -1; + } return (qse_ssize_t)count; #elif defined(__OS2__) + APIRET ret; ULONG count; - if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG))) - size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG); - if (DosWrite(fio->handle, - (PVOID)data, (ULONG)size, &count) != NO_ERROR) return -1; - return (qse_ssize_t)count; - -#elif defined(__DOS__) - - 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); - return write (fio->handle, data, size); - -#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); - return QSE_WRITE (fio->handle, data, size); - -#endif -} - -qse_ssize_t qse_fio_write (qse_fio_t* fio, const void* data, qse_size_t size) -{ -#if defined(__OS2__) if (fio->flags & QSE_FIO_APPEND) { /* i do this on a best-effort basis */ @@ -791,24 +910,42 @@ qse_ssize_t qse_fio_write (qse_fio_t* fio, const void* data, qse_size_t size) pos.ulHi = (ULONG)0; DosSetFilePtrL (fio->handle, pos, FILE_END, &newpos); } + + if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG))) + size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG); + ret = DosWrite(fio->handle, + (PVOID)data, (ULONG)size, &count); + if (ret != NO_ERROR) + { + fio->errnum = syserr_to_errnum (ret); + return -1; + } + return (qse_ssize_t)count; + +#elif defined(__DOS__) + + int n; + 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 (fio->handle, data, size); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; + +#else + + ssize_t n; + 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); + n = QSE_WRITE (fio->handle, data, size); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #endif - - if (fio->tio == QSE_NULL) - return fio_write (fio, data, size); - else - return qse_tio_write (fio->tio, data, size); -} - -qse_ssize_t qse_fio_flush (qse_fio_t* fio) -{ - if (fio->tio == QSE_NULL) return 0; - return qse_tio_flush (fio->tio); } #if defined(_WIN32) static int get_devname_from_handle ( - HANDLE handle, qse_char_t* buf, qse_size_t len) + qse_fio_t* fio, qse_char_t* buf, qse_size_t len) { HANDLE map = NULL; void* mem = NULL; @@ -816,19 +953,24 @@ static int get_devname_from_handle ( /* create a file mapping object */ map = CreateFileMapping ( - handle, + fio->handle, NULL, PAGE_READONLY, 0, 1, NULL ); - if (map == NULL) return -1; + if (map == NULL) + { + mem = MapViewOfFile (map, FILE_MAP_READ, 0, 0, 1); + return -1; + } /* create a file mapping to get the file name. */ mem = MapViewOfFile (map, FILE_MAP_READ, 0, 0, 1); if (mem == NULL) { + fio->errnum = syserr_to_errnum (GetLastError()); CloseHandle (map); return -1; } @@ -836,6 +978,7 @@ static int get_devname_from_handle ( olen = GetMappedFileName (GetCurrentProcess(), mem, buf, len); if (olen == 0) { + fio->errnum = syserr_to_errnum (GetLastError()); UnmapViewOfFile (mem); CloseHandle (map); return -1; @@ -847,9 +990,9 @@ static int get_devname_from_handle ( } static int get_volname_from_handle ( - HANDLE handle, qse_char_t* buf, qse_size_t len) + qse_fio_t* fio, qse_char_t* buf, qse_size_t len) { - if (get_devname_from_handle (handle, buf, len) == -1) return -1; + if (get_devname_from_handle (fio, buf, len) == -1) return -1; if (qse_strcasebeg (buf, QSE_T("\\Device\\LanmanRedirector\\"))) { @@ -866,6 +1009,7 @@ static int get_volname_from_handle ( if (n == 0 /* error */ || n > QSE_COUNTOF(drives) /* buffer small */) { + fio->errnum = syserr_to_errnum (GetLastError()); return -1; } @@ -911,25 +1055,41 @@ int qse_fio_chmod (qse_fio_t* fio, int mode) * if GENERIC_READ is not set in CreateFile, CreateFileMapping fails. * so if this fio is opened without QSE_FIO_READ, this function fails. */ - if (get_volname_from_handle ( - fio->handle, name, QSE_COUNTOF(name)) == -1) return -1; + if (get_volname_from_handle (fio, name, QSE_COUNTOF(name)) == -1) return -1; if (!(mode & QSE_FIO_WUSR)) flags = FILE_ATTRIBUTE_READONLY; - return (SetFileAttributes (name, flags) == FALSE)? -1: 0; + if (SetFileAttributes (name, flags) == FALSE) + { + fio->errnum = syserr_to_errnum (GetLastError()); + return -1; + } + return 0; #elif defined(__OS2__) + APIRET n; int flags = FILE_NORMAL; FILESTATUS3L stat; ULONG size = QSE_SIZEOF(stat); - if (DosQueryFileInfo (fio->handle, - FIL_STANDARDL, &stat, size) != NO_ERROR) return -1; + n = DosQueryFileInfo (fio->handle, FIL_STANDARDL, &stat, size); + if (n != NO_ERROR) + { + fio->errnum = syserr_to_errnum (n); + return -1; + } if (!(mode & QSE_FIO_WUSR)) flags = FILE_READONLY; stat.attrFile = flags; - return (DosSetFileInfo (fio->handle, FIL_STANDARDL, &stat, size) != NO_ERROR)? -1: 0; + n = DosSetFileInfo (fio->handle, FIL_STANDARDL, &stat, size); + if (n != NO_ERROR) + { + fio->errnum = syserr_to_errnum (n); + return -1; + } + + return 0; #elif defined(__DOS__) @@ -941,10 +1101,14 @@ int qse_fio_chmod (qse_fio_t* fio, int mode) /* TODO: fchmod not available. find a way to do this return fchmod (fio->handle, permission); */ + fio->errnum = QSE_FIO_ENOIMPL; return -1; #else - return QSE_FCHMOD (fio->handle, mode); + int n; + n = QSE_FCHMOD (fio->handle, mode); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #endif } @@ -952,20 +1116,37 @@ int qse_fio_sync (qse_fio_t* fio) { #if defined(_WIN32) - return (FlushFileBuffers (fio->handle) == FALSE)? -1: 0; + if (FlushFileBuffers (fio->handle) == FALSE) + { + fio->errnum = syserr_to_errnum (GetLastError()); + return -1; + } + return 0; #elif defined(__OS2__) - return (DosResetBuffer (fio->handle) == NO_ERROR)? 0: -1; + APIRET n; + n = DosResetBuffer (fio->handle); + if (n != NO_ERROR) + { + fio->errnum = syserr_to_errnum (n); + return -1; + } + return 0; #elif defined(__DOS__) - return fsync (fio->handle); + int n; + n = fsync (fio->handle); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #else - return QSE_FSYNC (fio->handle); - + int n; + n = QSE_FSYNC (fio->handle); + if (n <= -1) fio->errnum = syserr_to_errnum (errno); + return n; #endif } @@ -976,6 +1157,7 @@ int qse_fio_lock (qse_fio_t* fio, qse_fio_lck_t* lck, int flags) * fl.l_type = F_RDLCK, F_WRLCK; * QSE_FCNTL (fio->handle, F_SETLK, &fl); */ + fio->errnum = QSE_FIO_ENOIMPL; return -1; } @@ -986,31 +1168,10 @@ int qse_fio_unlock (qse_fio_t* fio, qse_fio_lck_t* lck, int flags) * fl.l_type = F_UNLCK; * QSE_FCNTL (fio->handle, F_SETLK, &fl); */ + fio->errnum = QSE_FIO_ENOIMPL; return -1; } -static qse_ssize_t fio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size) -{ - qse_fio_t* fio = (qse_fio_t*)arg; - QSE_ASSERT (fio != QSE_NULL); - if (cmd == QSE_TIO_DATA) return fio_read (fio, buf, size); - - /* take no actions for OPEN and CLOSE as they are handled - * by fio */ - return 0; -} - -static qse_ssize_t fio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size) -{ - qse_fio_t* fio = (qse_fio_t*)arg; - QSE_ASSERT (fio != QSE_NULL); - if (cmd == QSE_TIO_DATA) return fio_write (fio, buf, size); - - /* take no actions for OPEN and CLOSE as they are handled - * by fio */ - return 0; -} - int qse_getstdfiohandle (qse_fio_std_t std, qse_fio_hnd_t* hnd) { #if defined(_WIN32) diff --git a/qse/lib/cmn/pio.c b/qse/lib/cmn/pio.c index dde8f3c4..026abd84 100644 --- a/qse/lib/cmn/pio.c +++ b/qse/lib/cmn/pio.c @@ -34,8 +34,6 @@ # include #else # include "syscall.h" -# include -# include # if defined(HAVE_SPAWN_H) # include # endif @@ -43,8 +41,154 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (pio) -static qse_ssize_t pio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); -static qse_ssize_t pio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); +static qse_ssize_t pio_input ( + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size); +static qse_ssize_t pio_output ( + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size); + +#if defined(_WIN32) +static qse_pio_errnum_t syserr_to_errnum (DWORD e) +{ + + switch (e) + { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_NAME: + return QSE_PIO_EINVAL; + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + return QSE_PIO_ENOENT; + + case ERROR_ACCESS_DENIED: + return QSE_PIO_EACCES; + + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_OUTOFMEMORY: + return QSE_PIO_ENOMEM; + + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + return QSE_PIO_EEXIST; + + case ERROR_BROKEN_PIPE: + return QSE_PIO_EPIPE; + + default: + return QSE_PIO_ESUBSYS; + } +} +#elif defined(__OS2__) +static qse_pio_errnum_t syserr_to_errnum (APIRET e) +{ + switch (e) + { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_NAME: + return QSE_PIO_EINVAL; + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + return QSE_PIO_ENOENT; + + case ERROR_ACCESS_DENIED: + return QSE_PIO_EACCES; + + case ERROR_NOT_ENOUGH_MEMORY: + return QSE_PIO_ENOMEM; + + case ERROR_ALREADY_EXISTS: + return QSE_PIO_EEXIST; + + case ERROR_BROKEN_PIPE: + return QSE_PIO_EPIPE; + + default: + return QSE_PIO_ESUBSYS; + } +} +#elif defined(__DOS__) +static qse_pio_errnum_t syserr_to_errnum (int e) +{ + switch (e) + { + case ENOMEM: + return QSE_PIO_ENOMEM; + + case EINVAL: + return QSE_PIO_EINVAL; + + case ENOENT: + return QSE_PIO_ENOENT; + + case EACCES: + return QSE_PIO_EACCES; + + case EEXIST: + return QSE_PIO_EEXIST; + + default: + return QSE_PIO_ESUBSYS; + } +} +#else +static qse_pio_errnum_t syserr_to_errnum (int e) +{ + switch (e) + { + case ENOMEM: + return QSE_PIO_ENOMEM; + + case EINVAL: + return QSE_PIO_EINVAL; + + case ENOENT: + return QSE_PIO_ENOENT; + + case EACCES: + return QSE_PIO_EACCES; + + case EEXIST: + return QSE_PIO_EEXIST; + + case EINTR: + return QSE_PIO_EINTR; + + case EPIPE: + return QSE_PIO_EPIPE; + + default: + return QSE_PIO_ESUBSYS; + } +} +#endif + +static qse_pio_errnum_t tio_errnum_to_pio_errnum (qse_tio_t* tio) +{ + /* i only translate error codes that's relevant + * to pio. all other errors becom QSE_PIO_EOTHER */ + switch (tio->errnum) + { + case QSE_TIO_ENOMEM: + return QSE_PIO_ENOMEM; + case QSE_TIO_EINVAL: + return QSE_PIO_EINVAL; + case QSE_TIO_ENOENT: + return QSE_PIO_ENOENT; + case QSE_TIO_EACCES: + return QSE_PIO_EACCES; + case QSE_TIO_EILSEQ: + return QSE_PIO_EILSEQ; + case QSE_TIO_EICSEQ: + return QSE_PIO_EICSEQ; + case QSE_TIO_EILCHR: + return QSE_PIO_EILCHR; + default: + return QSE_PIO_EOTHER; + } +} qse_pio_t* qse_pio_open ( qse_mmgr_t* mmgr, qse_size_t ext, @@ -294,17 +438,14 @@ static int assert_executable (qse_pio_t* pio, const qse_mchar_t* path) if (QSE_ACCESS(path, X_OK) <= -1) { - if (errno == EACCES) pio->errnum = QSE_PIO_EACCES; - else if (errno == ENOENT) pio->errnum = QSE_PIO_ENOENT; - else if (errno == ENOMEM) pio->errnum = QSE_PIO_ENOMEM; + pio->errnum = syserr_to_errnum (errno); return -1; } - if (QSE_LSTAT(path, &st) <= -1) + /*if (QSE_LSTAT(path, &st) <= -1)*/ + if (QSE_STAT(path, &st) <= -1) { - if (errno == EACCES) pio->errnum = QSE_PIO_EACCES; - else if (errno == ENOENT) pio->errnum = QSE_PIO_ENOENT; - else if (errno == ENOMEM) pio->errnum = QSE_PIO_ENOMEM; + pio->errnum = syserr_to_errnum (errno); return -1; } @@ -1063,7 +1204,11 @@ int qse_pio_init ( posix_spawn_file_actions_destroy (&fa); fa_inited = 0; } - if (spawn_ret != 0) goto oops; + if (spawn_ret != 0) + { + pio->errnum = syserr_to_errnum (errno); + goto oops; + } pio->child = pid; if (flags & QSE_PIO_WRITEIN) @@ -1293,20 +1438,25 @@ int qse_pio_init ( { int r; - tio[i] = qse_tio_open (pio->mmgr, 0, topt); + tio[i] = qse_tio_open (pio->mmgr, QSE_SIZEOF(&pio->pin[i]), topt); if (tio[i] == QSE_NULL) { pio->errnum = QSE_PIO_ENOMEM; goto oops; } + + /**(qse_pio_pin_t**)qse_tio_getxtn(tio[i]) = &pio->pin[i]; */ + *(qse_pio_pin_t**)QSE_XTN(tio[i]) = &pio->pin[i]; r = (i == QSE_PIO_IN)? - qse_tio_attachout ( - tio[i], pio_output, &pio->pin[i], QSE_NULL, 4096): - qse_tio_attachin ( - tio[i], pio_input, &pio->pin[i], QSE_NULL, 4096); - - if (r <= -1) goto oops; + qse_tio_attachout (tio[i], pio_output, QSE_NULL, 4096): + qse_tio_attachin (tio[i], pio_input, QSE_NULL, 4096); + if (r <= -1) + { + if (pio->errnum == QSE_PIO_ENOERR) + pio->errnum = tio_errnum_to_pio_errnum (tio[i]); + goto oops; + } pio->pin[i].tio = tio[i]; } @@ -1402,28 +1552,6 @@ qse_pio_errnum_t qse_pio_geterrnum (qse_pio_t* pio) return pio->errnum; } -const qse_char_t* qse_pio_geterrmsg (qse_pio_t* pio) -{ - static const qse_char_t* __errstr[] = - { - QSE_T("no error"), - QSE_T("out of memory"), - QSE_T("invalid parameter"), - QSE_T("no handle available"), - QSE_T("child process not valid"), - QSE_T("interruped"), - QSE_T("broken pipe"), - QSE_T("access denied"), - QSE_T("no such file"), - QSE_T("systeam call error"), - QSE_T("unknown error") - }; - - return __errstr[ - (pio->errnum < 0 || pio->errnum >= QSE_COUNTOF(__errstr))? - QSE_COUNTOF(__errstr) - 1: pio->errnum]; -} - qse_cmgr_t* qse_pio_getcmgr (qse_pio_t* pio, qse_pio_hid_t hid) { return pio->pin[hid].tio? @@ -1493,7 +1621,7 @@ static qse_ssize_t pio_read ( /* ReadFile receives ERROR_BROKEN_PIPE when the write end * is closed in the child process */ if (GetLastError() == ERROR_BROKEN_PIPE) return 0; - pio->errnum = QSE_PIO_ESUBSYS; + pio->errnum = syserr_to_errnum(GetLastError()); return -1; } return (qse_ssize_t)count; @@ -1507,7 +1635,7 @@ static qse_ssize_t pio_read ( if (rc != NO_ERROR) { if (rc == ERROR_BROKEN_PIPE) return 0; /* TODO: check this */ - pio->errnum = QSE_PIO_ESUBSYS; + pio->errnum = syserr_to_errnum(rc); return -1; } return (qse_ssize_t)count; @@ -1519,7 +1647,7 @@ static qse_ssize_t pio_read ( size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int); n = read (hnd, buf, size); - if (n == -1) pio->errnum = QSE_PIO_ESUBSYS; + if (n <= -1) pio->errnum = syserr_to_errnum(errno); return n; #else @@ -1529,7 +1657,7 @@ static qse_ssize_t pio_read ( reread: n = QSE_READ (hnd, buf, size); - if (n == -1) + if (n <= -1) { if (errno == EINTR) { @@ -1537,13 +1665,9 @@ reread: pio->errnum = QSE_PIO_EINTR; else goto reread; } - else if (errno == EPIPE) - { - pio->errnum = QSE_PIO_EPIPE; - } else { - pio->errnum = QSE_PIO_ESUBSYS; + pio->errnum = syserr_to_errnum (errno); } } @@ -1557,7 +1681,16 @@ qse_ssize_t qse_pio_read ( if (pio->pin[hid].tio == QSE_NULL) return pio_read (pio, buf, size, pio->pin[hid].handle); else - return qse_tio_read (pio->pin[hid].tio, buf, size); + { + qse_ssize_t n; + + pio->errnum = QSE_PIO_ENOERR; + n = qse_tio_read (pio->pin[hid].tio, buf, size); + if (n <= -1 && pio->errnum == QSE_PIO_ENOERR) + pio->errnum = tio_errnum_to_pio_errnum (pio->pin[hid].tio); + + return n; + } } static qse_ssize_t pio_write ( @@ -1578,7 +1711,7 @@ static qse_ssize_t pio_write ( { /* the stream is already closed */ pio->errnum = QSE_PIO_ENOHND; - return -1; + return (qse_ssize_t)-1; } #if defined(_WIN32) @@ -1588,8 +1721,7 @@ static qse_ssize_t pio_write ( if (WriteFile (hnd, data, (DWORD)size, &count, QSE_NULL) == FALSE) { - pio->errnum = (GetLastError() == ERROR_BROKEN_PIPE)? - QSE_PIO_EPIPE: QSE_PIO_ESUBSYS; + pio->errnum = syserr_to_errnum(GetLastError()); return -1; } return (qse_ssize_t)count; @@ -1602,8 +1734,7 @@ static qse_ssize_t pio_write ( rc = DosWrite (hnd, (PVOID)data, (ULONG)size, &count); if (rc != NO_ERROR) { - pio->errnum = (rc == ERROR_BROKEN_PIPE)? - QSE_PIO_EPIPE: QSE_PIO_ESUBSYS; /* TODO: check this */ + pio->errnum = syserr_to_errnum(rc); return -1; } return (qse_ssize_t)count; @@ -1614,7 +1745,7 @@ static qse_ssize_t pio_write ( size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int); n = write (hnd, data, size); - if (n == -1) pio->errnum = QSE_PIO_ESUBSYS; + if (n <= -1) pio->errnum = syserro_to_errnum (errno); return n; #else @@ -1624,7 +1755,7 @@ static qse_ssize_t pio_write ( rewrite: n = QSE_WRITE (hnd, data, size); - if (n == -1) + if (n <= -1) { if (errno == EINTR) { @@ -1632,13 +1763,9 @@ rewrite: pio->errnum = QSE_PIO_EINTR; else goto rewrite; } - else if (errno == EPIPE) - { - pio->errnum = QSE_PIO_EPIPE; - } else { - pio->errnum = QSE_PIO_ESUBSYS; + pio->errnum = syserr_to_errnum (errno); } } return n; @@ -1653,13 +1780,30 @@ qse_ssize_t qse_pio_write ( if (pio->pin[hid].tio == QSE_NULL) return pio_write (pio, data, size, pio->pin[hid].handle); else - return qse_tio_write (pio->pin[hid].tio, data, size); + { + qse_ssize_t n; + + pio->errnum = QSE_PIO_ENOERR; + n = qse_tio_write (pio->pin[hid].tio, data, size); + if (n <= -1 && pio->errnum == QSE_PIO_ENOERR) + pio->errnum = tio_errnum_to_pio_errnum (pio->pin[hid].tio); + + return n; + } } qse_ssize_t qse_pio_flush (qse_pio_t* pio, qse_pio_hid_t hid) { + qse_ssize_t n; + if (pio->pin[hid].tio == QSE_NULL) return 0; - return qse_tio_flush (pio->pin[hid].tio); + + pio->errnum = QSE_PIO_ENOERR; + n = qse_tio_flush (pio->pin[hid].tio); + if (n <= -1 && pio->errnum == QSE_PIO_ENOERR) + pio->errnum = tio_errnum_to_pio_errnum (pio->pin[hid].tio); + + return n; } void qse_pio_end (qse_pio_t* pio, qse_pio_hid_t hid) @@ -1815,7 +1959,7 @@ int qse_pio_wait (qse_pio_t* pio) pio->errnum = QSE_PIO_EINTR; else continue; } - else pio->errnum = QSE_PIO_ESUBSYS; + else pio->errnum = syserr_to_errnum (errno); break; } @@ -1910,12 +2054,13 @@ int qse_pio_kill (qse_pio_t* pio) } static qse_ssize_t pio_input ( - qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size) + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size) { - qse_pio_pin_t* pin = (qse_pio_pin_t*)arg; - QSE_ASSERT (pin != QSE_NULL); if (cmd == QSE_TIO_DATA) { + /*qse_pio_pin_t* pin = (qse_pio_pin_t*)qse_tio_getxtn(tio);*/ + qse_pio_pin_t* pin = *(qse_pio_pin_t**)QSE_XTN(tio); + QSE_ASSERT (pin != QSE_NULL); QSE_ASSERT (pin->self != QSE_NULL); return pio_read (pin->self, buf, size, pin->handle); } @@ -1926,12 +2071,13 @@ static qse_ssize_t pio_input ( } static qse_ssize_t pio_output ( - qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size) + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size) { - qse_pio_pin_t* pin = (qse_pio_pin_t*)arg; - QSE_ASSERT (pin != QSE_NULL); if (cmd == QSE_TIO_DATA) { + /*qse_pio_pin_t* pin = (qse_pio_pin_t*)qse_tio_getxtn(tio);*/ + qse_pio_pin_t* pin = *(qse_pio_pin_t**)QSE_XTN(tio); + QSE_ASSERT (pin != QSE_NULL); QSE_ASSERT (pin->self != QSE_NULL); return pio_write (pin->self, buf, size, pin->handle); } diff --git a/qse/lib/cmn/sio.c b/qse/lib/cmn/sio.c index e5fbf22a..2dd50bba 100644 --- a/qse/lib/cmn/sio.c +++ b/qse/lib/cmn/sio.c @@ -21,13 +21,73 @@ #include #include "mem.h" -static qse_ssize_t __sio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); -static qse_ssize_t __sio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); - #if defined(_WIN32) # include /* for the UGLY hack */ +#elif defined(__OS2__) + /* nothing */ +#elif defined(__DOS__) + /* nothing */ +#else +# include "syscall.h" #endif +static qse_ssize_t file_input ( + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size); +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) +{ +/* TODO: finish this after adding fio->errnum */ + switch (fio->errnum) + { + case QSE_FIO_ENOMEM: + return QSE_SIO_ENOMEM; + case QSE_FIO_EINVAL: + return QSE_SIO_EINVAL; + case QSE_FIO_EACCES: + return QSE_SIO_EACCES; + case QSE_FIO_ENOENT: + return QSE_SIO_ENOENT; + case QSE_FIO_EEXIST: + return QSE_SIO_EEXIST; + case QSE_FIO_EINTR: + return QSE_SIO_EINTR; + case QSE_FIO_ESUBSYS: + return QSE_SIO_ESUBSYS; + default: + return QSE_SIO_EOTHER; + } +} + +static qse_sio_errnum_t tio_errnum_to_sio_errnum (qse_tio_t* tio) +{ + switch (tio->errnum) + { + case QSE_TIO_ENOMEM: + return QSE_SIO_ENOMEM; + case QSE_TIO_EINVAL: + return QSE_SIO_EINVAL; + case QSE_TIO_EACCES: + return QSE_SIO_EACCES; + case QSE_TIO_ENOENT: + return QSE_SIO_ENOENT; + case QSE_TIO_EILSEQ: + return QSE_SIO_EILSEQ; + case QSE_TIO_EICSEQ: + return QSE_SIO_EICSEQ; + case QSE_TIO_EILCHR: + return QSE_SIO_EILCHR; + default: + return QSE_SIO_EOTHER; + } +} + qse_sio_t* qse_sio_open ( qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_char_t* file, int flags) { @@ -84,27 +144,38 @@ int qse_sio_init ( mode = QSE_FIO_RUSR | QSE_FIO_WUSR | QSE_FIO_RGRP | QSE_FIO_ROTH; - /* sio flags redefines most fio flags. fio can be opened in the - * text mode. that way, fio is also buffered. since sio performs - * its own buffering, i don't want a caller to specify text mode - * flags accidentally. i mask off those bits here to avoid mishap. */ - if (qse_fio_init (&sio->fio, mmgr, file, - (flags & ~(QSE_FIO_TEXT|QSE_FIO_NOAUTOFLUSH)), mode) <= -1) return -1; + /* sio flag enumerators redefines most fio flag enumerators and + * compose a superset of fio flag enumerators. when a user calls + * 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, + (flags & ~QSE_FIO_RESERVED), mode) <= -1) + { + sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file); + return -1; + } if (flags & QSE_SIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR; if (flags & QSE_SIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH; - if (qse_tio_init(&sio->tio, mmgr, topt) <= -1) + if (qse_tio_init(&sio->tio.io, mmgr, topt) <= -1) { - qse_fio_fini (&sio->fio); + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + qse_fio_fini (&sio->u.file); return -1; } + /* store the back-reference to sio in the extension area.*/ + QSE_ASSERT (QSE_XTN(&sio->tio.io) == &sio->tio.xtn); + *(qse_sio_t**)QSE_XTN(&sio->tio.io) = sio; - if (qse_tio_attachin (&sio->tio, __sio_input, sio, sio->inbuf, QSE_COUNTOF(sio->inbuf)) <= -1 || - qse_tio_attachout (&sio->tio, __sio_output, sio, sio->outbuf, QSE_COUNTOF(sio->outbuf)) <= -1) + if (qse_tio_attachin (&sio->tio.io, file_input, sio->inbuf, QSE_COUNTOF(sio->inbuf)) <= -1 || + qse_tio_attachout (&sio->tio.io, file_output, sio->outbuf, QSE_COUNTOF(sio->outbuf)) <= -1) { - qse_tio_fini (&sio->tio); - qse_fio_fini (&sio->fio); + 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); return -1; } @@ -136,49 +207,74 @@ 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); - qse_fio_fini (&sio->fio); + qse_tio_fini (&sio->tio.io); + qse_fio_fini (&sio->u.file); } qse_cmgr_t* qse_sio_getcmgr (qse_sio_t* sio) { - return qse_tio_getcmgr (&sio->tio); + return qse_tio_getcmgr (&sio->tio.io); } void qse_sio_setcmgr (qse_sio_t* sio, qse_cmgr_t* cmgr) { - qse_tio_setcmgr (&sio->tio, cmgr); + qse_tio_setcmgr (&sio->tio.io, cmgr); } qse_sio_errnum_t qse_sio_geterrnum (qse_sio_t* sio) { - return QSE_TIO_ERRNUM(&sio->tio); + return sio->errnum; } qse_sio_hnd_t qse_sio_gethandle (qse_sio_t* sio) { - /*return qse_fio_gethandle (&sio->fio);*/ - return QSE_FIO_HANDLE(&sio->fio); + /*return qse_fio_gethandle (&sio->u.file);*/ + return QSE_FIO_HANDLE(&sio->u.file); +} + +qse_ubi_t qse_sio_gethandleasubi (qse_sio_t* sio) +{ + return qse_fio_gethandleasubi (&sio->u.file); } qse_ssize_t qse_sio_flush (qse_sio_t* sio) { - return qse_tio_flush (&sio->tio); + qse_ssize_t n; + + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_flush (&sio->tio.io); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return n; } void qse_sio_purge (qse_sio_t* sio) { - qse_tio_purge (&sio->tio); + qse_tio_purge (&sio->tio.io); } qse_ssize_t qse_sio_getmb (qse_sio_t* sio, qse_mchar_t* c) { - return qse_tio_readmbs (&sio->tio, c, 1); + qse_ssize_t n; + + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_readmbs (&sio->tio.io, c, 1); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + + return n; } qse_ssize_t qse_sio_getwc (qse_sio_t* sio, qse_wchar_t* c) { - return qse_tio_readwcs (&sio->tio, c, 1); + qse_ssize_t n; + + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_readwcs (&sio->tio.io, c, 1); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + + return n; } qse_ssize_t qse_sio_getmbs ( @@ -193,9 +289,14 @@ qse_ssize_t qse_sio_getmbs ( * so I don't implement any hack here */ #endif - n = qse_tio_readmbs (&sio->tio, buf, size - 1); - - if (n <= -1) return -1; + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_readmbs (&sio->tio.io, buf, size - 1); + if (n <= -1) + { + if (sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return -1; + } buf[n] = QSE_MT('\0'); return n; } @@ -203,12 +304,17 @@ qse_ssize_t qse_sio_getmbs ( qse_ssize_t qse_sio_getmbsn ( qse_sio_t* sio, qse_mchar_t* buf, qse_size_t size) { + qse_ssize_t n; #if defined(_WIN32) /* Using ReadConsoleA() didn't help at all. * so I don't implement any hack here */ #endif - return qse_tio_readmbs (&sio->tio, buf, size); + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_readmbs (&sio->tio.io, buf, size); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return n; } qse_ssize_t qse_sio_getwcs ( @@ -223,9 +329,14 @@ qse_ssize_t qse_sio_getwcs ( * so I don't implement any hack here */ #endif - n = qse_tio_readwcs (&sio->tio, buf, size - 1); - - if (n <= -1) return -1; + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_readwcs (&sio->tio.io, buf, size - 1); + if (n <= -1) + { + if (sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return -1; + } buf[n] = QSE_WT('\0'); return n; } @@ -233,55 +344,98 @@ qse_ssize_t qse_sio_getwcs ( qse_ssize_t qse_sio_getwcsn ( qse_sio_t* sio, qse_wchar_t* buf, qse_size_t size) { + qse_ssize_t n; + #if defined(_WIN32) /* Using ReadConsoleW() didn't help at all. * so I don't implement any hack here */ #endif - return qse_tio_readwcs (&sio->tio, buf, size); + + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_readwcs (&sio->tio.io, buf, size); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + + return n; } qse_ssize_t qse_sio_putmb (qse_sio_t* sio, qse_mchar_t c) { - return qse_tio_writembs (&sio->tio, &c, 1); + qse_ssize_t n; + + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_writembs (&sio->tio.io, &c, 1); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + + return n; } qse_ssize_t qse_sio_putwc (qse_sio_t* sio, qse_wchar_t c) { - return qse_tio_writewcs (&sio->tio, &c, 1); + qse_ssize_t n; + + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_writewcs (&sio->tio.io, &c, 1); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + + return n; } qse_ssize_t qse_sio_putmbs (qse_sio_t* sio, const qse_mchar_t* str) { + qse_ssize_t n; + #if defined(_WIN32) /* Using WriteConsoleA() didn't help at all. * so I don't implement any hack here */ #endif - return qse_tio_writembs (&sio->tio, str, (qse_size_t)-1); + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_writembs (&sio->tio.io, str, (qse_size_t)-1); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + + return n; } qse_ssize_t qse_sio_putmbsn ( qse_sio_t* sio, const qse_mchar_t* str, qse_size_t size) { + qse_ssize_t n; + #if defined(_WIN32) /* Using WriteConsoleA() didn't help at all. * so I don't implement any hack here */ #endif - return qse_tio_writembs (&sio->tio, str, size); + sio->errnum = QSE_SIO_ENOERR; + n = qse_tio_writembs (&sio->tio.io, str, size); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + + return n; } qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str) { + qse_ssize_t n; + + sio->errnum = QSE_SIO_ENOERR; + #if defined(_WIN32) /* DAMN UGLY: See comment in qse_sio_putwcsn() */ if (sio->status) { DWORD mode; - if (GetConsoleMode (sio->fio.handle, &mode) == FALSE) + if (GetConsoleMode (sio->u.file.handle, &mode) == FALSE) { - return qse_tio_writewcs (&sio->tio, str, (qse_size_t)-1); + n = qse_tio_writewcs (&sio->tio.io, str, (qse_size_t)-1); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return n; } else { @@ -291,8 +445,12 @@ 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->fio.handle, cur, left, - &count, QSE_NULL) == FALSE) return -1; + sio->u.file.handle, cur, left, + &count, QSE_NULL) == FALSE) + { + sio->errnum = QSE_SIO_EOTHER; + return -1; + } if (count == 0) break; } return cur - str; @@ -300,12 +458,19 @@ qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str) } #endif - return qse_tio_writewcs (&sio->tio, str, (qse_size_t)-1); + n = qse_tio_writewcs (&sio->tio.io, str, (qse_size_t)-1); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return n; } qse_ssize_t qse_sio_putwcsn ( qse_sio_t* sio, const qse_wchar_t* str, qse_size_t size) { + qse_ssize_t n; + + sio->errnum = QSE_SIO_ENOERR; + #if defined(_WIN32) /* DAMN UGLY: * WriteFile returns wrong number of bytes written if it is @@ -323,9 +488,12 @@ qse_ssize_t qse_sio_putwcsn ( { DWORD mode; - if (GetConsoleMode (sio->fio.handle, &mode) == FALSE) + if (GetConsoleMode (sio->u.file.handle, &mode) == FALSE) { - return qse_tio_writewcs (&sio->tio, str, size); + n = qse_tio_writewcs (&sio->tio.io, str, size); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return n; } else { @@ -336,7 +504,7 @@ qse_ssize_t qse_sio_putwcsn ( for (cur = str, left = size; left > 0; cur += count, left -= count) { if (WriteConsoleW ( - sio->fio.handle, cur, left, + sio->u.file.handle, cur, left, &count, QSE_NULL) == FALSE) return -1; if (count == 0) break; } @@ -345,15 +513,22 @@ qse_ssize_t qse_sio_putwcsn ( } #endif - return qse_tio_writewcs (&sio->tio, str, size); + n = qse_tio_writewcs (&sio->tio.io, str, size); + if (n <= -1 && sio->errnum == QSE_SIO_ENOERR) + sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io); + return n; } int qse_sio_getpos (qse_sio_t* sio, qse_sio_pos_t* pos) { qse_fio_off_t off; - off = qse_fio_seek (&sio->fio, 0, QSE_FIO_CURRENT); - if (off == (qse_fio_off_t)-1) return -1; + off = qse_fio_seek (&sio->u.file, 0, QSE_FIO_CURRENT); + if (off == (qse_fio_off_t)-1) + { + sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file); + return -1; + } *pos = off; return 0; @@ -364,9 +539,14 @@ 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->fio, pos, QSE_FIO_BEGIN); + off = qse_fio_seek (&sio->u.file, pos, QSE_FIO_BEGIN); + if (off == (qse_fio_off_t)-1) + { + sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file); + return -1; + } - return (off == (qse_fio_off_t)-1)? -1: 0; + return 0; } #if 0 @@ -376,44 +556,103 @@ 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->fio, + return (qse_fio_seek (&sio->u.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->fio, + return (qse_fio_seek (&sio->u.file, 0, QSE_FIO_BEGIN) == (qse_fio_off_t)-1)? -1: 0; } #endif -static qse_ssize_t __sio_input ( - qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size) +static qse_ssize_t file_input ( + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size) { - qse_sio_t* sio = (qse_sio_t*)arg; - - QSE_ASSERT (sio != QSE_NULL); if (cmd == QSE_TIO_DATA) { - return qse_fio_read (&sio->fio, buf, size); + qse_ssize_t n; + qse_sio_t* sio; + + 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); + return n; } return 0; } -static qse_ssize_t __sio_output ( - qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size) +static qse_ssize_t file_output ( + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size) { - qse_sio_t* sio = (qse_sio_t*)arg; - - QSE_ASSERT (sio != QSE_NULL); - if (cmd == QSE_TIO_DATA) { - return qse_fio_write (&sio->fio, buf, size); + qse_ssize_t n; + qse_sio_t* sio; + + 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); + return n; } return 0; } +/* ---------------------------------------------------------- */ + +#if 0 + +#if defined(_WIN32) +# include +#else +# include +#endif + +static qse_ssize_t socket_input ( + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size) +{ + + if (cmd == QSE_TIO_DATA) + { + qse_ssize_t n; + qse_sio_t* sio; + + sio = *(qse_sio_t**)QSE_XTN(tio); + QSE_ASSERT (sio != QSE_NULL); + + n = recv (sio->u.sck, buf, size, 0); + if (n <= -1) sio->errnum = syserr_to_errnum (errno); + return n; + } + + return 0; +} + +static qse_ssize_t socket_output ( + qse_tio_t* tio, qse_tio_cmd_t cmd, void* buf, qse_size_t size) +{ + if (cmd == QSE_TIO_DATA) + { + qse_ssize_t n; + qse_sio_t* sio; + + sio = *(qse_sio_t**)QSE_XTN(tio); + QSE_ASSERT (sio != QSE_NULL); + + n = send (sio->u.sck, buf, size, 0); + if (n <= -1) sio->errnum = syserr_to_errnum (errno); + return n; + } + + return 0; +} + +#endif diff --git a/qse/lib/cmn/syscall.h b/qse/lib/cmn/syscall.h index 91b569cc..eab18ecf 100644 --- a/qse/lib/cmn/syscall.h +++ b/qse/lib/cmn/syscall.h @@ -38,6 +38,9 @@ #ifdef HAVE_ERRNO_H # include #endif +#ifdef HAVE_FCNTL_H +# include +#endif #ifdef HAVE_TIME_H # include #endif diff --git a/qse/lib/cmn/tio-get.c b/qse/lib/cmn/tio-get.c index e5871706..ddb23110 100644 --- a/qse/lib/cmn/tio-get.c +++ b/qse/lib/cmn/tio-get.c @@ -49,14 +49,14 @@ qse_ssize_t qse_tio_readmbs (qse_tio_t* tio, qse_mchar_t* buf, qse_size_t size) { if (tio->inbuf_cur >= tio->inbuf_len) { + tio->errnum = QSE_TIO_ENOERR; n = tio->in.fun ( - QSE_TIO_DATA, tio->in.arg, - tio->in.buf.ptr, - tio->in.buf.capa); + tio, QSE_TIO_DATA, + tio->in.buf.ptr, tio->in.buf.capa); if (n == 0) break; if (n <= -1) { - tio->errnum = QSE_TIO_EIOERR; + if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER; return -1; } @@ -93,8 +93,9 @@ static QSE_INLINE qse_ssize_t tio_read_widechars ( if (tio->input_status & STATUS_EOF) n = 0; else { + tio->errnum = QSE_TIO_ENOERR; n = tio->in.fun ( - QSE_TIO_DATA, tio->in.arg, + tio, QSE_TIO_DATA, &tio->in.buf.ptr[tio->inbuf_len], tio->in.buf.capa - tio->inbuf_len); } @@ -122,7 +123,7 @@ static QSE_INLINE qse_ssize_t tio_read_widechars ( } if (n <= -1) { - tio->errnum = QSE_TIO_EIOERR; + if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER; return -1; } diff --git a/qse/lib/cmn/tio.c b/qse/lib/cmn/tio.c index 3ab9951c..a0029a0c 100644 --- a/qse/lib/cmn/tio.c +++ b/qse/lib/cmn/tio.c @@ -92,28 +92,6 @@ qse_tio_errnum_t qse_tio_geterrnum (qse_tio_t* tio) return tio->errnum; } -const qse_char_t* qse_tio_geterrmsg (qse_tio_t* tio) -{ - static const qse_char_t* __errmsg[] = - { - QSE_T("no error"), - QSE_T("out of memory"), - QSE_T("invalid parameter"), - QSE_T("no more space"), - QSE_T("illegal multibyte sequence"), - QSE_T("incomplete multibyte sequence"), - QSE_T("illegal wide character"), - QSE_T("no input function attached"), - QSE_T("no output function attached"), - QSE_T("I/O error"), - QSE_T("unknown error") - }; - - return __errmsg[ - (tio->errnum < 0 || tio->errnum >= QSE_COUNTOF(__errmsg))? - QSE_COUNTOF(__errmsg) - 1: tio->errnum]; -} - qse_cmgr_t* qse_tio_getcmgr (qse_tio_t* tio) { return tio->cmgr; @@ -125,7 +103,7 @@ void qse_tio_setcmgr (qse_tio_t* tio, qse_cmgr_t* cmgr) } int qse_tio_attachin ( - qse_tio_t* tio, qse_tio_io_fun_t input, void* arg, + qse_tio_t* tio, qse_tio_io_fun_t input, qse_mchar_t* bufptr, qse_size_t bufcapa) { qse_mchar_t* xbufptr; @@ -152,10 +130,11 @@ int qse_tio_attachin ( } } - if (input (QSE_TIO_OPEN, arg, QSE_NULL, 0) <= -1) + tio->errnum = QSE_TIO_ENOERR; + if (input (tio, QSE_TIO_OPEN, QSE_NULL, 0) <= -1) { + if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER; if (xbufptr != bufptr) QSE_MMGR_FREE (tio->mmgr, xbufptr); - tio->errnum = QSE_TIO_EIOERR; return -1; } @@ -167,7 +146,6 @@ int qse_tio_attachin ( */ tio->in.fun = input; - tio->in.arg = arg; tio->in.buf.ptr = xbufptr; tio->in.buf.capa = bufcapa; @@ -185,10 +163,10 @@ static int detach_in (qse_tio_t* tio, int fini) if (tio->in.fun) { - if (tio->in.fun ( - QSE_TIO_CLOSE, tio->in.arg, QSE_NULL, 0) <= -1) + tio->errnum = QSE_TIO_ENOERR; + if (tio->in.fun (tio, QSE_TIO_CLOSE, QSE_NULL, 0) <= -1) { - tio->errnum = QSE_TIO_EIOERR; + if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER; /* returning with an error here allows you to retry detaching */ if (!fini) return -1; @@ -205,7 +183,6 @@ static int detach_in (qse_tio_t* tio, int fini) } tio->in.fun = QSE_NULL; - tio->in.arg = QSE_NULL; tio->in.buf.ptr = QSE_NULL; tio->in.buf.capa = 0; } @@ -219,7 +196,7 @@ int qse_tio_detachin (qse_tio_t* tio) } int qse_tio_attachout ( - qse_tio_t* tio, qse_tio_io_fun_t output, void* arg, + qse_tio_t* tio, qse_tio_io_fun_t output, qse_mchar_t* bufptr, qse_size_t bufcapa) { qse_mchar_t* xbufptr; @@ -246,15 +223,15 @@ int qse_tio_attachout ( } } - if (output (QSE_TIO_OPEN, arg, QSE_NULL, 0) == -1) + tio->errnum = QSE_TIO_ENOERR; + if (output (tio, QSE_TIO_OPEN, QSE_NULL, 0) == -1) { + if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER; if (xbufptr != bufptr) QSE_MMGR_FREE (tio->mmgr, xbufptr); - tio->errnum = QSE_TIO_EIOERR; return -1; } tio->out.fun = output; - tio->out.arg = arg; tio->out.buf.ptr = xbufptr; tio->out.buf.capa = bufcapa; @@ -272,10 +249,10 @@ static int detach_out (qse_tio_t* tio, int fini) { qse_tio_flush (tio); /* don't care about the result */ - if (tio->out.fun ( - QSE_TIO_CLOSE, tio->out.arg, QSE_NULL, 0) <= -1) + tio->errnum = QSE_TIO_ENOERR; + if (tio->out.fun (tio, QSE_TIO_CLOSE, QSE_NULL, 0) <= -1) { - tio->errnum = QSE_TIO_EIOERR; + if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER; /* returning with an error here allows you to retry detaching */ if (!fini) return -1; @@ -291,7 +268,6 @@ static int detach_out (qse_tio_t* tio, int fini) } tio->out.fun = QSE_NULL; - tio->out.arg = QSE_NULL; tio->out.buf.ptr = QSE_NULL; tio->out.buf.capa = 0; } @@ -320,13 +296,13 @@ qse_ssize_t qse_tio_flush (qse_tio_t* tio) cur = tio->out.buf.ptr; while (left > 0) { - n = tio->out.fun ( - QSE_TIO_DATA, tio->out.arg, cur, left); + tio->errnum = QSE_TIO_ENOERR; + n = tio->out.fun (tio, QSE_TIO_DATA, cur, left); if (n <= -1) { + if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER; QSE_MEMCPY (tio->out.buf.ptr, cur, left); tio->outbuf_len = left; - tio->errnum = QSE_TIO_EIOERR; return -1; } if (n == 0) diff --git a/qse/lib/net/htrd.c b/qse/lib/net/htrd.c index 82aa7950..692a5dc4 100644 --- a/qse/lib/net/htrd.c +++ b/qse/lib/net/htrd.c @@ -209,7 +209,6 @@ static qse_mchar_t* parse_initial_line ( { qse_mchar_t* p = line; qse_mcstr_t tmp; - qse_http_method_t mtype; #if 0 /* ignore leading spaces excluding crlf */ @@ -225,10 +224,9 @@ static qse_mchar_t* parse_initial_line ( tmp.len = p - tmp.ptr; htrd->retype = QSE_HTRD_RETYPE_Q; - if ((htrd->option & QSE_HTRD_REQUEST) && - qse_gethttpmethodtypefromstr (&tmp, &mtype) >= 0) + if (htrd->option & QSE_HTRD_REQUEST) { - qse_htre_setqmethod (&htrd->re, mtype); + qse_htre_setqmethod (&htrd->re, qse_mcstrtohttpmethod (&tmp)); } else if ((htrd->option & QSE_HTRD_RESPONSE) && qse_mbsxcmp (tmp.ptr, tmp.len, QSE_MT("HTTP")) == 0) diff --git a/qse/lib/net/htre.c b/qse/lib/net/htre.c index b4b2269d..ad68f0e4 100644 --- a/qse/lib/net/htre.c +++ b/qse/lib/net/htre.c @@ -95,7 +95,8 @@ struct header_walker_ctx_t int ret; }; -static qse_htb_walk_t walk_headers (qse_htb_t* htb, qse_htb_pair_t* pair, void* ctx) +static qse_htb_walk_t walk_headers ( + qse_htb_t* htb, qse_htb_pair_t* pair, void* ctx) { struct header_walker_ctx_t* hwctx = (struct header_walker_ctx_t*)ctx; if (hwctx->walker (hwctx->re, QSE_HTB_KPTR(pair), QSE_HTB_VPTR(pair), hwctx->ctx) <= -1) @@ -204,5 +205,5 @@ void qse_htre_setconcb (qse_htre_t* re, qse_htre_concb_t concb, void* ctx) const qse_mchar_t* qse_htre_getqmethodname (const qse_htre_t* re) { - return qse_gethttpmethodname (re->qmethod_or_sstatus); + return qse_httpmethodtombs (re->qmethod_or_sstatus); } diff --git a/qse/lib/net/http.c b/qse/lib/net/http.c index 808c604f..35411ef5 100644 --- a/qse/lib/net/http.c +++ b/qse/lib/net/http.c @@ -31,17 +31,20 @@ int qse_comparehttpversions ( return v1->major - v2->major; } -const qse_mchar_t* qse_gethttpmethodname (qse_http_method_t type) +const qse_mchar_t* qse_httpmethodtombs (qse_http_method_t type) { + /* keep this table in the same order as qse_httpd_method_t enumerators */ static qse_mchar_t* names[] = { - QSE_MT("GET"), + QSE_MT("OTHER"), + QSE_MT("HEAD"), + QSE_MT("GET"), QSE_MT("POST"), QSE_MT("PUT"), QSE_MT("DELETE"), - QSE_MT("TRACE"), QSE_MT("OPTIONS"), + QSE_MT("TRACE"), QSE_MT("CONNECT") }; @@ -67,11 +70,8 @@ static struct mtab_t mtab[] = { QSE_MT("TRACE"), QSE_HTTP_TRACE } }; -int qse_gethttpmethodtype ( - const qse_mchar_t* name, - qse_http_method_t* type) +qse_http_method_t qse_mbstohttpmethod (const qse_mchar_t* name) { - /* perform binary search */ /* declaring left, right, mid to be of int is ok @@ -96,19 +96,13 @@ int qse_gethttpmethodtype ( right = mid - 1; } else if (n > 0) left = mid + 1; - else - { - *type = entry->type; - return 0; - } + else return entry->type; } - return -1; + return QSE_HTTP_OTHER; } -int qse_gethttpmethodtypefromstr ( - const qse_mcstr_t* name, - qse_http_method_t* type) +qse_http_method_t qse_mcstrtohttpmethod (const qse_mcstr_t* name) { /* perform binary search */ @@ -134,14 +128,10 @@ int qse_gethttpmethodtypefromstr ( right = mid - 1; } else if (n > 0) left = mid + 1; - else - { - *type = entry->type; - return 0; - } + else return entry->type; } - return -1; + return QSE_HTTP_OTHER; } int qse_parsehttprange (const qse_mchar_t* str, qse_http_range_t* range) diff --git a/qse/lib/net/httpd_task.c b/qse/lib/net/httpd_task.c index b0e73032..e1e4e2fd 100644 --- a/qse/lib/net/httpd_task.c +++ b/qse/lib/net/httpd_task.c @@ -2079,9 +2079,9 @@ static void task_fini_cgi ( if (cgi->pio_inited) { /* kill cgi in case it is still alive. - * qse_pio_wait() in qse_pio_close() can block. */ + * qse_pio_wait() in qse_pio_fini() can block. */ qse_pio_kill (&cgi->pio); - qse_pio_close (&cgi->pio); + qse_pio_fini (&cgi->pio); } if (cgi->res) qse_mbs_close (cgi->res); if (cgi->htrd) qse_htrd_close (cgi->htrd); diff --git a/qse/samples/cmn/fio01.c b/qse/samples/cmn/fio01.c index 2c044cb0..4018fdb2 100644 --- a/qse/samples/cmn/fio01.c +++ b/qse/samples/cmn/fio01.c @@ -22,7 +22,7 @@ static int test1 (void) fio = qse_fio_open ( QSE_MMGR_GETDFL(), 0, - QSE_T("fio1.txt"), + QSE_T("fio01-1.txt"), QSE_FIO_READ|QSE_FIO_WRITE|QSE_FIO_CREATE|QSE_FIO_TRUNCATE, QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH ); @@ -107,7 +107,7 @@ static int test2 (void) fio = qse_fio_open ( QSE_MMGR_GETDFL(), 0, - QSE_T("fio2.txt"), + QSE_T("fio01-2.txt"), QSE_FIO_CREATE | QSE_FIO_TRUNCATE | QSE_FIO_APPEND, QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH ); @@ -216,16 +216,16 @@ static int test3 (void) { qse_fio_t* fio; qse_ssize_t n; - const qse_char_t* x = QSE_T("\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?"); + const qse_mchar_t* x = QSE_MT("this is a test string"); qse_fio_off_t off; - qse_char_t buf[1000]; + qse_mchar_t buf[1000]; fio = qse_fio_open ( QSE_MMGR_GETDFL(), 0, - QSE_T("fio3.txt"), + QSE_T("fio01-3.txt"), - QSE_FIO_TEXT | QSE_FIO_READ | QSE_FIO_WRITE | + QSE_FIO_READ | QSE_FIO_WRITE | QSE_FIO_CREATE | QSE_FIO_TRUNCATE, QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH @@ -236,29 +236,24 @@ static int test3 (void) return -1; } - n = qse_fio_write (fio, x, qse_strlen(x)); + n = qse_fio_write (fio, x, qse_mbslen(x)); qse_printf (QSE_T("written %d chars\n"), (int)n); - n = qse_fio_flush (fio); - qse_printf (QSE_T("flushed %d chars\n"), (int)n); - off = qse_fio_seek (fio, 0, QSE_FIO_BEGIN); if (off == (qse_fio_off_t)-1) { qse_printf (QSE_T("failed to get file offset\n")); } - n = qse_fio_read (fio, buf, QSE_COUNTOF(buf)); qse_printf (QSE_T("read %d chars\n"), (int)n); if (n > 0) { - qse_printf (QSE_T("[%.*s]\n"), (int)n, buf); + qse_printf (QSE_T("[%.*hs]\n"), (int)n, buf); } qse_fio_close (fio); - return 0; } @@ -275,7 +270,7 @@ int main () R (test3); qse_printf (QSE_T("--------------------------------------------------------------------------------\n")); - qse_printf (QSE_T("Run \"rm -f fio?.txt\" to delete garbages\n")); + qse_printf (QSE_T("Run \"rm -f fio01-?.txt\" to delete garbages\n")); qse_printf (QSE_T("--------------------------------------------------------------------------------\n")); return 0; diff --git a/qse/samples/cmn/pio.c b/qse/samples/cmn/pio.c index cc207a17..d8ee8e96 100644 --- a/qse/samples/cmn/pio.c +++ b/qse/samples/cmn/pio.c @@ -52,8 +52,8 @@ static int pio1 (const qse_char_t* cmd, qse_env_t* env, int oflags, qse_pio_hid_ if (n <= -1) { qse_printf ( - QSE_T("qse_pio_read() returned error - %s\n"), - qse_pio_geterrmsg(pio) + QSE_T("qse_pio_read() returned error - %d\n"), + (int)qse_pio_geterrnum(pio) ); break; } @@ -74,8 +74,7 @@ static int pio1 (const qse_char_t* cmd, qse_env_t* env, int oflags, qse_pio_hid_ qse_printf (QSE_T("qse_pio_wait returns %d\n"), x); if (x <= -1) { - qse_printf (QSE_T("error code : %d, error string: %s\n"), - (int)qse_pio_geterrnum(pio), qse_pio_geterrmsg(pio)); + qse_printf (QSE_T("error code : %d\n"), (int)qse_pio_geterrnum(pio)); } qse_pio_close (pio); @@ -111,8 +110,8 @@ static int pio2 (const qse_char_t* cmd, qse_env_t* env, int oflags, qse_pio_hid_ if (n < 0) { qse_printf ( - QSE_T("qse_pio_read() returned error - %s\n"), - qse_pio_geterrmsg(pio) + QSE_T("qse_pio_read() returned error - %d\n"), + (int)qse_pio_geterrnum(pio) ); break; } @@ -129,8 +128,7 @@ static int pio2 (const qse_char_t* cmd, qse_env_t* env, int oflags, qse_pio_hid_ qse_printf (QSE_T("qse_pio_wait returns %d\n"), x); if (x <= -1) { - qse_printf (QSE_T("error code : %d, error string: %s\n"), - (int)qse_pio_geterrnum(pio), qse_pio_geterrmsg(pio)); + qse_printf (QSE_T("error code : %d\n"), (int)qse_pio_geterrnum(pio)); } qse_pio_close (pio); @@ -394,7 +392,7 @@ static int test13 (void) qse_printf (QSE_T("qse_pio_wait returns %d\n"), x); if (x == -1) { - qse_printf (QSE_T("error code : %d, error string: %s\n"), (int)QSE_PIO_ERRNUM(pio), qse_pio_geterrmsg(pio)); + qse_printf (QSE_T("error code : %d\n"), (int)QSE_PIO_ERRNUM(pio)); } qse_pio_close (pio); diff --git a/qse/samples/net/http01.c b/qse/samples/net/http01.c index 647acf17..ac417150 100644 --- a/qse/samples/net/http01.c +++ b/qse/samples/net/http01.c @@ -30,6 +30,7 @@ # include #endif +/* TODO: WIN32 TransmitFile */ #if defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE64) # if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) # define xsendfile sendfile64 @@ -270,6 +271,7 @@ qse_printf (QSE_T("opening file [%hs] for reading\n"), path); return -1; } +/* check if it is a link. symbolic link??? */ if (!S_ISREG(st.st_mode)) { qse_httpd_seterrnum (httpd, QSE_HTTPD_EACCES);