enhanced error handling of sio,pio,tio

This commit is contained in:
hyung-hwan 2012-02-12 13:20:39 +00:00
parent 3df521f7a9
commit a2346f6e4b
21 changed files with 1104 additions and 525 deletions

4
qse/configure vendored
View File

@ -15987,7 +15987,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi 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 : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -16013,7 +16013,7 @@ fi
done 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 : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"

View File

@ -78,9 +78,9 @@ AC_SUBST(LIBM, $LIBM)
dnl check header files. dnl check header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h]) AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h])
AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h]) AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h])
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]) AC_CHECK_HEADERS([execinfo.h])
dnl check data types dnl check data types

View File

@ -28,49 +28,62 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
#include <qse/cmn/tio.h> enum qse_fio_flag_t
enum qse_fio_open_flag_t
{ {
/** request text-based based IO */ /* (1 << 0) to (1 << 7) reserved for qse_sio_flag_t.
QSE_FIO_TEXT = (1 << 0), * see <qse/cmn/sio.h>. nerver use this value. */
QSE_FIO_IGNOREMBWCERR = (1 << 1), /* useful if QSE_FIO_TEXT is set */ QSE_FIO_RESERVED = 0xFF,
QSE_FIO_NOAUTOFLUSH = (1 << 2), /* useful if QSE_FIO_TEXT is set */
/** treat the file name pointer as a handle pointer */ /** 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 /** treate the file name pointer as a pointer to file name
* template to use when making a temporary 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() */ /** 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 */ /* normal open flags */
QSE_FIO_READ = (1 << 8), QSE_FIO_READ = (1 << 14),
QSE_FIO_WRITE = (1 << 9), QSE_FIO_WRITE = (1 << 15),
QSE_FIO_APPEND = (1 << 10), QSE_FIO_APPEND = (1 << 16),
QSE_FIO_CREATE = (1 << 11), QSE_FIO_CREATE = (1 << 17),
QSE_FIO_TRUNCATE = (1 << 12), QSE_FIO_TRUNCATE = (1 << 18),
QSE_FIO_EXCLUSIVE = (1 << 13), QSE_FIO_EXCLUSIVE = (1 << 19),
QSE_FIO_SYNC = (1 << 14), QSE_FIO_SYNC = (1 << 20),
/* do not follow a symbolic link, only on a supported platform */ /* 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 */ /* for WIN32 only. harmless(no effect) when used on other platforms */
QSE_FIO_NOSHREAD = (1 << 20), QSE_FIO_NOSHREAD = (1 << 24),
QSE_FIO_NOSHWRITE = (1 << 21), QSE_FIO_NOSHWRITE = (1 << 25),
QSE_FIO_NOSHDELETE = (1 << 22), QSE_FIO_NOSHDELETE = (1 << 26),
/* hints to OS. harmless(no effect) when used on unsupported platforms */ /* hints to OS. harmless(no effect) when used on unsupported platforms */
QSE_FIO_RANDOM = (1 << 23), /* hint that access be random */ QSE_FIO_RANDOM = (1 << 27), /* hint that access be random */
QSE_FIO_SEQUENTIAL = (1 << 24) /* hint that access is sequential */ 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 enum qse_fio_std_t
{ {
QSE_FIO_STDIN = 0, QSE_FIO_STDIN = 0,
@ -126,13 +139,10 @@ typedef struct qse_fio_lck_t qse_fio_lck_t;
struct qse_fio_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_DEFINE_COMMON_FIELDS (fio)
qse_fio_hnd_t handle; qse_fio_errnum_t errnum;
int flags; /* extra flags */ qse_fio_hnd_t handle;
qse_tio_t* tio; int flags; /* extra flags */
}; };
struct qse_fio_lck_t struct qse_fio_lck_t
@ -200,23 +210,6 @@ void qse_fio_fini (
qse_fio_t* fio 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. * 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 qse_fio_t* fio
); );
/** qse_ubi_t qse_fio_gethandleasubi (
* The qse_fio_sethandle() function sets the file handle qse_fio_t* fio
* 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
); );
/** /**
@ -273,15 +259,6 @@ qse_ssize_t qse_fio_write (
qse_size_t size 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. * The qse_fio_chmod() function changes the file mode.
* *

View File

@ -126,15 +126,22 @@ enum qse_pio_option_t
enum qse_pio_errnum_t enum qse_pio_errnum_t
{ {
QSE_PIO_ENOERR = 0, /**< no error */ QSE_PIO_ENOERR = 0, /**< no error */
QSE_PIO_ENOMEM, /**< out of memory */ QSE_PIO_ENOMEM, /**< out of memory */
QSE_PIO_EINVAL, /**< invalid parameter */ 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_EACCES, /**< access denied */
QSE_PIO_ENOENT, /**< no such file */ 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; 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 */ 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. * The qse_pio_getcmgr() function returns the current character manager.
* It returns #QSE_NULL is @a pio is not opened with #QSE_PIO_TEXT. * It returns #QSE_NULL is @a pio is not opened with #QSE_PIO_TEXT.

View File

@ -32,39 +32,52 @@
enum qse_sio_flag_t enum qse_sio_flag_t
{ {
QSE_SIO_IGNOREMBWCERR = QSE_FIO_IGNOREMBWCERR, /* ensure that these enumerators never overlap with
QSE_SIO_NOAUTOFLUSH = QSE_FIO_NOAUTOFLUSH, * 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_HANDLE = QSE_FIO_HANDLE,
QSE_SIO_TEMPORARY = QSE_FIO_TEMPORARY, QSE_SIO_TEMPORARY = QSE_FIO_TEMPORARY,
QSE_SIO_NOCLOSE = QSE_FIO_NOCLOSE, QSE_SIO_NOCLOSE = QSE_FIO_NOCLOSE,
QSE_SIO_READ = QSE_FIO_READ, QSE_SIO_READ = QSE_FIO_READ,
QSE_SIO_WRITE = QSE_FIO_WRITE, QSE_SIO_WRITE = QSE_FIO_WRITE,
QSE_SIO_APPEND = QSE_FIO_APPEND, QSE_SIO_APPEND = QSE_FIO_APPEND,
QSE_SIO_CREATE = QSE_FIO_CREATE, QSE_SIO_CREATE = QSE_FIO_CREATE,
QSE_SIO_TRUNCATE = QSE_FIO_TRUNCATE, QSE_SIO_TRUNCATE = QSE_FIO_TRUNCATE,
QSE_SIO_EXCLUSIVE = QSE_FIO_EXCLUSIVE, QSE_SIO_EXCLUSIVE = QSE_FIO_EXCLUSIVE,
QSE_SIO_SYNC = QSE_FIO_SYNC, QSE_SIO_SYNC = QSE_FIO_SYNC,
QSE_SIO_NOFOLLOW = QSE_FIO_NOFOLLOW, QSE_SIO_NOFOLLOW = QSE_FIO_NOFOLLOW,
QSE_SIO_NOSHREAD = QSE_FIO_NOSHREAD, QSE_SIO_NOSHREAD = QSE_FIO_NOSHREAD,
QSE_SIO_NOSHWRITE = QSE_FIO_NOSHWRITE, QSE_SIO_NOSHWRITE = QSE_FIO_NOSHWRITE,
QSE_SIO_NOSHDELETE = QSE_FIO_NOSHDELETE, QSE_SIO_NOSHDELETE = QSE_FIO_NOSHDELETE,
QSE_SIO_RANDOM = QSE_FIO_RANDOM, QSE_SIO_RANDOM = QSE_FIO_RANDOM,
QSE_SIO_SEQUENTIAL = QSE_FIO_SEQUENTIAL QSE_SIO_SEQUENTIAL = QSE_FIO_SEQUENTIAL
}; };
typedef qse_tio_errnum_t qse_sio_errnum_t; enum qse_sio_errnum_t
#define QSE_SIO_ENOERR QSE_TIO_ENOERR {
#define QSE_SIO_ENOMEM QSE_TIO_ENOMEM QSE_SIO_ENOERR = 0, /**< no error */
#define QSE_SIO_ENOSPC QSE_TIO_ENOSPC
#define QSE_SIO_EILSEQ QSE_TIO_EILSEQ QSE_SIO_ENOMEM, /**< out of memory */
#define QSE_SIO_EICSEQ QSE_TIO_EICSEQ QSE_SIO_EINVAL, /**< invalid parameter */
#define QSE_SIO_EILCHR QSE_TIO_EILCHR QSE_SIO_EACCES, /**< access denied */
#define QSE_SIO_ERRNUM(sio) QSE_TIO_ERRNUM(&((sio)->tio)) 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_off_t qse_sio_pos_t;
typedef qse_fio_hnd_t qse_sio_hnd_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 struct qse_sio_t
{ {
QSE_DEFINE_COMMON_FIELDS (tio) QSE_DEFINE_COMMON_FIELDS (sio)
qse_fio_t fio; qse_sio_errnum_t errnum;
qse_tio_t tio;
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) #if defined(_WIN32)
int status; int status;
#endif #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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -157,6 +212,10 @@ qse_sio_hnd_t qse_sio_gethandle (
qse_sio_t* sio qse_sio_t* sio
); );
qse_ubi_t qse_sio_gethandleasubi (
qse_sio_t* sio
);
qse_ssize_t qse_sio_flush ( qse_ssize_t qse_sio_flush (
qse_sio_t* sio qse_sio_t* sio
); );

View File

@ -33,15 +33,19 @@
enum qse_tio_errnum_t enum qse_tio_errnum_t
{ {
QSE_TIO_ENOERR = 0, QSE_TIO_ENOERR = 0,
QSE_TIO_ENOMEM, /* out of memory */ QSE_TIO_ENOMEM, /* out of memory */
QSE_TIO_EINVAL, /* invalid parameter */ QSE_TIO_EINVAL, /* invalid parameter */
QSE_TIO_EACCES, /**< access denied */
QSE_TIO_ENOENT, /**< no such file */
QSE_TIO_ENOSPC, /* no more space */ QSE_TIO_ENOSPC, /* no more space */
QSE_TIO_EILSEQ, /* illegal sequence */ QSE_TIO_EILSEQ, /* illegal sequence */
QSE_TIO_EICSEQ, /* incomplete sequence */ QSE_TIO_EICSEQ, /* incomplete sequence */
QSE_TIO_EILCHR, /* illegal character */ QSE_TIO_EILCHR, /* illegal character */
QSE_TIO_ENINPF, /* no input function attached */ QSE_TIO_ENINPF, /* no input function attached */
QSE_TIO_ENOUTF, /* no output 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; 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. * The qse_tio_io_fun_t types define a text I/O handler.
*/ */
typedef qse_ssize_t (*qse_tio_io_fun_t) ( typedef qse_ssize_t (*qse_tio_io_fun_t) (
qse_tio_t* tio,
qse_tio_cmd_t cmd, qse_tio_cmd_t cmd,
void* arg,
void* data, void* data,
qse_size_t size qse_size_t size
); );
@ -91,7 +95,6 @@ typedef qse_ssize_t (*qse_tio_io_fun_t) (
struct qse_tio_io_t struct qse_tio_io_t
{ {
qse_tio_io_fun_t fun; qse_tio_io_fun_t fun;
void* arg;
struct struct
{ {
qse_size_t capa; qse_size_t capa;
@ -169,14 +172,6 @@ qse_tio_errnum_t qse_tio_geterrnum (
qse_tio_t* tio 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. * The qse_tio_getcmgr() function returns the character manager.
*/ */
@ -199,7 +194,6 @@ void qse_tio_setcmgr (
int qse_tio_attachin ( int qse_tio_attachin (
qse_tio_t* tio, qse_tio_t* tio,
qse_tio_io_fun_t input, qse_tio_io_fun_t input,
void* arg,
qse_mchar_t* bufptr, qse_mchar_t* bufptr,
qse_size_t bufcapa qse_size_t bufcapa
); );
@ -219,7 +213,6 @@ int qse_tio_detachin (
int qse_tio_attachout ( int qse_tio_attachout (
qse_tio_t* tio, qse_tio_t* tio,
qse_tio_io_fun_t output, qse_tio_io_fun_t output,
void* arg,
qse_mchar_t* bufptr, qse_mchar_t* bufptr,
qse_size_t bufcapa qse_size_t bufcapa
); );

View File

@ -70,6 +70,9 @@
/* Define to 1 if you have the `expl' function. */ /* Define to 1 if you have the `expl' function. */
#undef HAVE_EXPL #undef HAVE_EXPL
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fdopendir' function. */ /* Define to 1 if you have the `fdopendir' function. */
#undef HAVE_FDOPENDIR #undef HAVE_FDOPENDIR
@ -279,6 +282,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H #undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the `tan' function. */ /* Define to 1 if you have the `tan' function. */
#undef HAVE_TAN #undef HAVE_TAN

View File

@ -53,14 +53,52 @@ typedef struct qse_http_version_t qse_http_version_t;
*/ */
enum qse_http_method_t enum qse_http_method_t
{ {
QSE_HTTP_GET, QSE_HTTP_OTHER,
/* rfc 2616 */
QSE_HTTP_HEAD, QSE_HTTP_HEAD,
QSE_HTTP_GET,
QSE_HTTP_POST, QSE_HTTP_POST,
QSE_HTTP_PUT, QSE_HTTP_PUT,
QSE_HTTP_DELETE, QSE_HTTP_DELETE,
QSE_HTTP_TRACE,
QSE_HTTP_OPTIONS, QSE_HTTP_OPTIONS,
QSE_HTTP_TRACE,
QSE_HTTP_CONNECT 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; 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_http_version_t* v2
); );
const qse_mchar_t* qse_gethttpmethodname ( const qse_mchar_t* qse_httpmethodtombs (
qse_http_method_t type qse_http_method_t type
); );
int qse_gethttpmethodtype ( qse_http_method_t qse_mbstohttpmethod (
const qse_mchar_t* name, const qse_mchar_t* name
qse_http_method_t* method
); );
int qse_gethttpmethodtypefromstr ( qse_http_method_t qse_mcstrtohttpmethod (
const qse_mcstr_t* name, const qse_mcstr_t* name
qse_http_method_t* type
); );
int qse_parsehttprange ( int qse_parsehttprange (

View File

@ -20,10 +20,10 @@
#include <qse/cmn/fio.h> #include <qse/cmn/fio.h>
#include <qse/cmn/str.h> #include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/fmt.h> #include <qse/cmn/fmt.h>
#include <qse/cmn/alg.h> #include <qse/cmn/alg.h>
#include <qse/cmn/time.h> #include <qse/cmn/time.h>
#include <qse/cmn/mbwc.h>
#include "mem.h" #include "mem.h"
#if defined(_WIN32) #if defined(_WIN32)
@ -39,16 +39,120 @@
# include <fcntl.h> # include <fcntl.h>
#else #else
# include "syscall.h" # include "syscall.h"
# include <sys/types.h>
# include <fcntl.h>
#endif #endif
QSE_IMPLEMENT_COMMON_FUNCTIONS (fio) QSE_IMPLEMENT_COMMON_FUNCTIONS (fio)
static qse_ssize_t fio_input ( #if defined(_WIN32)
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); static qse_fio_errnum_t syserr_to_errnum (DWORD e)
static qse_ssize_t fio_output ( {
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size);
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_fio_t* qse_fio_open (
qse_mmgr_t* mmgr, qse_size_t ext, 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 /* The path name template must be at least 4 characters long
* excluding the terminating null. this function fails if not */ * 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); qse_gettime (&now);
temp_no += (now & 0xFFFFFFFFlu); temp_no += (now & 0xFFFFFFFFlu);
@ -120,7 +228,11 @@ int qse_fio_init (
temp_tries++; temp_tries++;
/* Fails after 5000 tries. 5000 randomly chosen */ /* 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 /* Generate the next random number to use to make a
* new path name */ * new path name */
@ -210,6 +322,7 @@ int qse_fio_init (
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
fio->errnum = syserr_to_errnum(GetLastError());
return -1; return -1;
} }
@ -217,6 +330,7 @@ int qse_fio_init (
#if 0 #if 0
if (GetFileType(handle) == FILE_TYPE_UNKNOWN) if (GetFileType(handle) == FILE_TYPE_UNKNOWN)
{ {
fio->errnum = syserr_to_errnum(GetLastError());
CloseHandle (handle); CloseHandle (handle);
return -1; return -1;
} }
@ -250,10 +364,20 @@ int qse_fio_init (
px = qse_wcstombs (path, &wl, path_mb, &ml); px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2) if (px == -2)
{ {
/* the static buffer is too small.
* dynamically allocate a buffer */
path_mb = qse_wcstombsdup (path, mmgr); 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 #endif
zero.ulLo = 0; zero.ulLo = 0;
@ -329,6 +453,7 @@ int qse_fio_init (
if (ret != NO_ERROR) if (ret != NO_ERROR)
{ {
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
fio->errnum = syserr_to_errnum(ret);
return -1; return -1;
} }
} }
@ -358,9 +483,17 @@ int qse_fio_init (
if (px == -2) if (px == -2)
{ {
path_mb = qse_wcstombsdup (path, mmgr); 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 #endif
if (flags & QSE_FIO_APPEND) if (flags & QSE_FIO_APPEND)
@ -401,6 +534,7 @@ int qse_fio_init (
if (handle <= -1) if (handle <= -1)
{ {
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
fio->errnum = syserr_to_errnum (errno);
return -1; return -1;
} }
} }
@ -428,10 +562,20 @@ int qse_fio_init (
px = qse_wcstombs (path, &wl, path_mb, &ml); px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2) if (px == -2)
{ {
/* the static buffer is too small.
* allocate a buffer */
path_mb = qse_wcstombsdup (path, mmgr); 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 #endif
/* /*
* rwa -> RDWR | APPEND * rwa -> RDWR | APPEND
@ -481,6 +625,7 @@ int qse_fio_init (
if (handle == -1) if (handle == -1)
{ {
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
fio->errnum = syserr_to_errnum (errno);
return -1; return -1;
} }
@ -496,50 +641,12 @@ int qse_fio_init (
#endif #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; fio->handle = handle;
return 0; return 0;
} }
void qse_fio_fini (qse_fio_t* fio) 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 (!(fio->flags & QSE_FIO_NOCLOSE))
{ {
#if defined(_WIN32) #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) qse_fio_hnd_t qse_fio_gethandle (qse_fio_t* fio)
{ {
return fio->handle; 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 ( 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]); fio->handle, x.LowPart, &x.HighPart, seek_map[origin]);
if (x.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) 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)-1;
} }
return (qse_fio_off_t)x.QuadPart; return (qse_fio_off_t)x.QuadPart;
@ -628,7 +738,11 @@ qse_fio_off_t qse_fio_seek (
pos.ulHi = (ULONG)(offset>>32); pos.ulHi = (ULONG)(offset>>32);
ret = DosSetFilePtrL (fio->handle, pos, seek_map[origin], &newpos); 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; return ((qse_fio_off_t)pos.ulHi << 32) | pos.ulLo;
#elif defined(__DOS__) #elif defined(__DOS__)
@ -657,6 +771,7 @@ qse_fio_off_t qse_fio_seek (
&tmp, &tmp,
seek_map[origin]) == -1) seek_map[origin]) == -1)
{ {
fio->errnum = syserr_to_errnum (errno);
return (qse_fio_off_t)-1; 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; SetEndOfFile(fio->handle) == FALSE) return -1;
#endif #endif
if (qse_fio_seek (fio, size, QSE_FIO_BEGIN) == (qse_fio_off_t)-1) return -1; 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; return 0;
#elif defined(__OS2__) #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); sz.ulHi = (ULONG)(size>>32);
ret = DosSetFileSizeL (fio->handle, sz); 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__) #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 #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 #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) #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))) if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD)))
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, 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; return (qse_ssize_t)count;
#elif defined(__OS2__) #elif defined(__OS2__)
APIRET ret;
ULONG count; ULONG count;
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG))) if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG)))
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, ret = DosRead (fio->handle, buf, (ULONG)size, &count);
buf, (ULONG)size, &count) != NO_ERROR) return -1; if (ret != NO_ERROR)
{
fio->errnum = syserr_to_errnum (ret);
return -1;
}
return (qse_ssize_t)count; return (qse_ssize_t)count;
#elif defined(__DOS__) #elif defined(__DOS__)
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t))) int n;
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t); if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int)))
return read (fio->handle, buf, size); 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 #else
ssize_t n;
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t))) 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); 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 #endif
} }
qse_ssize_t qse_fio_read (qse_fio_t* fio, void* buf, qse_size_t size) qse_ssize_t qse_fio_write (qse_fio_t* fio, const void* data, 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)
{ {
#if defined(_WIN32) #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))) if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD)))
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, 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; return (qse_ssize_t)count;
#elif defined(__OS2__) #elif defined(__OS2__)
APIRET ret;
ULONG count; 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) if (fio->flags & QSE_FIO_APPEND)
{ {
/* i do this on a best-effort basis */ /* 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; pos.ulHi = (ULONG)0;
DosSetFilePtrL (fio->handle, pos, FILE_END, &newpos); 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 #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) #if defined(_WIN32)
static int get_devname_from_handle ( 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; HANDLE map = NULL;
void* mem = NULL; void* mem = NULL;
@ -816,19 +953,24 @@ static int get_devname_from_handle (
/* create a file mapping object */ /* create a file mapping object */
map = CreateFileMapping ( map = CreateFileMapping (
handle, fio->handle,
NULL, NULL,
PAGE_READONLY, PAGE_READONLY,
0, 0,
1, 1,
NULL 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. */ /* create a file mapping to get the file name. */
mem = MapViewOfFile (map, FILE_MAP_READ, 0, 0, 1); mem = MapViewOfFile (map, FILE_MAP_READ, 0, 0, 1);
if (mem == NULL) if (mem == NULL)
{ {
fio->errnum = syserr_to_errnum (GetLastError());
CloseHandle (map); CloseHandle (map);
return -1; return -1;
} }
@ -836,6 +978,7 @@ static int get_devname_from_handle (
olen = GetMappedFileName (GetCurrentProcess(), mem, buf, len); olen = GetMappedFileName (GetCurrentProcess(), mem, buf, len);
if (olen == 0) if (olen == 0)
{ {
fio->errnum = syserr_to_errnum (GetLastError());
UnmapViewOfFile (mem); UnmapViewOfFile (mem);
CloseHandle (map); CloseHandle (map);
return -1; return -1;
@ -847,9 +990,9 @@ static int get_devname_from_handle (
} }
static int get_volname_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\\"))) if (qse_strcasebeg (buf, QSE_T("\\Device\\LanmanRedirector\\")))
{ {
@ -866,6 +1009,7 @@ static int get_volname_from_handle (
if (n == 0 /* error */ || if (n == 0 /* error */ ||
n > QSE_COUNTOF(drives) /* buffer small */) n > QSE_COUNTOF(drives) /* buffer small */)
{ {
fio->errnum = syserr_to_errnum (GetLastError());
return -1; 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. * if GENERIC_READ is not set in CreateFile, CreateFileMapping fails.
* so if this fio is opened without QSE_FIO_READ, this function fails. * so if this fio is opened without QSE_FIO_READ, this function fails.
*/ */
if (get_volname_from_handle ( if (get_volname_from_handle (fio, name, QSE_COUNTOF(name)) == -1) return -1;
fio->handle, name, QSE_COUNTOF(name)) == -1) return -1;
if (!(mode & QSE_FIO_WUSR)) flags = FILE_ATTRIBUTE_READONLY; 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__) #elif defined(__OS2__)
APIRET n;
int flags = FILE_NORMAL; int flags = FILE_NORMAL;
FILESTATUS3L stat; FILESTATUS3L stat;
ULONG size = QSE_SIZEOF(stat); ULONG size = QSE_SIZEOF(stat);
if (DosQueryFileInfo (fio->handle, n = DosQueryFileInfo (fio->handle, FIL_STANDARDL, &stat, size);
FIL_STANDARDL, &stat, size) != NO_ERROR) return -1; if (n != NO_ERROR)
{
fio->errnum = syserr_to_errnum (n);
return -1;
}
if (!(mode & QSE_FIO_WUSR)) flags = FILE_READONLY; if (!(mode & QSE_FIO_WUSR)) flags = FILE_READONLY;
stat.attrFile = flags; 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__) #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 /* TODO: fchmod not available. find a way to do this
return fchmod (fio->handle, permission); */ return fchmod (fio->handle, permission); */
fio->errnum = QSE_FIO_ENOIMPL;
return -1; return -1;
#else #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 #endif
} }
@ -952,20 +1116,37 @@ int qse_fio_sync (qse_fio_t* fio)
{ {
#if defined(_WIN32) #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__) #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__) #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 #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 #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; * fl.l_type = F_RDLCK, F_WRLCK;
* QSE_FCNTL (fio->handle, F_SETLK, &fl); * QSE_FCNTL (fio->handle, F_SETLK, &fl);
*/ */
fio->errnum = QSE_FIO_ENOIMPL;
return -1; 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; * fl.l_type = F_UNLCK;
* QSE_FCNTL (fio->handle, F_SETLK, &fl); * QSE_FCNTL (fio->handle, F_SETLK, &fl);
*/ */
fio->errnum = QSE_FIO_ENOIMPL;
return -1; 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) int qse_getstdfiohandle (qse_fio_std_t std, qse_fio_hnd_t* hnd)
{ {
#if defined(_WIN32) #if defined(_WIN32)

View File

@ -34,8 +34,6 @@
# include <io.h> # include <io.h>
#else #else
# include "syscall.h" # include "syscall.h"
# include <fcntl.h>
# include <sys/wait.h>
# if defined(HAVE_SPAWN_H) # if defined(HAVE_SPAWN_H)
# include <spawn.h> # include <spawn.h>
# endif # endif
@ -43,8 +41,154 @@
QSE_IMPLEMENT_COMMON_FUNCTIONS (pio) 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_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);
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_pio_t* qse_pio_open (
qse_mmgr_t* mmgr, qse_size_t ext, 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 (QSE_ACCESS(path, X_OK) <= -1)
{ {
if (errno == EACCES) pio->errnum = QSE_PIO_EACCES; pio->errnum = syserr_to_errnum (errno);
else if (errno == ENOENT) pio->errnum = QSE_PIO_ENOENT;
else if (errno == ENOMEM) pio->errnum = QSE_PIO_ENOMEM;
return -1; 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; pio->errnum = syserr_to_errnum (errno);
else if (errno == ENOENT) pio->errnum = QSE_PIO_ENOENT;
else if (errno == ENOMEM) pio->errnum = QSE_PIO_ENOMEM;
return -1; return -1;
} }
@ -1063,7 +1204,11 @@ int qse_pio_init (
posix_spawn_file_actions_destroy (&fa); posix_spawn_file_actions_destroy (&fa);
fa_inited = 0; fa_inited = 0;
} }
if (spawn_ret != 0) goto oops; if (spawn_ret != 0)
{
pio->errnum = syserr_to_errnum (errno);
goto oops;
}
pio->child = pid; pio->child = pid;
if (flags & QSE_PIO_WRITEIN) if (flags & QSE_PIO_WRITEIN)
@ -1293,20 +1438,25 @@ int qse_pio_init (
{ {
int r; 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) if (tio[i] == QSE_NULL)
{ {
pio->errnum = QSE_PIO_ENOMEM; pio->errnum = QSE_PIO_ENOMEM;
goto oops; goto oops;
} }
r = (i == QSE_PIO_IN)? /**(qse_pio_pin_t**)qse_tio_getxtn(tio[i]) = &pio->pin[i]; */
qse_tio_attachout ( *(qse_pio_pin_t**)QSE_XTN(tio[i]) = &pio->pin[i];
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; r = (i == QSE_PIO_IN)?
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]; pio->pin[i].tio = tio[i];
} }
@ -1402,28 +1552,6 @@ qse_pio_errnum_t qse_pio_geterrnum (qse_pio_t* pio)
return pio->errnum; 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) qse_cmgr_t* qse_pio_getcmgr (qse_pio_t* pio, qse_pio_hid_t hid)
{ {
return pio->pin[hid].tio? return pio->pin[hid].tio?
@ -1493,7 +1621,7 @@ static qse_ssize_t pio_read (
/* ReadFile receives ERROR_BROKEN_PIPE when the write end /* ReadFile receives ERROR_BROKEN_PIPE when the write end
* is closed in the child process */ * is closed in the child process */
if (GetLastError() == ERROR_BROKEN_PIPE) return 0; if (GetLastError() == ERROR_BROKEN_PIPE) return 0;
pio->errnum = QSE_PIO_ESUBSYS; pio->errnum = syserr_to_errnum(GetLastError());
return -1; return -1;
} }
return (qse_ssize_t)count; return (qse_ssize_t)count;
@ -1507,7 +1635,7 @@ static qse_ssize_t pio_read (
if (rc != NO_ERROR) if (rc != NO_ERROR)
{ {
if (rc == ERROR_BROKEN_PIPE) return 0; /* TODO: check this */ if (rc == ERROR_BROKEN_PIPE) return 0; /* TODO: check this */
pio->errnum = QSE_PIO_ESUBSYS; pio->errnum = syserr_to_errnum(rc);
return -1; return -1;
} }
return (qse_ssize_t)count; 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); size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int);
n = read (hnd, buf, size); n = read (hnd, buf, size);
if (n == -1) pio->errnum = QSE_PIO_ESUBSYS; if (n <= -1) pio->errnum = syserr_to_errnum(errno);
return n; return n;
#else #else
@ -1529,7 +1657,7 @@ static qse_ssize_t pio_read (
reread: reread:
n = QSE_READ (hnd, buf, size); n = QSE_READ (hnd, buf, size);
if (n == -1) if (n <= -1)
{ {
if (errno == EINTR) if (errno == EINTR)
{ {
@ -1537,13 +1665,9 @@ reread:
pio->errnum = QSE_PIO_EINTR; pio->errnum = QSE_PIO_EINTR;
else goto reread; else goto reread;
} }
else if (errno == EPIPE)
{
pio->errnum = QSE_PIO_EPIPE;
}
else 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) if (pio->pin[hid].tio == QSE_NULL)
return pio_read (pio, buf, size, pio->pin[hid].handle); return pio_read (pio, buf, size, pio->pin[hid].handle);
else 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 ( static qse_ssize_t pio_write (
@ -1578,7 +1711,7 @@ static qse_ssize_t pio_write (
{ {
/* the stream is already closed */ /* the stream is already closed */
pio->errnum = QSE_PIO_ENOHND; pio->errnum = QSE_PIO_ENOHND;
return -1; return (qse_ssize_t)-1;
} }
#if defined(_WIN32) #if defined(_WIN32)
@ -1588,8 +1721,7 @@ static qse_ssize_t pio_write (
if (WriteFile (hnd, data, (DWORD)size, &count, QSE_NULL) == FALSE) if (WriteFile (hnd, data, (DWORD)size, &count, QSE_NULL) == FALSE)
{ {
pio->errnum = (GetLastError() == ERROR_BROKEN_PIPE)? pio->errnum = syserr_to_errnum(GetLastError());
QSE_PIO_EPIPE: QSE_PIO_ESUBSYS;
return -1; return -1;
} }
return (qse_ssize_t)count; return (qse_ssize_t)count;
@ -1602,8 +1734,7 @@ static qse_ssize_t pio_write (
rc = DosWrite (hnd, (PVOID)data, (ULONG)size, &count); rc = DosWrite (hnd, (PVOID)data, (ULONG)size, &count);
if (rc != NO_ERROR) if (rc != NO_ERROR)
{ {
pio->errnum = (rc == ERROR_BROKEN_PIPE)? pio->errnum = syserr_to_errnum(rc);
QSE_PIO_EPIPE: QSE_PIO_ESUBSYS; /* TODO: check this */
return -1; return -1;
} }
return (qse_ssize_t)count; 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); size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int);
n = write (hnd, data, size); n = write (hnd, data, size);
if (n == -1) pio->errnum = QSE_PIO_ESUBSYS; if (n <= -1) pio->errnum = syserro_to_errnum (errno);
return n; return n;
#else #else
@ -1624,7 +1755,7 @@ static qse_ssize_t pio_write (
rewrite: rewrite:
n = QSE_WRITE (hnd, data, size); n = QSE_WRITE (hnd, data, size);
if (n == -1) if (n <= -1)
{ {
if (errno == EINTR) if (errno == EINTR)
{ {
@ -1632,13 +1763,9 @@ rewrite:
pio->errnum = QSE_PIO_EINTR; pio->errnum = QSE_PIO_EINTR;
else goto rewrite; else goto rewrite;
} }
else if (errno == EPIPE)
{
pio->errnum = QSE_PIO_EPIPE;
}
else else
{ {
pio->errnum = QSE_PIO_ESUBSYS; pio->errnum = syserr_to_errnum (errno);
} }
} }
return n; return n;
@ -1653,13 +1780,30 @@ qse_ssize_t qse_pio_write (
if (pio->pin[hid].tio == QSE_NULL) if (pio->pin[hid].tio == QSE_NULL)
return pio_write (pio, data, size, pio->pin[hid].handle); return pio_write (pio, data, size, pio->pin[hid].handle);
else 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 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; 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) 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; pio->errnum = QSE_PIO_EINTR;
else continue; else continue;
} }
else pio->errnum = QSE_PIO_ESUBSYS; else pio->errnum = syserr_to_errnum (errno);
break; break;
} }
@ -1910,12 +2054,13 @@ int qse_pio_kill (qse_pio_t* pio)
} }
static qse_ssize_t pio_input ( 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) 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); QSE_ASSERT (pin->self != QSE_NULL);
return pio_read (pin->self, buf, size, pin->handle); 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 ( 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) 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); QSE_ASSERT (pin->self != QSE_NULL);
return pio_write (pin->self, buf, size, pin->handle); return pio_write (pin->self, buf, size, pin->handle);
} }

View File

@ -21,13 +21,73 @@
#include <qse/cmn/sio.h> #include <qse/cmn/sio.h>
#include "mem.h" #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) #if defined(_WIN32)
# include <windows.h> /* for the UGLY hack */ # include <windows.h> /* for the UGLY hack */
#elif defined(__OS2__)
/* nothing */
#elif defined(__DOS__)
/* nothing */
#else
# include "syscall.h"
#endif #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_sio_t* qse_sio_open (
qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_char_t* file, int flags) 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 | mode = QSE_FIO_RUSR | QSE_FIO_WUSR |
QSE_FIO_RGRP | QSE_FIO_ROTH; QSE_FIO_RGRP | QSE_FIO_ROTH;
/* sio flags redefines most fio flags. fio can be opened in the /* sio flag enumerators redefines most fio flag enumerators and
* text mode. that way, fio is also buffered. since sio performs * compose a superset of fio flag enumerators. when a user calls
* its own buffering, i don't want a caller to specify text mode * this function, a user can specify a sio flag enumerator not
* flags accidentally. i mask off those bits here to avoid mishap. */ * present in the fio flag enumerator. mask off such an enumerator. */
if (qse_fio_init (&sio->fio, mmgr, file, if (qse_fio_init (
(flags & ~(QSE_FIO_TEXT|QSE_FIO_NOAUTOFLUSH)), mode) <= -1) return -1; &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_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR;
if (flags & QSE_SIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH; 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; 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 || if (qse_tio_attachin (&sio->tio.io, file_input, sio->inbuf, QSE_COUNTOF(sio->inbuf)) <= -1 ||
qse_tio_attachout (&sio->tio, __sio_output, sio, sio->outbuf, QSE_COUNTOF(sio->outbuf)) <= -1) qse_tio_attachout (&sio->tio.io, file_output, sio->outbuf, QSE_COUNTOF(sio->outbuf)) <= -1)
{ {
qse_tio_fini (&sio->tio); if (sio->errnum = QSE_SIO_ENOERR)
qse_fio_fini (&sio->fio); sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
qse_tio_fini (&sio->tio.io);
qse_fio_fini (&sio->u.file);
return -1; return -1;
} }
@ -136,49 +207,74 @@ void qse_sio_fini (qse_sio_t* sio)
{ {
/*if (qse_sio_flush (sio) <= -1) return -1;*/ /*if (qse_sio_flush (sio) <= -1) return -1;*/
qse_sio_flush (sio); qse_sio_flush (sio);
qse_tio_fini (&sio->tio); qse_tio_fini (&sio->tio.io);
qse_fio_fini (&sio->fio); qse_fio_fini (&sio->u.file);
} }
qse_cmgr_t* qse_sio_getcmgr (qse_sio_t* sio) 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) 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) 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) qse_sio_hnd_t qse_sio_gethandle (qse_sio_t* sio)
{ {
/*return qse_fio_gethandle (&sio->fio);*/ /*return qse_fio_gethandle (&sio->u.file);*/
return QSE_FIO_HANDLE(&sio->fio); 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) 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) 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) 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) 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 ( qse_ssize_t qse_sio_getmbs (
@ -193,9 +289,14 @@ qse_ssize_t qse_sio_getmbs (
* so I don't implement any hack here */ * so I don't implement any hack here */
#endif #endif
n = qse_tio_readmbs (&sio->tio, buf, size - 1); sio->errnum = QSE_SIO_ENOERR;
n = qse_tio_readmbs (&sio->tio.io, buf, size - 1);
if (n <= -1) return -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'); buf[n] = QSE_MT('\0');
return n; return n;
} }
@ -203,12 +304,17 @@ qse_ssize_t qse_sio_getmbs (
qse_ssize_t qse_sio_getmbsn ( qse_ssize_t qse_sio_getmbsn (
qse_sio_t* sio, qse_mchar_t* buf, qse_size_t size) qse_sio_t* sio, qse_mchar_t* buf, qse_size_t size)
{ {
qse_ssize_t n;
#if defined(_WIN32) #if defined(_WIN32)
/* Using ReadConsoleA() didn't help at all. /* Using ReadConsoleA() didn't help at all.
* so I don't implement any hack here */ * so I don't implement any hack here */
#endif #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 ( qse_ssize_t qse_sio_getwcs (
@ -223,9 +329,14 @@ qse_ssize_t qse_sio_getwcs (
* so I don't implement any hack here */ * so I don't implement any hack here */
#endif #endif
n = qse_tio_readwcs (&sio->tio, buf, size - 1); sio->errnum = QSE_SIO_ENOERR;
n = qse_tio_readwcs (&sio->tio.io, buf, size - 1);
if (n <= -1) return -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'); buf[n] = QSE_WT('\0');
return n; return n;
} }
@ -233,55 +344,98 @@ qse_ssize_t qse_sio_getwcs (
qse_ssize_t qse_sio_getwcsn ( qse_ssize_t qse_sio_getwcsn (
qse_sio_t* sio, qse_wchar_t* buf, qse_size_t size) qse_sio_t* sio, qse_wchar_t* buf, qse_size_t size)
{ {
qse_ssize_t n;
#if defined(_WIN32) #if defined(_WIN32)
/* Using ReadConsoleW() didn't help at all. /* Using ReadConsoleW() didn't help at all.
* so I don't implement any hack here */ * so I don't implement any hack here */
#endif #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) 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) 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 qse_sio_putmbs (qse_sio_t* sio, const qse_mchar_t* str)
{ {
qse_ssize_t n;
#if defined(_WIN32) #if defined(_WIN32)
/* Using WriteConsoleA() didn't help at all. /* Using WriteConsoleA() didn't help at all.
* so I don't implement any hack here */ * so I don't implement any hack here */
#endif #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_ssize_t qse_sio_putmbsn (
qse_sio_t* sio, const qse_mchar_t* str, qse_size_t size) qse_sio_t* sio, const qse_mchar_t* str, qse_size_t size)
{ {
qse_ssize_t n;
#if defined(_WIN32) #if defined(_WIN32)
/* Using WriteConsoleA() didn't help at all. /* Using WriteConsoleA() didn't help at all.
* so I don't implement any hack here */ * so I don't implement any hack here */
#endif #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 qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str)
{ {
qse_ssize_t n;
sio->errnum = QSE_SIO_ENOERR;
#if defined(_WIN32) #if defined(_WIN32)
/* DAMN UGLY: See comment in qse_sio_putwcsn() */ /* DAMN UGLY: See comment in qse_sio_putwcsn() */
if (sio->status) if (sio->status)
{ {
DWORD mode; 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 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) for (cur = str, left = qse_wcslen(str); left > 0; cur += count, left -= count)
{ {
if (WriteConsoleW ( if (WriteConsoleW (
sio->fio.handle, cur, left, sio->u.file.handle, cur, left,
&count, QSE_NULL) == FALSE) return -1; &count, QSE_NULL) == FALSE)
{
sio->errnum = QSE_SIO_EOTHER;
return -1;
}
if (count == 0) break; if (count == 0) break;
} }
return cur - str; return cur - str;
@ -300,12 +458,19 @@ qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str)
} }
#endif #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_ssize_t qse_sio_putwcsn (
qse_sio_t* sio, const qse_wchar_t* str, qse_size_t size) 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) #if defined(_WIN32)
/* DAMN UGLY: /* DAMN UGLY:
* WriteFile returns wrong number of bytes written if it is * WriteFile returns wrong number of bytes written if it is
@ -323,9 +488,12 @@ qse_ssize_t qse_sio_putwcsn (
{ {
DWORD mode; 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 else
{ {
@ -336,7 +504,7 @@ qse_ssize_t qse_sio_putwcsn (
for (cur = str, left = size; left > 0; cur += count, left -= count) for (cur = str, left = size; left > 0; cur += count, left -= count)
{ {
if (WriteConsoleW ( if (WriteConsoleW (
sio->fio.handle, cur, left, sio->u.file.handle, cur, left,
&count, QSE_NULL) == FALSE) return -1; &count, QSE_NULL) == FALSE) return -1;
if (count == 0) break; if (count == 0) break;
} }
@ -345,15 +513,22 @@ qse_ssize_t qse_sio_putwcsn (
} }
#endif #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) int qse_sio_getpos (qse_sio_t* sio, qse_sio_pos_t* pos)
{ {
qse_fio_off_t off; qse_fio_off_t off;
off = qse_fio_seek (&sio->fio, 0, QSE_FIO_CURRENT); off = qse_fio_seek (&sio->u.file, 0, QSE_FIO_CURRENT);
if (off == (qse_fio_off_t)-1) return -1; if (off == (qse_fio_off_t)-1)
{
sio->errnum = fio_errnum_to_sio_errnum (&sio->u.file);
return -1;
}
*pos = off; *pos = off;
return 0; return 0;
@ -364,9 +539,14 @@ int qse_sio_setpos (qse_sio_t* sio, qse_sio_pos_t pos)
qse_fio_off_t off; qse_fio_off_t off;
if (qse_sio_flush(sio) <= -1) return -1; if (qse_sio_flush(sio) <= -1) return -1;
off = qse_fio_seek (&sio->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 #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.... */ * can move to the end of the stream also.... */
if (qse_sio_flush(sio) <= -1) return -1; if (qse_sio_flush(sio) <= -1) return -1;
return (qse_fio_seek (&sio->fio, return (qse_fio_seek (&sio->u.file,
0, QSE_FIO_END) == (qse_fio_off_t)-1)? -1: 0; 0, QSE_FIO_END) == (qse_fio_off_t)-1)? -1: 0;
/* TODO: write this function */ /* TODO: write this function */
if (qse_sio_flush(sio) <= -1) return -1; if (qse_sio_flush(sio) <= -1) return -1;
return (qse_fio_seek (&sio->fio, return (qse_fio_seek (&sio->u.file,
0, QSE_FIO_BEGIN) == (qse_fio_off_t)-1)? -1: 0; 0, QSE_FIO_BEGIN) == (qse_fio_off_t)-1)? -1: 0;
} }
#endif #endif
static qse_ssize_t __sio_input ( static qse_ssize_t file_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_sio_t* sio = (qse_sio_t*)arg;
QSE_ASSERT (sio != QSE_NULL);
if (cmd == QSE_TIO_DATA) 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; return 0;
} }
static qse_ssize_t __sio_output ( static qse_ssize_t file_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_sio_t* sio = (qse_sio_t*)arg;
QSE_ASSERT (sio != QSE_NULL);
if (cmd == QSE_TIO_DATA) 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; 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

@ -38,6 +38,9 @@
#ifdef HAVE_ERRNO_H #ifdef HAVE_ERRNO_H
# include <errno.h> # include <errno.h>
#endif #endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_TIME_H #ifdef HAVE_TIME_H
# include <time.h> # include <time.h>
#endif #endif

View File

@ -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) if (tio->inbuf_cur >= tio->inbuf_len)
{ {
tio->errnum = QSE_TIO_ENOERR;
n = tio->in.fun ( n = tio->in.fun (
QSE_TIO_DATA, tio->in.arg, tio, QSE_TIO_DATA,
tio->in.buf.ptr, tio->in.buf.ptr, tio->in.buf.capa);
tio->in.buf.capa);
if (n == 0) break; if (n == 0) break;
if (n <= -1) if (n <= -1)
{ {
tio->errnum = QSE_TIO_EIOERR; if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER;
return -1; return -1;
} }
@ -93,8 +93,9 @@ static QSE_INLINE qse_ssize_t tio_read_widechars (
if (tio->input_status & STATUS_EOF) n = 0; if (tio->input_status & STATUS_EOF) n = 0;
else else
{ {
tio->errnum = QSE_TIO_ENOERR;
n = tio->in.fun ( n = tio->in.fun (
QSE_TIO_DATA, tio->in.arg, tio, QSE_TIO_DATA,
&tio->in.buf.ptr[tio->inbuf_len], &tio->in.buf.ptr[tio->inbuf_len],
tio->in.buf.capa - 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) if (n <= -1)
{ {
tio->errnum = QSE_TIO_EIOERR; if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER;
return -1; return -1;
} }

View File

@ -92,28 +92,6 @@ qse_tio_errnum_t qse_tio_geterrnum (qse_tio_t* tio)
return tio->errnum; 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) qse_cmgr_t* qse_tio_getcmgr (qse_tio_t* tio)
{ {
return tio->cmgr; return tio->cmgr;
@ -125,7 +103,7 @@ void qse_tio_setcmgr (qse_tio_t* tio, qse_cmgr_t* cmgr)
} }
int qse_tio_attachin ( 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* bufptr, qse_size_t bufcapa)
{ {
qse_mchar_t* xbufptr; 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); if (xbufptr != bufptr) QSE_MMGR_FREE (tio->mmgr, xbufptr);
tio->errnum = QSE_TIO_EIOERR;
return -1; return -1;
} }
@ -167,7 +146,6 @@ int qse_tio_attachin (
*/ */
tio->in.fun = input; tio->in.fun = input;
tio->in.arg = arg;
tio->in.buf.ptr = xbufptr; tio->in.buf.ptr = xbufptr;
tio->in.buf.capa = bufcapa; 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)
{ {
if (tio->in.fun ( tio->errnum = QSE_TIO_ENOERR;
QSE_TIO_CLOSE, tio->in.arg, QSE_NULL, 0) <= -1) 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 */ /* returning with an error here allows you to retry detaching */
if (!fini) return -1; 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.fun = QSE_NULL;
tio->in.arg = QSE_NULL;
tio->in.buf.ptr = QSE_NULL; tio->in.buf.ptr = QSE_NULL;
tio->in.buf.capa = 0; tio->in.buf.capa = 0;
} }
@ -219,7 +196,7 @@ int qse_tio_detachin (qse_tio_t* tio)
} }
int qse_tio_attachout ( 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* bufptr, qse_size_t bufcapa)
{ {
qse_mchar_t* xbufptr; 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); if (xbufptr != bufptr) QSE_MMGR_FREE (tio->mmgr, xbufptr);
tio->errnum = QSE_TIO_EIOERR;
return -1; return -1;
} }
tio->out.fun = output; tio->out.fun = output;
tio->out.arg = arg;
tio->out.buf.ptr = xbufptr; tio->out.buf.ptr = xbufptr;
tio->out.buf.capa = bufcapa; 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 */ qse_tio_flush (tio); /* don't care about the result */
if (tio->out.fun ( tio->errnum = QSE_TIO_ENOERR;
QSE_TIO_CLOSE, tio->out.arg, QSE_NULL, 0) <= -1) 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 */ /* returning with an error here allows you to retry detaching */
if (!fini) return -1; 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.fun = QSE_NULL;
tio->out.arg = QSE_NULL;
tio->out.buf.ptr = QSE_NULL; tio->out.buf.ptr = QSE_NULL;
tio->out.buf.capa = 0; tio->out.buf.capa = 0;
} }
@ -320,13 +296,13 @@ qse_ssize_t qse_tio_flush (qse_tio_t* tio)
cur = tio->out.buf.ptr; cur = tio->out.buf.ptr;
while (left > 0) while (left > 0)
{ {
n = tio->out.fun ( tio->errnum = QSE_TIO_ENOERR;
QSE_TIO_DATA, tio->out.arg, cur, left); n = tio->out.fun (tio, QSE_TIO_DATA, cur, left);
if (n <= -1) if (n <= -1)
{ {
if (tio->errnum == QSE_TIO_ENOERR) tio->errnum = QSE_TIO_EOTHER;
QSE_MEMCPY (tio->out.buf.ptr, cur, left); QSE_MEMCPY (tio->out.buf.ptr, cur, left);
tio->outbuf_len = left; tio->outbuf_len = left;
tio->errnum = QSE_TIO_EIOERR;
return -1; return -1;
} }
if (n == 0) if (n == 0)

View File

@ -209,7 +209,6 @@ static qse_mchar_t* parse_initial_line (
{ {
qse_mchar_t* p = line; qse_mchar_t* p = line;
qse_mcstr_t tmp; qse_mcstr_t tmp;
qse_http_method_t mtype;
#if 0 #if 0
/* ignore leading spaces excluding crlf */ /* ignore leading spaces excluding crlf */
@ -225,10 +224,9 @@ static qse_mchar_t* parse_initial_line (
tmp.len = p - tmp.ptr; tmp.len = p - tmp.ptr;
htrd->retype = QSE_HTRD_RETYPE_Q; htrd->retype = QSE_HTRD_RETYPE_Q;
if ((htrd->option & QSE_HTRD_REQUEST) && if (htrd->option & QSE_HTRD_REQUEST)
qse_gethttpmethodtypefromstr (&tmp, &mtype) >= 0)
{ {
qse_htre_setqmethod (&htrd->re, mtype); qse_htre_setqmethod (&htrd->re, qse_mcstrtohttpmethod (&tmp));
} }
else if ((htrd->option & QSE_HTRD_RESPONSE) && else if ((htrd->option & QSE_HTRD_RESPONSE) &&
qse_mbsxcmp (tmp.ptr, tmp.len, QSE_MT("HTTP")) == 0) qse_mbsxcmp (tmp.ptr, tmp.len, QSE_MT("HTTP")) == 0)

View File

@ -95,7 +95,8 @@ struct header_walker_ctx_t
int ret; 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; 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) 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) 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);
} }

View File

@ -31,17 +31,20 @@ int qse_comparehttpversions (
return v1->major - v2->major; 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[] = static qse_mchar_t* names[] =
{ {
QSE_MT("GET"), QSE_MT("OTHER"),
QSE_MT("HEAD"), QSE_MT("HEAD"),
QSE_MT("GET"),
QSE_MT("POST"), QSE_MT("POST"),
QSE_MT("PUT"), QSE_MT("PUT"),
QSE_MT("DELETE"), QSE_MT("DELETE"),
QSE_MT("TRACE"),
QSE_MT("OPTIONS"), QSE_MT("OPTIONS"),
QSE_MT("TRACE"),
QSE_MT("CONNECT") QSE_MT("CONNECT")
}; };
@ -67,11 +70,8 @@ static struct mtab_t mtab[] =
{ QSE_MT("TRACE"), QSE_HTTP_TRACE } { QSE_MT("TRACE"), QSE_HTTP_TRACE }
}; };
int qse_gethttpmethodtype ( qse_http_method_t qse_mbstohttpmethod (const qse_mchar_t* name)
const qse_mchar_t* name,
qse_http_method_t* type)
{ {
/* perform binary search */ /* perform binary search */
/* declaring left, right, mid to be of int is ok /* declaring left, right, mid to be of int is ok
@ -96,19 +96,13 @@ int qse_gethttpmethodtype (
right = mid - 1; right = mid - 1;
} }
else if (n > 0) left = mid + 1; else if (n > 0) left = mid + 1;
else else return entry->type;
{
*type = entry->type;
return 0;
}
} }
return -1; return QSE_HTTP_OTHER;
} }
int qse_gethttpmethodtypefromstr ( qse_http_method_t qse_mcstrtohttpmethod (const qse_mcstr_t* name)
const qse_mcstr_t* name,
qse_http_method_t* type)
{ {
/* perform binary search */ /* perform binary search */
@ -134,14 +128,10 @@ int qse_gethttpmethodtypefromstr (
right = mid - 1; right = mid - 1;
} }
else if (n > 0) left = mid + 1; else if (n > 0) left = mid + 1;
else else return entry->type;
{
*type = entry->type;
return 0;
}
} }
return -1; return QSE_HTTP_OTHER;
} }
int qse_parsehttprange (const qse_mchar_t* str, qse_http_range_t* range) int qse_parsehttprange (const qse_mchar_t* str, qse_http_range_t* range)

View File

@ -2079,9 +2079,9 @@ static void task_fini_cgi (
if (cgi->pio_inited) if (cgi->pio_inited)
{ {
/* kill cgi in case it is still alive. /* 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_kill (&cgi->pio);
qse_pio_close (&cgi->pio); qse_pio_fini (&cgi->pio);
} }
if (cgi->res) qse_mbs_close (cgi->res); if (cgi->res) qse_mbs_close (cgi->res);
if (cgi->htrd) qse_htrd_close (cgi->htrd); if (cgi->htrd) qse_htrd_close (cgi->htrd);

View File

@ -22,7 +22,7 @@ static int test1 (void)
fio = qse_fio_open ( fio = qse_fio_open (
QSE_MMGR_GETDFL(), QSE_MMGR_GETDFL(),
0, 0,
QSE_T("fio1.txt"), QSE_T("fio01-1.txt"),
QSE_FIO_READ|QSE_FIO_WRITE|QSE_FIO_CREATE|QSE_FIO_TRUNCATE, QSE_FIO_READ|QSE_FIO_WRITE|QSE_FIO_CREATE|QSE_FIO_TRUNCATE,
QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH
); );
@ -107,7 +107,7 @@ static int test2 (void)
fio = qse_fio_open ( fio = qse_fio_open (
QSE_MMGR_GETDFL(), QSE_MMGR_GETDFL(),
0, 0,
QSE_T("fio2.txt"), QSE_T("fio01-2.txt"),
QSE_FIO_CREATE | QSE_FIO_TRUNCATE | QSE_FIO_APPEND, QSE_FIO_CREATE | QSE_FIO_TRUNCATE | QSE_FIO_APPEND,
QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH 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_fio_t* fio;
qse_ssize_t n; 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_fio_off_t off;
qse_char_t buf[1000]; qse_mchar_t buf[1000];
fio = qse_fio_open ( fio = qse_fio_open (
QSE_MMGR_GETDFL(), QSE_MMGR_GETDFL(),
0, 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_CREATE | QSE_FIO_TRUNCATE,
QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH QSE_FIO_RUSR|QSE_FIO_WUSR|QSE_FIO_RGRP|QSE_FIO_ROTH
@ -236,29 +236,24 @@ static int test3 (void)
return -1; 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); 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); off = qse_fio_seek (fio, 0, QSE_FIO_BEGIN);
if (off == (qse_fio_off_t)-1) if (off == (qse_fio_off_t)-1)
{ {
qse_printf (QSE_T("failed to get file offset\n")); qse_printf (QSE_T("failed to get file offset\n"));
} }
n = qse_fio_read (fio, buf, QSE_COUNTOF(buf)); n = qse_fio_read (fio, buf, QSE_COUNTOF(buf));
qse_printf (QSE_T("read %d chars\n"), (int)n); qse_printf (QSE_T("read %d chars\n"), (int)n);
if (n > 0) 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); qse_fio_close (fio);
return 0; return 0;
} }
@ -275,7 +270,7 @@ int main ()
R (test3); R (test3);
qse_printf (QSE_T("--------------------------------------------------------------------------------\n")); 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")); qse_printf (QSE_T("--------------------------------------------------------------------------------\n"));
return 0; return 0;

View File

@ -52,8 +52,8 @@ static int pio1 (const qse_char_t* cmd, qse_env_t* env, int oflags, qse_pio_hid_
if (n <= -1) if (n <= -1)
{ {
qse_printf ( qse_printf (
QSE_T("qse_pio_read() returned error - %s\n"), QSE_T("qse_pio_read() returned error - %d\n"),
qse_pio_geterrmsg(pio) (int)qse_pio_geterrnum(pio)
); );
break; 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); qse_printf (QSE_T("qse_pio_wait returns %d\n"), x);
if (x <= -1) if (x <= -1)
{ {
qse_printf (QSE_T("error code : %d, error string: %s\n"), qse_printf (QSE_T("error code : %d\n"), (int)qse_pio_geterrnum(pio));
(int)qse_pio_geterrnum(pio), qse_pio_geterrmsg(pio));
} }
qse_pio_close (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) if (n < 0)
{ {
qse_printf ( qse_printf (
QSE_T("qse_pio_read() returned error - %s\n"), QSE_T("qse_pio_read() returned error - %d\n"),
qse_pio_geterrmsg(pio) (int)qse_pio_geterrnum(pio)
); );
break; 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); qse_printf (QSE_T("qse_pio_wait returns %d\n"), x);
if (x <= -1) if (x <= -1)
{ {
qse_printf (QSE_T("error code : %d, error string: %s\n"), qse_printf (QSE_T("error code : %d\n"), (int)qse_pio_geterrnum(pio));
(int)qse_pio_geterrnum(pio), qse_pio_geterrmsg(pio));
} }
qse_pio_close (pio); qse_pio_close (pio);
@ -394,7 +392,7 @@ static int test13 (void)
qse_printf (QSE_T("qse_pio_wait returns %d\n"), x); qse_printf (QSE_T("qse_pio_wait returns %d\n"), x);
if (x == -1) 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); qse_pio_close (pio);

View File

@ -30,6 +30,7 @@
# include <sys/sendfile.h> # include <sys/sendfile.h>
#endif #endif
/* TODO: WIN32 TransmitFile */
#if defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE64) #if defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE64)
# if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) # if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64)
# define xsendfile sendfile64 # define xsendfile sendfile64
@ -270,6 +271,7 @@ qse_printf (QSE_T("opening file [%hs] for reading\n"), path);
return -1; return -1;
} }
/* check if it is a link. symbolic link??? */
if (!S_ISREG(st.st_mode)) if (!S_ISREG(st.st_mode))
{ {
qse_httpd_seterrnum (httpd, QSE_HTTPD_EACCES); qse_httpd_seterrnum (httpd, QSE_HTTPD_EACCES);