enhanced error handling of sio,pio,tio
This commit is contained in:
		
							
								
								
									
										4
									
								
								qse/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								qse/configure
									
									
									
									
										vendored
									
									
								
							| @ -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" | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -28,49 +28,62 @@ | ||||
| #include <qse/types.h> | ||||
| #include <qse/macros.h> | ||||
|  | ||||
| #include <qse/cmn/tio.h> | ||||
|  | ||||
| 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 <qse/cmn/sio.h>. 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. | ||||
|  * | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
| @ -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 | ||||
| ); | ||||
|  | ||||
| @ -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 | ||||
| ); | ||||
|  | ||||
| @ -70,6 +70,9 @@ | ||||
| /* Define to 1 if you have the `expl' function. */ | ||||
| #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. */ | ||||
| #undef HAVE_FDOPENDIR | ||||
|  | ||||
| @ -279,6 +282,9 @@ | ||||
| /* Define to 1 if you have the <sys/types.h> header file. */ | ||||
| #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. */ | ||||
| #undef HAVE_TAN | ||||
|  | ||||
|  | ||||
| @ -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 ( | ||||
|  | ||||
| @ -20,10 +20,10 @@ | ||||
|  | ||||
| #include <qse/cmn/fio.h> | ||||
| #include <qse/cmn/str.h> | ||||
| #include <qse/cmn/mbwc.h> | ||||
| #include <qse/cmn/fmt.h> | ||||
| #include <qse/cmn/alg.h> | ||||
| #include <qse/cmn/time.h> | ||||
| #include <qse/cmn/mbwc.h> | ||||
| #include "mem.h" | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| @ -39,16 +39,120 @@ | ||||
| #	include <fcntl.h> | ||||
| #else | ||||
| #	include "syscall.h" | ||||
| #	include <sys/types.h> | ||||
| #	include <fcntl.h> | ||||
| #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) | ||||
|  | ||||
| @ -34,8 +34,6 @@ | ||||
| #	include <io.h> | ||||
| #else | ||||
| #	include "syscall.h" | ||||
| #	include <fcntl.h> | ||||
| #	include <sys/wait.h> | ||||
| #	if defined(HAVE_SPAWN_H) | ||||
| #		include <spawn.h> | ||||
| #	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); | ||||
| 	} | ||||
|  | ||||
| @ -21,13 +21,73 @@ | ||||
| #include <qse/cmn/sio.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) | ||||
| #	include <windows.h> /* 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 <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 | ||||
|  | ||||
| @ -38,6 +38,9 @@ | ||||
| #ifdef HAVE_ERRNO_H | ||||
| #	include <errno.h> | ||||
| #endif | ||||
| #ifdef HAVE_FCNTL_H | ||||
| #	include <fcntl.h> | ||||
| #endif | ||||
| #ifdef HAVE_TIME_H | ||||
| #	include <time.h> | ||||
| #endif | ||||
|  | ||||
| @ -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; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| @ -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)  | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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); | ||||
| } | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -30,6 +30,7 @@ | ||||
| #	include <sys/sendfile.h> | ||||
| #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); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user