enhanced sio,pio,fio to support win9x
fixed minor bugs in sio,pio,fio
This commit is contained in:
@ -179,6 +179,7 @@ SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TRUE = @TRUE@
|
||||
UNICOWS_LIBS = @UNICOWS_LIBS@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
@ -206,6 +206,7 @@ SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TRUE = @TRUE@
|
||||
UNICOWS_LIBS = @UNICOWS_LIBS@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
@ -100,9 +100,9 @@ libqsecmn_la_SOURCES = \
|
||||
|
||||
libqsecmn_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
|
||||
|
||||
if WIN32
|
||||
libqsecmn_la_LIBADD = -lpsapi
|
||||
endif
|
||||
#if WIN32
|
||||
#libqsecmn_la_LIBADD = -lpsapi
|
||||
#endif
|
||||
|
||||
if ENABLE_CXX
|
||||
|
||||
|
@ -35,6 +35,10 @@ PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
|
||||
#if WIN32
|
||||
#libqsecmn_la_LIBADD = -lpsapi
|
||||
#endif
|
||||
@ENABLE_CXX_TRUE@am__append_1 = libqsecmnxx.la
|
||||
subdir = lib/cmn
|
||||
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
|
||||
@ -74,7 +78,7 @@ am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libqsecmn_la_DEPENDENCIES =
|
||||
libqsecmn_la_LIBADD =
|
||||
am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \
|
||||
assert.lo chr.lo dll.lo env.lo gdl.lo htb.lo lda.lo fio.lo \
|
||||
fma.lo fmt.lo fs.lo fs-err.lo fs-move.lo hton.lo ipad.lo \
|
||||
@ -220,6 +224,7 @@ SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TRUE = @TRUE@
|
||||
UNICOWS_LIBS = @UNICOWS_LIBS@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
@ -373,7 +378,6 @@ libqsecmn_la_SOURCES = \
|
||||
xma.c
|
||||
|
||||
libqsecmn_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
|
||||
@WIN32_TRUE@libqsecmn_la_LIBADD = -lpsapi
|
||||
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
|
||||
@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <psapi.h> /* for GetMappedFileName() */
|
||||
/*# include <psapi.h>*/ /* for GetMappedFileName(). but dynamically loaded */
|
||||
# include <tchar.h>
|
||||
#elif defined(__OS2__)
|
||||
# define INCL_DOSFILEMGR
|
||||
@ -41,6 +41,12 @@
|
||||
# include "syscall.h"
|
||||
#endif
|
||||
|
||||
/* internal status codes */
|
||||
enum
|
||||
{
|
||||
STATUS_APPEND = (1 << 0),
|
||||
STATUS_NOCLOSE = (1 << 1)
|
||||
};
|
||||
|
||||
QSE_IMPLEMENT_COMMON_FUNCTIONS (fio)
|
||||
|
||||
@ -188,21 +194,35 @@ int qse_fio_init (
|
||||
qse_char_t* temp_ptr;
|
||||
qse_size_t temp_tries;
|
||||
|
||||
#if defined(_WIN32)
|
||||
int fellback = 0;
|
||||
#endif
|
||||
|
||||
QSE_MEMSET (fio, 0, QSE_SIZEOF(*fio));
|
||||
fio->mmgr = mmgr;
|
||||
|
||||
/* Store the flags for later use though only OS/2 needs
|
||||
* this at this moment */
|
||||
fio->flags = flags;
|
||||
if (!(flags & (QSE_FIO_READ | QSE_FIO_WRITE | QSE_FIO_APPEND | QSE_FIO_HANDLE)))
|
||||
{
|
||||
/* one of QSE_FIO_READ, QSE_FIO_WRITE, QSE_FIO_APPEND,
|
||||
* and QSE_FIO_HANDLE must be specified */
|
||||
fio->errnum = QSE_FIO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Store some flags for later use */
|
||||
if (flags & QSE_FIO_NOCLOSE)
|
||||
fio->status |= STATUS_NOCLOSE;
|
||||
|
||||
if (flags & QSE_FIO_TEMPORARY)
|
||||
{
|
||||
qse_ntime_t now;
|
||||
|
||||
QSE_ASSERTX (
|
||||
(flags & QSE_FIO_HANDLE) == 0,
|
||||
"QSE_FIO_TEMPORARY and QSE_FIO_HANDLE are mutually exclusive"
|
||||
);
|
||||
if (flags & QSE_FIO_HANDLE)
|
||||
{
|
||||
/* QSE_FIO_TEMPORARY and QSE_FIO_HANDLE are mutually exclusive */
|
||||
fio->errnum = QSE_FIO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
temp_no = 0;
|
||||
/* if QSE_FIO_TEMPORARY is used, the path name must
|
||||
@ -258,6 +278,10 @@ int qse_fio_init (
|
||||
if (flags & QSE_FIO_HANDLE)
|
||||
{
|
||||
handle = *(qse_fio_hnd_t*)path;
|
||||
QSE_ASSERTX (
|
||||
handle != INVALID_HANDLE_VALUE,
|
||||
"Do not specify an invalid handle value"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -266,11 +290,21 @@ int qse_fio_init (
|
||||
DWORD creation_disposition = 0;
|
||||
DWORD flag_and_attr = FILE_ATTRIBUTE_NORMAL;
|
||||
|
||||
if (fellback) share_mode &= ~FILE_SHARE_DELETE;
|
||||
|
||||
if (flags & QSE_FIO_APPEND)
|
||||
{
|
||||
/* this is not officially documented for CreateFile.
|
||||
* ZwCreateFile (kernel) seems to document it */
|
||||
desired_access |= FILE_APPEND_DATA;
|
||||
if (fellback)
|
||||
{
|
||||
desired_access |= GENERIC_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is not officially documented for CreateFile.
|
||||
* ZwCreateFile (kernel) seems to document it */
|
||||
fio->status &= ~STATUS_APPEND;
|
||||
desired_access |= FILE_APPEND_DATA;
|
||||
}
|
||||
}
|
||||
else if (flags & QSE_FIO_WRITE)
|
||||
{
|
||||
@ -318,12 +352,44 @@ int qse_fio_init (
|
||||
QSE_NULL, /* set noinherit by setting no secattr */
|
||||
creation_disposition, flag_and_attr, 0
|
||||
);
|
||||
}
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
|
||||
fio->errnum = syserr_to_errnum(GetLastError());
|
||||
return -1;
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD e = GetLastError();
|
||||
if (!fellback && e == ERROR_INVALID_PARAMETER &&
|
||||
((share_mode & FILE_SHARE_DELETE) || (flags & QSE_FIO_APPEND)))
|
||||
{
|
||||
/* old windows fails with ERROR_INVALID_PARAMETER
|
||||
* when some advanced flags are used. so try again
|
||||
* with fallback flags */
|
||||
fellback = 1;
|
||||
|
||||
share_mode &= ~FILE_SHARE_DELETE;
|
||||
if (flags & QSE_FIO_APPEND)
|
||||
{
|
||||
fio->status |= STATUS_APPEND;
|
||||
desired_access &= ~FILE_APPEND_DATA;
|
||||
desired_access |= GENERIC_WRITE;
|
||||
}
|
||||
|
||||
handle = CreateFile (
|
||||
path, desired_access, share_mode,
|
||||
QSE_NULL, /* set noinherit by setting no secattr */
|
||||
creation_disposition, flag_and_attr, 0
|
||||
);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
|
||||
fio->errnum = syserr_to_errnum(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
|
||||
fio->errnum = syserr_to_errnum(e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* some special check */
|
||||
@ -383,6 +449,9 @@ int qse_fio_init (
|
||||
zero.ulLo = 0;
|
||||
zero.ulHi = 0;
|
||||
|
||||
if (flags & QSE_FIO_APPEND)
|
||||
fio->stats |= STATUS_APPEND;
|
||||
|
||||
if (flags & QSE_FIO_CREATE)
|
||||
{
|
||||
if (flags & QSE_FIO_EXCLUSIVE)
|
||||
@ -463,6 +532,10 @@ int qse_fio_init (
|
||||
if (flags & QSE_FIO_HANDLE)
|
||||
{
|
||||
handle = *(qse_fio_hnd_t*)path;
|
||||
QSE_ASSERTX (
|
||||
handle >= 0,
|
||||
"Do not specify an invalid handle value"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -544,6 +617,10 @@ int qse_fio_init (
|
||||
if (flags & QSE_FIO_HANDLE)
|
||||
{
|
||||
handle = *(qse_fio_hnd_t*)path;
|
||||
QSE_ASSERTX (
|
||||
handle >= 0,
|
||||
"Do not specify an invalid handle value"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -620,25 +697,23 @@ int qse_fio_init (
|
||||
#else
|
||||
if (path_mb != path_mb_buf) QSE_MMGR_FREE (mmgr, path_mb);
|
||||
#endif
|
||||
if (handle == -1)
|
||||
{
|
||||
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
|
||||
fio->errnum = syserr_to_errnum (errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set some file access hints */
|
||||
#if defined(POSIX_FADV_RANDOM)
|
||||
if (flags & QSE_FIO_RANDOM)
|
||||
posix_fadvise (handle, 0, 0, POSIX_FADV_RANDOM);
|
||||
#endif
|
||||
#if defined(POSIX_FADV_SEQUENTIAL)
|
||||
if (flags & QSE_FIO_SEQUENTIAL)
|
||||
posix_fadvise (handle, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (handle == -1)
|
||||
{
|
||||
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
|
||||
fio->errnum = syserr_to_errnum (errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set some file access hints */
|
||||
#if defined(POSIX_FADV_RANDOM)
|
||||
if (flags & QSE_FIO_RANDOM)
|
||||
posix_fadvise (handle, 0, 0, POSIX_FADV_RANDOM);
|
||||
#endif
|
||||
#if defined(POSIX_FADV_SEQUENTIAL)
|
||||
if (flags & QSE_FIO_SEQUENTIAL)
|
||||
posix_fadvise (handle, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
fio->handle = handle;
|
||||
@ -647,7 +722,7 @@ int qse_fio_init (
|
||||
|
||||
void qse_fio_fini (qse_fio_t* fio)
|
||||
{
|
||||
if (!(fio->flags & QSE_FIO_NOCLOSE))
|
||||
if (!(fio->status & STATUS_NOCLOSE))
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
CloseHandle (fio->handle);
|
||||
@ -701,7 +776,7 @@ qse_fio_off_t qse_fio_seek (
|
||||
QSE_ASSERT (QSE_SIZEOF(offset) <= QSE_SIZEOF(x.QuadPart));
|
||||
|
||||
/* SetFilePointerEx is not available on Windows NT 4.
|
||||
* So let's use SetFilePointerEx */
|
||||
* So let's use SetFilePointer */
|
||||
#if 0
|
||||
x.QuadPart = offset;
|
||||
if (SetFilePointerEx (fio->handle, x, &y, seek_map[origin]) == FALSE)
|
||||
@ -887,6 +962,14 @@ qse_ssize_t qse_fio_write (qse_fio_t* fio, const void* data, qse_size_t size)
|
||||
#if defined(_WIN32)
|
||||
|
||||
DWORD count;
|
||||
|
||||
if (fio->status & STATUS_APPEND)
|
||||
{
|
||||
/* TODO: only when FILE_APPEND_DATA failed??? how do i know this??? */
|
||||
/* i do this on a best-effort basis */
|
||||
SetFilePointer (fio->handle, 0, QSE_NULL, FILE_END);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -902,7 +985,7 @@ qse_ssize_t qse_fio_write (qse_fio_t* fio, const void* data, qse_size_t size)
|
||||
APIRET ret;
|
||||
ULONG count;
|
||||
|
||||
if (fio->flags & QSE_FIO_APPEND)
|
||||
if (fio->status & STATUS_APPEND)
|
||||
{
|
||||
/* i do this on a best-effort basis */
|
||||
LONGLONG pos, newpos;
|
||||
@ -950,6 +1033,36 @@ static int get_devname_from_handle (
|
||||
HANDLE map = NULL;
|
||||
void* mem = NULL;
|
||||
DWORD olen;
|
||||
HINSTANCE psapi;
|
||||
|
||||
typedef DWORD (WINAPI*getmappedfilename_t) (
|
||||
HANDLE hProcess,
|
||||
LPVOID lpv,
|
||||
LPTSTR lpFilename,
|
||||
DWORD nSize
|
||||
);
|
||||
getmappedfilename_t getmappedfilename;
|
||||
|
||||
/* try to load psapi.dll dynamially for
|
||||
* systems without it. direct linking to the library
|
||||
* may end up with dependency failure on such systems.
|
||||
* this way, the worst case is that this function simply
|
||||
* fails. */
|
||||
psapi = LoadLibrary (QSE_T("PSAPI.DLL"));
|
||||
if (!psapi)
|
||||
{
|
||||
fio->errnum = syserr_to_errnum (GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
getmappedfilename = (getmappedfilename_t)
|
||||
GetProcAddress (psapi, QSE_T("GetMappedFileName"));
|
||||
if (!getmappedfilename)
|
||||
{
|
||||
fio->errnum = syserr_to_errnum (GetLastError());
|
||||
FreeLibrary (psapi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create a file mapping object */
|
||||
map = CreateFileMapping (
|
||||
@ -962,7 +1075,8 @@ static int get_devname_from_handle (
|
||||
);
|
||||
if (map == NULL)
|
||||
{
|
||||
mem = MapViewOfFile (map, FILE_MAP_READ, 0, 0, 1);
|
||||
fio->errnum = syserr_to_errnum (GetLastError());
|
||||
FreeLibrary (psapi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -972,20 +1086,23 @@ static int get_devname_from_handle (
|
||||
{
|
||||
fio->errnum = syserr_to_errnum (GetLastError());
|
||||
CloseHandle (map);
|
||||
FreeLibrary (psapi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
olen = GetMappedFileName (GetCurrentProcess(), mem, buf, len);
|
||||
olen = getmappedfilename (GetCurrentProcess(), mem, buf, len);
|
||||
if (olen == 0)
|
||||
{
|
||||
fio->errnum = syserr_to_errnum (GetLastError());
|
||||
UnmapViewOfFile (mem);
|
||||
CloseHandle (map);
|
||||
FreeLibrary (psapi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
UnmapViewOfFile (mem);
|
||||
CloseHandle (map);
|
||||
FreeLibrary (psapi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,9 @@ int qse_runmain (
|
||||
{
|
||||
#if (defined(QSE_ACHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \
|
||||
(defined(QSE_ACHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR))
|
||||
{
|
||||
return handler (argc, (qse_char_t**)argv);
|
||||
}
|
||||
|
||||
return handler (argc, (qse_char_t**)argv);
|
||||
|
||||
#else
|
||||
{
|
||||
int i, ret;
|
||||
|
@ -221,7 +221,7 @@ struct param_t
|
||||
qse_mchar_t** argv;
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
/* nothign extra */
|
||||
/* nothing extra */
|
||||
#else
|
||||
qse_mchar_t fixed_mbuf[64];
|
||||
#endif
|
||||
@ -528,6 +528,9 @@ int qse_pio_init (
|
||||
PROCESS_INFORMATION procinfo;
|
||||
STARTUPINFO startup;
|
||||
HANDLE windevnul = INVALID_HANDLE_VALUE;
|
||||
BOOL apiret;
|
||||
qse_char_t* dupcmd;
|
||||
int create_retried;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
APIRET rc;
|
||||
@ -549,7 +552,7 @@ int qse_pio_init (
|
||||
#elif defined(HAVE_POSIX_SPAWN)
|
||||
posix_spawn_file_actions_t fa;
|
||||
int fa_inited = 0;
|
||||
int spawn_ret;
|
||||
int pserr;
|
||||
qse_pio_pid_t pid;
|
||||
param_t param;
|
||||
extern char** environ;
|
||||
@ -581,8 +584,14 @@ int qse_pio_init (
|
||||
/* don't inherit write handle */
|
||||
if (SetHandleInformation (handle[1], HANDLE_FLAG_INHERIT, 0) == FALSE)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (GetLastError());
|
||||
goto oops;
|
||||
DWORD e = GetLastError();
|
||||
if (e != ERROR_CALL_NOT_IMPLEMENTED)
|
||||
{
|
||||
/* SetHandleInformation() is not implemented on win9x.
|
||||
* so let's care only if it is implemented */
|
||||
pio->errnum = syserr_to_errnum (e);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
minidx = 0; maxidx = 1;
|
||||
@ -600,8 +609,14 @@ int qse_pio_init (
|
||||
/* don't inherit read handle */
|
||||
if (SetHandleInformation (handle[2], HANDLE_FLAG_INHERIT, 0) == FALSE)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (GetLastError());
|
||||
goto oops;
|
||||
DWORD e = GetLastError();
|
||||
if (e != ERROR_CALL_NOT_IMPLEMENTED)
|
||||
{
|
||||
/* SetHandleInformation() is not implemented on win9x.
|
||||
* so let's care only if it is implemented */
|
||||
pio->errnum = syserr_to_errnum (e);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
if (minidx == -1) minidx = 2;
|
||||
@ -620,8 +635,14 @@ int qse_pio_init (
|
||||
/* don't inherit read handle */
|
||||
if (SetHandleInformation (handle[4], HANDLE_FLAG_INHERIT, 0) == FALSE)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (GetLastError());
|
||||
goto oops;
|
||||
DWORD e = GetLastError();
|
||||
if (e != ERROR_CALL_NOT_IMPLEMENTED)
|
||||
{
|
||||
/* SetHandleInformation() is not implemented on win9x.
|
||||
* so let's care only if it is implemented */
|
||||
pio->errnum = syserr_to_errnum (e);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
if (minidx == -1) minidx = 4;
|
||||
@ -664,12 +685,18 @@ int qse_pio_init (
|
||||
startup.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
startup.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
startup.hStdOutput = GetStdHandle (STD_ERROR_HANDLE);
|
||||
|
||||
if (startup.hStdInput == INVALID_HANDLE_VALUE ||
|
||||
startup.hStdOutput == INVALID_HANDLE_VALUE ||
|
||||
startup.hStdError == INVALID_HANDLE_VALUE) goto oops;
|
||||
startup.hStdError == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (GetLastError());
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (flags & QSE_PIO_WRITEIN) startup.hStdInput = handle[0];
|
||||
if (flags & QSE_PIO_WRITEIN)
|
||||
{
|
||||
startup.hStdInput = handle[0];
|
||||
}
|
||||
|
||||
if (flags & QSE_PIO_READOUT)
|
||||
{
|
||||
@ -696,72 +723,95 @@ int qse_pio_init (
|
||||
/* there is nothing to do for QSE_PIO_SHELL as CreateProcess
|
||||
* takes the entire command line */
|
||||
|
||||
create_retried = 0;
|
||||
|
||||
create_process:
|
||||
if (flags & QSE_PIO_SHELL)
|
||||
{
|
||||
qse_char_t* dupcmd;
|
||||
BOOL x;
|
||||
static const qse_char_t* cmdname[] =
|
||||
{
|
||||
QSE_T("cmd.exe /c "),
|
||||
QSE_T("command.com /c ")
|
||||
};
|
||||
static const qse_mchar_t* mcmdname[] =
|
||||
{
|
||||
QSE_MT("cmd.exe /c "),
|
||||
QSE_MT("command.com /c ")
|
||||
};
|
||||
|
||||
if (flags & QSE_PIO_SHELL)
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
if (flags & QSE_PIO_MBSCMD)
|
||||
{
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
if (flags & QSE_PIO_MBSCMD)
|
||||
{
|
||||
const qse_mchar_t* x[3];
|
||||
x[0] = QSE_MT("cmd.exe /c ");
|
||||
x[1] = (const qse_mchar_t*)cmd;
|
||||
x[2] = QSE_NULL;
|
||||
dupcmd = qse_mbsatowcsdup (x, mmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
dupcmd = qse_strdup2 (QSE_T("cmd.exe /c "), cmd, mmgr);
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
}
|
||||
#endif
|
||||
const qse_mchar_t* x[3];
|
||||
x[0] = mcmdname[create_retried];
|
||||
x[1] = (const qse_mchar_t*)cmd;
|
||||
x[2] = QSE_NULL;
|
||||
dupcmd = qse_mbsatowcsdup (x, mmgr);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
if (flags & QSE_PIO_MBSCMD)
|
||||
{
|
||||
dupcmd = qse_mbstowcsdup ((const qse_mchar_t*)cmd, mmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
/* CreateProcess requires command buffer to be read-write. */
|
||||
dupcmd = qse_strdup (cmd, mmgr);
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
dupcmd = qse_strdup2 (cmdname[create_retried], cmd, mmgr);
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
if (flags & QSE_PIO_MBSCMD)
|
||||
{
|
||||
dupcmd = qse_mbstowcsdup ((const qse_mchar_t*)cmd, mmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
/* CreateProcess requires command buffer to be read-write. */
|
||||
dupcmd = qse_strdup (cmd, mmgr);
|
||||
#if defined(QSE_CHAR_IS_WCHAR)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dupcmd == QSE_NULL)
|
||||
{
|
||||
pio->errnum = QSE_PIO_ENOMEM;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
apiret = CreateProcess (
|
||||
QSE_NULL, /* LPCTSTR lpApplicationName */
|
||||
dupcmd, /* LPTSTR lpCommandLine */
|
||||
QSE_NULL, /* LPSECURITY_ATTRIBUTES lpProcessAttributes */
|
||||
QSE_NULL, /* LPSECURITY_ATTRIBUTES lpThreadAttributes */
|
||||
TRUE, /* BOOL bInheritHandles */
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
0, /* DWORD dwCreationFlags */
|
||||
#else
|
||||
CREATE_UNICODE_ENVIRONMENT, /* DWORD dwCreationFlags */
|
||||
#endif
|
||||
(env? qse_env_getstr(env): QSE_NULL), /* LPVOID lpEnvironment */
|
||||
QSE_NULL, /* LPCTSTR lpCurrentDirectory */
|
||||
&startup, /* LPSTARTUPINFO lpStartupInfo */
|
||||
&procinfo /* LPPROCESS_INFORMATION lpProcessInformation */
|
||||
);
|
||||
|
||||
QSE_MMGR_FREE (mmgr, dupcmd);
|
||||
if (apiret == FALSE)
|
||||
{
|
||||
DWORD e = GetLastError();
|
||||
if (create_retried == 0 && (flags & QSE_PIO_SHELL) &&
|
||||
e == ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
/* if it failed to exeucte cmd.exe,
|
||||
* attempt to execute command.com.
|
||||
* this is provision for old windows platforms */
|
||||
create_retried = 1;
|
||||
goto create_process;
|
||||
}
|
||||
|
||||
if (dupcmd == QSE_NULL)
|
||||
{
|
||||
pio->errnum = QSE_PIO_ENOMEM;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
x = CreateProcess (
|
||||
QSE_NULL, /* LPCTSTR lpApplicationName */
|
||||
dupcmd, /* LPTSTR lpCommandLine */
|
||||
QSE_NULL, /* LPSECURITY_ATTRIBUTES lpProcessAttributes */
|
||||
QSE_NULL, /* LPSECURITY_ATTRIBUTES lpThreadAttributes */
|
||||
TRUE, /* BOOL bInheritHandles */
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
0, /* DWORD dwCreationFlags */
|
||||
#else
|
||||
CREATE_UNICODE_ENVIRONMENT, /* DWORD dwCreationFlags */
|
||||
#endif
|
||||
(env? qse_env_getstr(env): QSE_NULL), /* LPVOID lpEnvironment */
|
||||
QSE_NULL, /* LPCTSTR lpCurrentDirectory */
|
||||
&startup, /* LPSTARTUPINFO lpStartupInfo */
|
||||
&procinfo /* LPPROCESS_INFORMATION lpProcessInformation */
|
||||
);
|
||||
|
||||
QSE_MMGR_FREE (mmgr, dupcmd);
|
||||
if (x == FALSE)
|
||||
pio->errnum = syserr_to_errnum (GetLastError());
|
||||
pio->errnum = syserr_to_errnum (e);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (windevnul != INVALID_HANDLE_VALUE)
|
||||
@ -1124,6 +1174,7 @@ int qse_pio_init (
|
||||
#elif defined(__DOS__)
|
||||
|
||||
/* DOS not multi-processed. can't support pio */
|
||||
pio->errnum = QSE_PIO_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#elif defined(HAVE_POSIX_SPAWN)
|
||||
@ -1165,35 +1216,83 @@ int qse_pio_init (
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (posix_spawn_file_actions_init (&fa) != 0) goto oops;
|
||||
if ((pserr = posix_spawn_file_actions_init (&fa)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
fa_inited = 1;
|
||||
|
||||
if (flags & QSE_PIO_WRITEIN)
|
||||
{
|
||||
/* child should read */
|
||||
if (posix_spawn_file_actions_addclose (&fa, handle[1]) != 0) goto oops;
|
||||
if (posix_spawn_file_actions_adddup2 (&fa, handle[0], 0) != 0) goto oops;
|
||||
if (posix_spawn_file_actions_addclose (&fa, handle[0]) != 0) goto oops;
|
||||
if ((pserr = posix_spawn_file_actions_addclose (&fa, handle[1])) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((pserr = posix_spawn_file_actions_adddup2 (&fa, handle[0]), 0) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((pserr = posix_spawn_file_actions_addclose (&fa, handle[0])) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & QSE_PIO_READOUT)
|
||||
{
|
||||
/* child should write */
|
||||
if (posix_spawn_file_actions_addclose (&fa, handle[2]) != 0) goto oops;
|
||||
if (posix_spawn_file_actions_adddup2 (&fa, handle[3], 1) != 0) goto oops;
|
||||
if ((pserr = posix_spawn_file_actions_addclose (&fa, handle[2])) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((pserr = posix_spawn_file_actions_adddup2 (&fa, handle[3], 1)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((flags & QSE_PIO_ERRTOOUT) &&
|
||||
posix_spawn_file_actions_adddup2 (&fa, handle[3], 2) != 0) goto oops;
|
||||
if (posix_spawn_file_actions_addclose (&fa, handle[3]) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_adddup2 (&fa, handle[3], 2)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((pserr = posix_spawn_file_actions_addclose (&fa, handle[3])) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & QSE_PIO_READERR)
|
||||
{
|
||||
/* child should write */
|
||||
if (posix_spawn_file_actions_addclose (&fa, handle[4]) != 0) goto oops;
|
||||
if (posix_spawn_file_actions_adddup2 (&fa, handle[5], 2) != 0) goto oops;
|
||||
if ((pserr = posix_spawn_file_actions_addclose (&fa, handle[4])) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((pserr = posix_spawn_file_actions_adddup2 (&fa, handle[5], 2)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((flags & QSE_PIO_OUTTOERR) &&
|
||||
posix_spawn_file_actions_adddup2 (&fa, handle[5], 1) != 0) goto oops;
|
||||
if (posix_spawn_file_actions_addclose (&fa, handle[5]) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_adddup2 (&fa, handle[5], 1)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((pserr = posix_spawn_file_actions_addclose (&fa, handle[5])) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@ -1203,11 +1302,23 @@ int qse_pio_init (
|
||||
#endif
|
||||
|
||||
if ((flags & QSE_PIO_INTONUL) &&
|
||||
posix_spawn_file_actions_addopen (&fa, 0, QSE_MT("/dev/null"), oflags, 0) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_addopen (&fa, 0, QSE_MT("/dev/null"), oflags, 0)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((flags & QSE_PIO_OUTTONUL) &&
|
||||
posix_spawn_file_actions_addopen (&fa, 1, QSE_MT("/dev/null"), oflags, 0) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_addopen (&fa, 1, QSE_MT("/dev/null"), oflags, 0)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((flags & QSE_PIO_ERRTONUL) &&
|
||||
posix_spawn_file_actions_addopen (&fa, 2, QSE_MT("/dev/null"), oflags, 0) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_addopen (&fa, 2, QSE_MT("/dev/null"), oflags, 0)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
/* there remains the chance of race condition that
|
||||
@ -1216,11 +1327,23 @@ int qse_pio_init (
|
||||
* just on the best-effort basis.
|
||||
*/
|
||||
if ((flags & QSE_PIO_DROPIN) && is_fd_valid(0) &&
|
||||
posix_spawn_file_actions_addclose (&fa, 0) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_addclose (&fa, 0)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((flags & QSE_PIO_DROPOUT) && is_fd_valid(1) &&
|
||||
posix_spawn_file_actions_addclose (&fa, 1) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_addclose (&fa, 1)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
if ((flags & QSE_PIO_DROPERR) && is_fd_valid(2) &&
|
||||
posix_spawn_file_actions_addclose (&fa, 2) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_addclose (&fa, 2)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (!(flags & QSE_PIO_NOCLOEXEC))
|
||||
{
|
||||
@ -1236,7 +1359,11 @@ int qse_pio_init (
|
||||
* with addclose() is closed before posix_spawn().
|
||||
* addclose() if no FD_CLOEXEC is set or it's unknown. */
|
||||
if (is_fd_valid_and_nocloexec(fd) &&
|
||||
posix_spawn_file_actions_addclose (&fa, fd) != 0) goto oops;
|
||||
(pserr = posix_spawn_file_actions_addclose (&fa, fd)) != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1251,7 +1378,7 @@ int qse_pio_init (
|
||||
goto oops;
|
||||
}
|
||||
|
||||
spawn_ret = posix_spawn(
|
||||
pserr = posix_spawn(
|
||||
&pid, param.argv[0], &fa, QSE_NULL, param.argv,
|
||||
(env? qse_env_getarr(env): environ));
|
||||
free_param (pio, ¶m);
|
||||
@ -1260,9 +1387,9 @@ int qse_pio_init (
|
||||
posix_spawn_file_actions_destroy (&fa);
|
||||
fa_inited = 0;
|
||||
}
|
||||
if (spawn_ret != 0)
|
||||
if (pserr != 0)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (errno);
|
||||
pio->errnum = syserr_to_errnum (pserr);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
@ -1287,20 +1414,32 @@ int qse_pio_init (
|
||||
|
||||
if (flags & QSE_PIO_WRITEIN)
|
||||
{
|
||||
if (QSE_PIPE(&handle[0]) <= -1) goto oops;
|
||||
if (QSE_PIPE(&handle[0]) <= -1)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
minidx = 0; maxidx = 1;
|
||||
}
|
||||
|
||||
if (flags & QSE_PIO_READOUT)
|
||||
{
|
||||
if (QSE_PIPE(&handle[2]) <= -1) goto oops;
|
||||
if (QSE_PIPE(&handle[2]) <= -1)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
if (minidx == -1) minidx = 2;
|
||||
maxidx = 3;
|
||||
}
|
||||
|
||||
if (flags & QSE_PIO_READERR)
|
||||
{
|
||||
if (QSE_PIPE(&handle[4]) <= -1) goto oops;
|
||||
if (QSE_PIPE(&handle[4]) <= -1)
|
||||
{
|
||||
pio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
if (minidx == -1) minidx = 4;
|
||||
maxidx = 5;
|
||||
}
|
||||
@ -1325,6 +1464,7 @@ int qse_pio_init (
|
||||
pid = QSE_FORK();
|
||||
if (pid <= -1)
|
||||
{
|
||||
pio->errnum = QSE_PIO_EINVAL;
|
||||
free_param (pio, ¶m);
|
||||
goto oops;
|
||||
}
|
||||
@ -1979,7 +2119,8 @@ int qse_pio_wait (qse_pio_t* pio)
|
||||
child_rc.codeResult: (255 + 1 + child_rc.codeTerminate);
|
||||
|
||||
#elif defined(__DOS__)
|
||||
/* TOOD: implement this */
|
||||
|
||||
pio->errnum = QSE_PIO_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#else
|
||||
@ -2099,7 +2240,8 @@ int qse_pio_kill (qse_pio_t* pio)
|
||||
return 0;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: implement this*/
|
||||
|
||||
pio->errnum = QSE_PIO_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#else
|
||||
|
@ -43,7 +43,6 @@ static qse_ssize_t socket_output (
|
||||
|
||||
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:
|
||||
@ -60,6 +59,8 @@ static qse_sio_errnum_t fio_errnum_to_sio_errnum (qse_fio_t* fio)
|
||||
return QSE_SIO_EINTR;
|
||||
case QSE_FIO_ESUBSYS:
|
||||
return QSE_SIO_ESUBSYS;
|
||||
case QSE_FIO_ENOIMPL:
|
||||
return QSE_SIO_ENOIMPL;
|
||||
default:
|
||||
return QSE_SIO_EOTHER;
|
||||
}
|
||||
@ -422,42 +423,43 @@ 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->u.file.handle, &mode) == FALSE)
|
||||
{
|
||||
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
|
||||
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE &&
|
||||
GetConsoleOutputCP() == CP_UTF8)
|
||||
{
|
||||
DWORD count, left;
|
||||
const qse_wchar_t* cur;
|
||||
|
||||
if (qse_sio_flush (sio) <= -1) return -1; /* can't do buffering */
|
||||
|
||||
for (cur = str, left = qse_wcslen(str); left > 0; cur += count, left -= count)
|
||||
{
|
||||
if (WriteConsoleW (
|
||||
sio->u.file.handle, cur, left,
|
||||
&count, QSE_NULL) == FALSE)
|
||||
{
|
||||
sio->errnum = QSE_SIO_EOTHER;
|
||||
sio->errnum = QSE_SIO_ESUBSYS;
|
||||
return -1;
|
||||
}
|
||||
if (count == 0) break;
|
||||
|
||||
if (count > left)
|
||||
{
|
||||
sio->errnum = QSE_SIO_ESUBSYS;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return cur - str;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sio->errnum = QSE_SIO_ENOERR;
|
||||
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);
|
||||
@ -469,8 +471,6 @@ qse_ssize_t qse_sio_putwcsn (
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
sio->errnum = QSE_SIO_ENOERR;
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* DAMN UGLY:
|
||||
* WriteFile returns wrong number of bytes written if it is
|
||||
@ -488,31 +488,46 @@ qse_ssize_t qse_sio_putwcsn (
|
||||
{
|
||||
DWORD mode;
|
||||
|
||||
if (GetConsoleMode (sio->u.file.handle, &mode) == FALSE)
|
||||
{
|
||||
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
|
||||
if (GetConsoleMode (sio->u.file.handle, &mode) == TRUE &&
|
||||
GetConsoleOutputCP() == CP_UTF8)
|
||||
{
|
||||
DWORD count, left;
|
||||
const qse_wchar_t* cur;
|
||||
|
||||
if (qse_sio_flush (sio) <= -1) return -1; /* can't do buffering */
|
||||
|
||||
for (cur = str, left = size; left > 0; cur += count, left -= count)
|
||||
{
|
||||
if (WriteConsoleW (
|
||||
sio->u.file.handle, cur, left,
|
||||
&count, QSE_NULL) == FALSE) return -1;
|
||||
&count, QSE_NULL) == FALSE)
|
||||
{
|
||||
sio->errnum = QSE_SIO_ESUBSYS;
|
||||
return -1;
|
||||
}
|
||||
if (count == 0) break;
|
||||
|
||||
/* Note:
|
||||
* WriteConsoleW() in unicosw.dll on win 9x/me returns
|
||||
* the number of bytes via 'count'. If a double byte
|
||||
* string is given, 'count' can be greater than 'left'.
|
||||
* this case is a miserable failure. however, i don't
|
||||
* think there is CP_UTF8 codepage for console on win9x/me.
|
||||
* so let me make this function fail if that ever happens.
|
||||
*/
|
||||
if (count > left)
|
||||
{
|
||||
sio->errnum = QSE_SIO_ESUBSYS;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return cur - str;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
sio->errnum = QSE_SIO_ENOERR;
|
||||
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);
|
||||
|
@ -48,8 +48,10 @@ qse_size_t qse_slwcrtoslmb (
|
||||
#if defined(_WIN32)
|
||||
int n;
|
||||
|
||||
/* CP_THREAD_ACP results in ERROR_INVALID_PARAMETER
|
||||
* on an old windows os like win95 */
|
||||
n = WideCharToMultiByte (
|
||||
CP_THREAD_ACP, 0 /*WC_ERR_INVALID_CHARS*/,
|
||||
CP_ACP/*CP_THREAD_ACP*/, 0 /*WC_ERR_INVALID_CHARS*/,
|
||||
&wc, 1, mb, mbl, NULL, NULL);
|
||||
if (n == 0)
|
||||
{
|
||||
@ -106,11 +108,11 @@ qse_size_t qse_slmbrtoslwc (
|
||||
QSE_ASSERT (mb != QSE_NULL);
|
||||
QSE_ASSERT (mbl > 0);
|
||||
|
||||
dbcslen = IsDBCSLeadByteEx(CP_THREAD_ACP, *mb)? 2: 1;
|
||||
dbcslen = IsDBCSLeadByteEx(CP_ACP/*CP_THREAD_ACP*/, *mb)? 2: 1;
|
||||
if (mbl < dbcslen) return mbl + 1; /* incomplete sequence */
|
||||
|
||||
n = MultiByteToWideChar (
|
||||
CP_THREAD_ACP, MB_ERR_INVALID_CHARS, mb, dbcslen, wc, 1);
|
||||
CP_ACP/*CP_THREAD_ACP*/, MB_ERR_INVALID_CHARS, mb, dbcslen, wc, 1);
|
||||
if (n == 0)
|
||||
{
|
||||
/*DWORD e = GetLastError();*/
|
||||
@ -184,7 +186,7 @@ qse_size_t qse_slmbrlen (
|
||||
* the actual sequence. So it can't actually detect an invalid
|
||||
* sequence. Thus, qse_slmbrtowc() may return a different length
|
||||
* for an invalid sequence form qse_slmbrlen(). */
|
||||
dbcslen = IsDBCSLeadByteEx(CP_THREAD_ACP, *mb)? 2: 1;
|
||||
dbcslen = IsDBCSLeadByteEx(CP_ACP/*CP_THREAD_ACP*/, *mb)? 2: 1;
|
||||
if (mbl < dbcslen) return mbl + 1; /* incomplete sequence */
|
||||
return dbcslen;
|
||||
|
||||
|
@ -204,6 +204,7 @@ SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TRUE = @TRUE@
|
||||
UNICOWS_LIBS = @UNICOWS_LIBS@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
@ -186,6 +186,7 @@ SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TRUE = @TRUE@
|
||||
UNICOWS_LIBS = @UNICOWS_LIBS@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
@ -381,10 +381,10 @@ static qse_httpd_task_t* entask_error (
|
||||
|
||||
return qse_httpd_entaskformat (
|
||||
httpd, client, task,
|
||||
QSE_MT("HTTP/%d.%d %d %s\r\nConnection: %s\r\nContent-Type: text/html;charset=utf-8\r\nContent-Length: %d\r\n\r\n%s\r\n\r\n"),
|
||||
QSE_MT("HTTP/%d.%d %d %s\r\nConnection: %s\r\nContent-Type: text/html\r\nContent-Length: %lu\r\n\r\n%s\r\n\r\n"),
|
||||
version->major, version->minor, code, smsg,
|
||||
(keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
(int)qse_mbslen(lmsg) + 4, lmsg
|
||||
(unsigned long)qse_mbslen(lmsg) + 4, lmsg
|
||||
);
|
||||
}
|
||||
|
||||
@ -415,12 +415,18 @@ qse_httpd_task_t* qse_httpd_entaskauth (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
const qse_httpd_task_t* task, const qse_mchar_t* realm, qse_htre_t* req)
|
||||
{
|
||||
const qse_http_version_t* version = qse_htre_getversion(req);
|
||||
/* TODO: */
|
||||
const qse_http_version_t* version;
|
||||
const qse_mchar_t* lmsg;
|
||||
|
||||
version = qse_htre_getversion(req);
|
||||
lmsg = QSE_MT("<html><head><title>Unauthorized</title></head><body><b>UNAUTHORIZED<b></body></html>");
|
||||
|
||||
return qse_httpd_entaskformat (
|
||||
httpd, client, task,
|
||||
QSE_MT("HTTP/%d.%d 401 Unauthorized\r\nContent-Length: 0\r\nWWW-Authenticate: Digest realm=\"%s\", qop=\"auth\", nonce=\"%s\""),
|
||||
version->major, version->minor);
|
||||
QSE_MT("HTTP/%d.%d 401 Unauthorized\r\nConnection: %s\r\nWWW-Authenticate: Basic realm=\"%s\"\r\nContent-Type: text/html\r\nContent-Length: %lu\r\n\r\n%s\r\n\r\n"),
|
||||
version->major, version->minor,
|
||||
(req->attr.keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
realm, (unsigned long)qse_mbslen(lmsg) + 4, lmsg);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -816,7 +822,7 @@ static QSE_INLINE int task_main_path_dir (
|
||||
{
|
||||
x = qse_httpd_entaskformat (
|
||||
httpd, client, x,
|
||||
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: keep-alive\r\nContent-Type: text/html;charset=utf-8\r\nTransfer-Encoding: chunked\r\n\r\n"),
|
||||
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: keep-alive\r\nContent-Type: text/html\r\nTransfer-Encoding: chunked\r\n\r\n"),
|
||||
data->version.major, data->version.minor
|
||||
);
|
||||
if (x) x = qse_httpd_entaskdir (httpd, client, x, handle, data->keepalive);
|
||||
@ -825,7 +831,7 @@ static QSE_INLINE int task_main_path_dir (
|
||||
{
|
||||
x = qse_httpd_entaskformat (
|
||||
httpd, client, x,
|
||||
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: close\r\nContent-Type: text/html;charset=utf-8\r\n\r\n"),
|
||||
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n"),
|
||||
data->version.major, data->version.minor
|
||||
);
|
||||
|
||||
|
@ -204,6 +204,7 @@ SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TRUE = @TRUE@
|
||||
UNICOWS_LIBS = @UNICOWS_LIBS@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
@ -186,6 +186,7 @@ SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TRUE = @TRUE@
|
||||
UNICOWS_LIBS = @UNICOWS_LIBS@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
Reference in New Issue
Block a user