* added QSE_PIO_MBSCMD
* added qse_env_insertsys() and related functions
This commit is contained in:
parent
93f8bfca65
commit
cfe85ecc60
@ -93,8 +93,13 @@ void qse_env_clear (
|
|||||||
qse_env_t* env
|
qse_env_t* env
|
||||||
);
|
);
|
||||||
|
|
||||||
#define qse_env_getstr(env) ((env)->str.ptr)
|
const qse_env_char_t* qse_env_getstr (
|
||||||
#define qse_env_getarr(env) ((env)->arr.ptr)
|
qse_env_t* env
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_env_char_t** qse_env_getarr (
|
||||||
|
qse_env_t* env
|
||||||
|
);
|
||||||
|
|
||||||
int qse_env_insertw (
|
int qse_env_insertw (
|
||||||
qse_env_t* env,
|
qse_env_t* env,
|
||||||
@ -118,12 +123,26 @@ int qse_env_deletem (
|
|||||||
const qse_mchar_t* name
|
const qse_mchar_t* name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
int qse_env_insertsysw (
|
||||||
|
qse_env_t* env,
|
||||||
|
const qse_wchar_t* name
|
||||||
|
);
|
||||||
|
|
||||||
|
int qse_env_insertsysm (
|
||||||
|
qse_env_t* env,
|
||||||
|
const qse_mchar_t* name
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
#if defined(QSE_CHAR_IS_WCHAR)
|
#if defined(QSE_CHAR_IS_WCHAR)
|
||||||
# define qse_env_insert(env,name,value) qse_env_insertw(env,name,value)
|
# define qse_env_insert(env,name,value) qse_env_insertw(env,name,value)
|
||||||
# define qse_env_delete(env,name) qse_env_deletew(env,name)
|
# define qse_env_delete(env,name) qse_env_deletew(env,name)
|
||||||
|
# define qse_env_insertsys(env,name) qse_env_insertsysw(env,name)
|
||||||
#else
|
#else
|
||||||
# define qse_env_insert(env,name,value) qse_env_insertm(env,name,value)
|
# define qse_env_insert(env,name,value) qse_env_insertm(env,name,value)
|
||||||
# define qse_env_delete(env,name) qse_env_deletem(env,name)
|
# define qse_env_delete(env,name) qse_env_deletem(env,name)
|
||||||
|
# define qse_env_insertsys(env,name) qse_env_insertsysm(env,name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: pio.h 538 2011-08-09 16:08:26Z hyunghwan.chung $
|
* $Id: pio.h 539 2011-08-10 16:18:35Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -44,6 +44,10 @@ enum qse_pio_oflag_t
|
|||||||
* (/bin/sh on *nix, cmd.exe on windows) */
|
* (/bin/sh on *nix, cmd.exe on windows) */
|
||||||
QSE_PIO_SHELL = (1 << 1),
|
QSE_PIO_SHELL = (1 << 1),
|
||||||
|
|
||||||
|
/** indicate that the command to qse_pio_open() is a multi-byte string.
|
||||||
|
* it is useful if #QSE_CHAR_IS_WCHAR is defined. */
|
||||||
|
QSE_PIO_MBSCMD = (1 << 2),
|
||||||
|
|
||||||
/** write to stdin of a child process */
|
/** write to stdin of a child process */
|
||||||
QSE_PIO_WRITEIN = (1 << 8),
|
QSE_PIO_WRITEIN = (1 << 8),
|
||||||
/** read stdout of a child process */
|
/** read stdout of a child process */
|
||||||
@ -51,9 +55,9 @@ enum qse_pio_oflag_t
|
|||||||
/** read stderr of a child process */
|
/** read stderr of a child process */
|
||||||
QSE_PIO_READERR = (1 << 10),
|
QSE_PIO_READERR = (1 << 10),
|
||||||
|
|
||||||
/** redirect stderr to stdout (2>&1, require QSE_PIO_READOUT) */
|
/** redirect stderr to stdout (2>&1, require #QSE_PIO_READOUT) */
|
||||||
QSE_PIO_ERRTOOUT = (1 << 11),
|
QSE_PIO_ERRTOOUT = (1 << 11),
|
||||||
/** redirect stdout to stderr (1>&2, require QSE_PIO_READERR) */
|
/** redirect stdout to stderr (1>&2, require #QSE_PIO_READERR) */
|
||||||
QSE_PIO_OUTTOERR = (1 << 12),
|
QSE_PIO_OUTTOERR = (1 << 12),
|
||||||
|
|
||||||
/** redirect stdin to the null device (</dev/null, <NUL) */
|
/** redirect stdin to the null device (</dev/null, <NUL) */
|
||||||
@ -192,7 +196,10 @@ QSE_DEFINE_COMMON_FUNCTIONS (pio)
|
|||||||
* the default shell of an underlying system: /bin/sh on *nix, cmd.exe on win32.
|
* the default shell of an underlying system: /bin/sh on *nix, cmd.exe on win32.
|
||||||
* On *nix systems, a full path to the command is needed if it is not specified.
|
* On *nix systems, a full path to the command is needed if it is not specified.
|
||||||
* If @a env is #QSE_NULL, the environment of @a cmd inherits that of the
|
* If @a env is #QSE_NULL, the environment of @a cmd inherits that of the
|
||||||
* calling process.
|
* calling process. If you want to pass an empty environment, you can pass
|
||||||
|
* an empty @a env object with no items inserted. If #QSE_PIO_MBSCMD is
|
||||||
|
* specified in @a oflags, @a cmd is treated as a multi-byte string whose
|
||||||
|
* character type is #qse_mchar_t.
|
||||||
* @return #qse_pio_t object on success, #QSE_NULL on failure
|
* @return #qse_pio_t object on success, #QSE_NULL on failure
|
||||||
*/
|
*/
|
||||||
qse_pio_t* qse_pio_open (
|
qse_pio_t* qse_pio_open (
|
||||||
|
@ -213,8 +213,8 @@ qse_httpd_task_t* qse_httpd_entaskcgi (
|
|||||||
qse_httpd_t* httpd,
|
qse_httpd_t* httpd,
|
||||||
qse_httpd_client_t* client,
|
qse_httpd_client_t* client,
|
||||||
const qse_httpd_task_t* pred,
|
const qse_httpd_task_t* pred,
|
||||||
const qse_char_t* path,
|
const qse_mchar_t* path,
|
||||||
const qse_http_version_t* version
|
const qse_htre_t* req
|
||||||
);
|
);
|
||||||
|
|
||||||
void* qse_httpd_allocmem (
|
void* qse_httpd_allocmem (
|
||||||
|
@ -95,6 +95,26 @@ void qse_env_clear (qse_env_t* env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const qse_env_char_t* qse_env_getstr (qse_env_t* env)
|
||||||
|
{
|
||||||
|
if (env->str.ptr) return env->str.ptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static qse_env_char_t empty[2] = { 0, 0 };
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_env_char_t** qse_env_getarr (qse_env_t* env)
|
||||||
|
{
|
||||||
|
if (env->arr.ptr) return env->arr.ptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static qse_env_char_t* empty[1] = { QSE_NULL };
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int expandarr (qse_env_t* env)
|
static int expandarr (qse_env_t* env)
|
||||||
{
|
{
|
||||||
qse_env_char_t** tmp;
|
qse_env_char_t** tmp;
|
||||||
@ -165,7 +185,7 @@ static int insertw (qse_env_t* env, const qse_wchar_t* name, const qse_wchar_t*
|
|||||||
env->str.len += qse_wcscpy (&env->str.ptr[env->str.len], value);
|
env->str.len += qse_wcscpy (&env->str.ptr[env->str.len], value);
|
||||||
env->str.ptr[++env->str.len] = QSE_WT('\0');
|
env->str.ptr[++env->str.len] = QSE_WT('\0');
|
||||||
|
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_envstrw (qse_env_t* env, const qse_wchar_t* nv)
|
static int add_envstrw (qse_env_t* env, const qse_wchar_t* nv)
|
||||||
@ -244,7 +264,7 @@ static int insertm (qse_env_t* env, const qse_mchar_t* name, const qse_mchar_t*
|
|||||||
env->str.len += qse_mbscpy (&env->str.ptr[env->str.len], value);
|
env->str.len += qse_mbscpy (&env->str.ptr[env->str.len], value);
|
||||||
env->str.ptr[++env->str.len] = QSE_MT('\0');
|
env->str.ptr[++env->str.len] = QSE_MT('\0');
|
||||||
|
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_envstrm (qse_env_t* env, const qse_mchar_t* nv)
|
static int add_envstrm (qse_env_t* env, const qse_mchar_t* nv)
|
||||||
@ -395,6 +415,115 @@ int qse_env_deletem (qse_env_t* env, const qse_mchar_t* name)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static qse_char_t* getenv (const qse_char_t* name, int* free)
|
||||||
|
{
|
||||||
|
DWORD n;
|
||||||
|
|
||||||
|
n = GetEnvironmentVariable (name, QSE_NULL, 0);
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
qse_char_t* buf;
|
||||||
|
|
||||||
|
buf = QSE_MMGR_ALLOC (env->mmgr, n * QSE_SIZEOF(*buf));
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
if (GetEnvironmentVariable (name, buf, n) == n - 1)
|
||||||
|
{
|
||||||
|
*free = 1;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
QSE_MMGR_FREE (env->mmgr, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
/* TODO: */
|
||||||
|
# error IMPLEMENT THIS
|
||||||
|
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
/* TODO: */
|
||||||
|
# error IMPLEMENT THIS
|
||||||
|
|
||||||
|
#else
|
||||||
|
static qse_mchar_t* getenv (const qse_mchar_t* name, int* free)
|
||||||
|
{
|
||||||
|
extern char** environ;
|
||||||
|
char** p = environ;
|
||||||
|
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
qse_mchar_t* eq;
|
||||||
|
eq = qse_mbsbeg (*p, name);
|
||||||
|
if (eq && *eq == QSE_MT('='))
|
||||||
|
{
|
||||||
|
*free = 0;
|
||||||
|
return eq + 1;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int qse_env_insertsysw (qse_env_t* env, const qse_wchar_t* name)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && defined(QSE_CHAR_IS_WCHAR)
|
||||||
|
int ret, free;
|
||||||
|
qse_wchar_t* v;
|
||||||
|
|
||||||
|
v = getenv (name, &free);
|
||||||
|
if (v == QSE_NULL) return 0;
|
||||||
|
ret = insertw (env, name, v);
|
||||||
|
if (free) QSE_MMGR_FREE (env->mmgr, v);
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
/* convert wchar to mchar */
|
||||||
|
qse_mchar_t* namedup;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
namedup = qse_wcstombsdup (name, env->mmgr);
|
||||||
|
if (namedup)
|
||||||
|
{
|
||||||
|
ret = qse_env_insertsysm (env, namedup);
|
||||||
|
QSE_MMGR_FREE (env->mmgr, namedup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_env_insertsysm (qse_env_t* env, const qse_mchar_t* name)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && defined(QSE_CHAR_IS_WCHAR)
|
||||||
|
/* convert mchar to wchar */
|
||||||
|
qse_wchar_t* namedup;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
namedup = qse_mbstowcsdup (name, env->mmgr);
|
||||||
|
if (namedup)
|
||||||
|
{
|
||||||
|
ret = qse_env_insertsysw (env, namedup);
|
||||||
|
QSE_MMGR_FREE (env->mmgr, namedup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
int ret, free;
|
||||||
|
qse_mchar_t* v;
|
||||||
|
|
||||||
|
v = getenv (name, &free);
|
||||||
|
if (v == QSE_NULL) return -1;
|
||||||
|
ret = insertm (env, name, v);
|
||||||
|
if (free) QSE_MMGR_FREE (env->mmgr, v);
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int load_curenv (qse_env_t* env)
|
static int load_curenv (qse_env_t* env)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: pio.c 538 2011-08-09 16:08:26Z hyunghwan.chung $
|
* $Id: pio.c 539 2011-08-10 16:18:35Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -104,9 +104,7 @@ qse_pio_t* qse_pio_init (
|
|||||||
SECURITY_ATTRIBUTES secattr;
|
SECURITY_ATTRIBUTES secattr;
|
||||||
PROCESS_INFORMATION procinfo;
|
PROCESS_INFORMATION procinfo;
|
||||||
STARTUPINFO startup;
|
STARTUPINFO startup;
|
||||||
qse_char_t* dup = QSE_NULL;
|
|
||||||
HANDLE windevnul = INVALID_HANDLE_VALUE;
|
HANDLE windevnul = INVALID_HANDLE_VALUE;
|
||||||
BOOL x;
|
|
||||||
|
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
APIRET rc;
|
APIRET rc;
|
||||||
@ -245,47 +243,48 @@ qse_pio_t* qse_pio_init (
|
|||||||
/* there is nothing to do for QSE_PIO_SHELL as CreateProcess
|
/* there is nothing to do for QSE_PIO_SHELL as CreateProcess
|
||||||
* takes the entire command line */
|
* takes the entire command line */
|
||||||
|
|
||||||
if (oflags & QSE_PIO_SHELL)
|
|
||||||
{
|
{
|
||||||
dup = QSE_MMGR_ALLOC (
|
const qse_char_t* dupcmd;
|
||||||
mmgr, (11+qse_strlen(cmd)+1 )*QSE_SIZEOF(qse_char_t));
|
BOOL x;
|
||||||
if (dup == QSE_NULL) goto oops;
|
|
||||||
|
|
||||||
qse_strcpy (dup, QSE_T("cmd.exe /c "));
|
if (oflags & QSE_PIO_SHELL)
|
||||||
qse_strcpy (&dup[11], cmd);
|
{
|
||||||
}
|
dupcmd = QSE_MMGR_ALLOC (
|
||||||
else
|
mmgr, (11+qse_strlen(cmd)+1 )*QSE_SIZEOF(qse_char_t));
|
||||||
{
|
if (dupcmd == QSE_NULL) goto oops;
|
||||||
dup = qse_strdup (cmd, mmgr);
|
|
||||||
if (dup == QSE_NULL) goto oops;
|
qse_strcpy (dupcmd, QSE_T("cmd.exe /c "));
|
||||||
|
qse_strcpy (&dupcmd[11], cmd);
|
||||||
|
}
|
||||||
|
else dupcmd = cmd;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dupcmd != cmd) QSE_MMGR_FREE (mmgr, dupcmd);
|
||||||
|
if (x == FALSE) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = CreateProcess (
|
|
||||||
NULL, /* LPCTSTR lpApplicationName */
|
|
||||||
dup, /* LPTSTR lpCommandLine */
|
|
||||||
NULL, /* LPSECURITY_ATTRIBUTES lpProcessAttributes */
|
|
||||||
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 */
|
|
||||||
NULL, /* LPCTSTR lpCurrentDirectory */
|
|
||||||
&startup, /* LPSTARTUPINFO lpStartupInfo */
|
|
||||||
&procinfo /* LPPROCESS_INFORMATION lpProcessInformation */
|
|
||||||
);
|
|
||||||
|
|
||||||
QSE_MMGR_FREE (mmgr, dup); dup = QSE_NULL;
|
|
||||||
if (windevnul != INVALID_HANDLE_VALUE)
|
if (windevnul != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
CloseHandle (windevnul);
|
CloseHandle (windevnul);
|
||||||
windevnul = INVALID_HANDLE_VALUE;
|
windevnul = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x == FALSE) goto oops;
|
|
||||||
|
|
||||||
if (oflags & QSE_PIO_WRITEIN)
|
if (oflags & QSE_PIO_WRITEIN)
|
||||||
{
|
{
|
||||||
CloseHandle (handle[0]);
|
CloseHandle (handle[0]);
|
||||||
@ -577,8 +576,6 @@ qse_pio_t* qse_pio_init (
|
|||||||
qse_mchar_t* mcmd;
|
qse_mchar_t* mcmd;
|
||||||
int fcnt = 0;
|
int fcnt = 0;
|
||||||
#ifndef QSE_CHAR_IS_MCHAR
|
#ifndef QSE_CHAR_IS_MCHAR
|
||||||
qse_size_t n, mn, wl;
|
|
||||||
qse_char_t* wcmd = QSE_NULL;
|
|
||||||
qse_mchar_t buf[64];
|
qse_mchar_t buf[64];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -694,69 +691,95 @@ qse_pio_t* qse_pio_init (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (oflags & QSE_PIO_SHELL)
|
if (oflags & QSE_PIO_MBSCMD)
|
||||||
{
|
{
|
||||||
n = qse_wcstombslen (cmd, &mn);
|
/* the cmd is flagged to be of qse_mchar_t
|
||||||
if (cmd[n] != QSE_WT('\0'))
|
* while the default character type is qse_wchar_t. */
|
||||||
|
|
||||||
|
if (oflags & QSE_PIO_SHELL) mcmd = (qse_mchar_t*)cmd;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* cmd has illegal sequence */
|
mcmd = qse_mbsdup ((const qse_mchar_t*)cmd, pio->mmgr);
|
||||||
goto child_oops;
|
if (mcmd == QSE_NULL) goto child_oops;
|
||||||
|
|
||||||
|
fcnt = qse_mbsspl (mcmd, QSE_MT(""),
|
||||||
|
QSE_MT('\"'), QSE_MT('\"'), QSE_MT('\\'));
|
||||||
|
if (fcnt <= 0)
|
||||||
|
{
|
||||||
|
/* no field or an error */
|
||||||
|
goto child_oops;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wcmd = qse_strdup (cmd, pio->mmgr);
|
qse_size_t n, mn, wl;
|
||||||
if (wcmd == QSE_NULL) goto child_oops;
|
qse_char_t* wcmd = QSE_NULL;
|
||||||
|
|
||||||
fcnt = qse_strspl (wcmd, QSE_T(""),
|
if (oflags & QSE_PIO_SHELL)
|
||||||
QSE_T('\"'), QSE_T('\"'), QSE_T('\\'));
|
|
||||||
if (fcnt <= 0)
|
|
||||||
{
|
{
|
||||||
/* no field or an error */
|
n = qse_wcstombslen (cmd, &mn);
|
||||||
goto child_oops;
|
if (cmd[n] != QSE_WT('\0'))
|
||||||
|
{
|
||||||
|
/* cmd has illegal sequence */
|
||||||
|
goto child_oops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wcmd = qse_strdup (cmd, pio->mmgr);
|
||||||
|
if (wcmd == QSE_NULL) goto child_oops;
|
||||||
|
|
||||||
|
fcnt = qse_strspl (wcmd, QSE_T(""),
|
||||||
|
QSE_T('\"'), QSE_T('\"'), QSE_T('\\'));
|
||||||
|
if (fcnt <= 0)
|
||||||
|
{
|
||||||
|
/* no field or an error */
|
||||||
|
goto child_oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the length of the string after splitting */
|
||||||
|
for (wl = 0, n = fcnt; n > 0; )
|
||||||
|
{
|
||||||
|
if (wcmd[wl++] == QSE_T('\0')) n--;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = qse_wcsntombsnlen (wcmd, wl, &mn);
|
||||||
|
if (n != wl) goto child_oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the length of the string after splitting */
|
/* prepare to reserve 1 more slot for the terminating '\0'
|
||||||
for (wl = 0, n = fcnt; n > 0; )
|
* by incrementing mn by 1. */
|
||||||
|
mn = mn + 1;
|
||||||
|
|
||||||
|
if (mn <= QSE_COUNTOF(buf))
|
||||||
{
|
{
|
||||||
if (wcmd[wl++] == QSE_T('\0')) n--;
|
mcmd = buf;
|
||||||
|
mn = QSE_COUNTOF(buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mcmd = QSE_MMGR_ALLOC (
|
||||||
|
pio->mmgr, mn*QSE_SIZEOF(*mcmd));
|
||||||
|
if (mcmd == QSE_NULL) goto child_oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = qse_wcsntombsnlen (wcmd, wl, &mn);
|
if (oflags & QSE_PIO_SHELL)
|
||||||
if (n != wl) goto child_oops;
|
{
|
||||||
}
|
/* qse_wcstombs() should succeed as
|
||||||
|
* qse_wcstombslen() was successful above */
|
||||||
/* prepare to reserve 1 more slot for the terminating '\0'
|
qse_wcstombs (cmd, mcmd, &mn);
|
||||||
* by incrementing mn by 1. */
|
/* qse_wcstombs() null-terminate mcmd */
|
||||||
mn = mn + 1;
|
}
|
||||||
|
else
|
||||||
if (mn <= QSE_COUNTOF(buf))
|
{
|
||||||
{
|
QSE_ASSERT (wcmd != QSE_NULL);
|
||||||
mcmd = buf;
|
/* qse_wcsntombsn() should succeed as
|
||||||
mn = QSE_COUNTOF(buf);
|
* qse_wcsntombsnlen() was successful above */
|
||||||
}
|
qse_wcsntombsn (wcmd, wl, mcmd, &mn);
|
||||||
else
|
/* qse_wcsntombsn() doesn't null-terminate mcmd */
|
||||||
{
|
mcmd[mn] = QSE_MT('\0');
|
||||||
mcmd = QSE_MMGR_ALLOC (
|
}
|
||||||
pio->mmgr, mn*QSE_SIZEOF(*mcmd));
|
|
||||||
if (mcmd == QSE_NULL) goto child_oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oflags & QSE_PIO_SHELL)
|
|
||||||
{
|
|
||||||
/* qse_wcstombs() should succeed as
|
|
||||||
* qse_wcstombslen() was successful above */
|
|
||||||
qse_wcstombs (cmd, mcmd, &mn);
|
|
||||||
/* qse_wcstombs() null-terminate mcmd */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QSE_ASSERT (wcmd != QSE_NULL);
|
|
||||||
/* qse_wcsntombsn() should succeed as
|
|
||||||
* qse_wcsntombsnlen() was successful above */
|
|
||||||
qse_wcsntombsn (wcmd, wl, mcmd, &mn);
|
|
||||||
/* qse_wcsntombsn() doesn't null-terminate mcmd */
|
|
||||||
mcmd[mn] = QSE_MT('\0');
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -880,7 +903,6 @@ oops:
|
|||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (windevnul != INVALID_HANDLE_VALUE) CloseHandle (windevnul);
|
if (windevnul != INVALID_HANDLE_VALUE) CloseHandle (windevnul);
|
||||||
if (dup) QSE_MMGR_FREE (mmgr, dup);
|
|
||||||
|
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
if (cmd_line) QSE_MMGR_FREE (mmgr, cmd_line);
|
if (cmd_line) QSE_MMGR_FREE (mmgr, cmd_line);
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#ifdef HAVE_SYS_SENDFILE_H
|
#ifdef HAVE_SYS_SENDFILE_H
|
||||||
# include <sys/sendfile.h>
|
# include <sys/sendfile.h>
|
||||||
#else
|
#else
|
||||||
qse_ssize_t sendfile (
|
static qse_ssize_t sendfile (
|
||||||
int out_fd, int in_fd, qse_foff_t* offset, qse_size_t count)
|
int out_fd, int in_fd, qse_foff_t* offset, qse_size_t count)
|
||||||
{
|
{
|
||||||
qse_mchar_t buf[MAX_SEND_SIZE];
|
qse_mchar_t buf[MAX_SEND_SIZE];
|
||||||
@ -55,7 +55,6 @@ qse_ssize_t sendfile (
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static int task_main_disconnect (
|
static int task_main_disconnect (
|
||||||
@ -665,14 +664,16 @@ qse_httpd_task_t* qse_httpd_entaskpath (
|
|||||||
typedef struct task_cgi_arg_t task_cgi_arg_t;
|
typedef struct task_cgi_arg_t task_cgi_arg_t;
|
||||||
struct task_cgi_arg_t
|
struct task_cgi_arg_t
|
||||||
{
|
{
|
||||||
const qse_char_t* path;
|
const qse_mchar_t* path;
|
||||||
qse_http_version_t version;
|
const qse_htre_t* req;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct task_cgi_t task_cgi_t;
|
typedef struct task_cgi_t task_cgi_t;
|
||||||
struct task_cgi_t
|
struct task_cgi_t
|
||||||
{
|
{
|
||||||
const qse_char_t* path;
|
int init_failed;
|
||||||
|
|
||||||
|
const qse_mchar_t* path;
|
||||||
qse_http_version_t version;
|
qse_http_version_t version;
|
||||||
|
|
||||||
qse_env_t* env;
|
qse_env_t* env;
|
||||||
@ -822,6 +823,45 @@ static qse_htrd_recbs_t cgi_htrd_cbs =
|
|||||||
QSE_NULL /* not needed for CGI */
|
QSE_NULL /* not needed for CGI */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static qse_env_t* makecgienv (
|
||||||
|
qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_htre_t* req)
|
||||||
|
{
|
||||||
|
/* TODO: error check */
|
||||||
|
qse_env_t* env;
|
||||||
|
|
||||||
|
env = qse_env_open (httpd->mmgr, 0, 0);
|
||||||
|
if (env == QSE_NULL) goto oops;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
qse_env_insertsys (env, QSE_T("PATH"));
|
||||||
|
#else
|
||||||
|
qse_env_insertsysm (env, QSE_MT("LANG"));
|
||||||
|
qse_env_insertsysm (env, QSE_MT("PATH"));
|
||||||
|
//qse_env_insertm (env, QSE_MT("SERVER_PORT"), );
|
||||||
|
|
||||||
|
{
|
||||||
|
qse_mchar_t port[16];
|
||||||
|
snprintf (port, QSE_COUNTOF(port),
|
||||||
|
"%d", (int)ntohs(client->addr.in4.sin_port));
|
||||||
|
qse_env_insertm (env, QSE_MT("REMOTE_PORT"), port);
|
||||||
|
}
|
||||||
|
//qse_env_insertm (env, QSE_MT("REMOTE_ADDR"), QSE_MT("what the hell"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
qse_env_insertm (env, "SERVER_NAME",
|
||||||
|
qse_env_insertm (env, "SERVER_ROOT",
|
||||||
|
qse_env_insertm (env, "DOCUMENT_ROOT",
|
||||||
|
qse_env_insertm (env, "REMOTE_PORT",
|
||||||
|
qse_env_insertm (env, "REQUEST_URI",
|
||||||
|
#endif
|
||||||
|
return env;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (env) qse_env_close (env);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int task_init_cgi (
|
static int task_init_cgi (
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||||
{
|
{
|
||||||
@ -829,9 +869,13 @@ static int task_init_cgi (
|
|||||||
task_cgi_arg_t* arg = (task_cgi_arg_t*)task->ctx;
|
task_cgi_arg_t* arg = (task_cgi_arg_t*)task->ctx;
|
||||||
|
|
||||||
QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn));
|
QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn));
|
||||||
qse_strcpy ((qse_char_t*)(xtn + 1), arg->path);
|
qse_mbscpy ((qse_mchar_t*)(xtn + 1), arg->path);
|
||||||
xtn->path = (qse_char_t*)(xtn + 1);
|
xtn->path = (qse_mchar_t*)(xtn + 1);
|
||||||
xtn->version = arg->version;
|
xtn->version = *qse_htre_getversion(arg->req);
|
||||||
|
|
||||||
|
xtn->env = makecgienv (httpd, client, arg->req);
|
||||||
|
if (xtn->env == QSE_NULL) xtn->init_failed = 1;
|
||||||
|
|
||||||
task->ctx = xtn;
|
task->ctx = xtn;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1090,6 +1134,10 @@ static int task_main_cgi (
|
|||||||
{
|
{
|
||||||
task_cgi_t* cgi = (task_cgi_t*)task->ctx;
|
task_cgi_t* cgi = (task_cgi_t*)task->ctx;
|
||||||
cgi_htrd_xtn_t* xtn;
|
cgi_htrd_xtn_t* xtn;
|
||||||
|
/* TODO: get the message using callback */
|
||||||
|
const qse_mchar_t* msg = "Internal server error has occurred";
|
||||||
|
|
||||||
|
if (cgi->init_failed) goto oops;
|
||||||
|
|
||||||
cgi->htrd = qse_htrd_open (httpd->mmgr, QSE_SIZEOF(cgi_htrd_xtn_t));
|
cgi->htrd = qse_htrd_open (httpd->mmgr, QSE_SIZEOF(cgi_htrd_xtn_t));
|
||||||
if (cgi->htrd == QSE_NULL) goto oops;
|
if (cgi->htrd == QSE_NULL) goto oops;
|
||||||
@ -1106,29 +1154,29 @@ static int task_main_cgi (
|
|||||||
cgi->res = qse_mbs_open (httpd->mmgr, 0, 256);
|
cgi->res = qse_mbs_open (httpd->mmgr, 0, 256);
|
||||||
if (cgi->res == QSE_NULL) goto oops;
|
if (cgi->res == QSE_NULL) goto oops;
|
||||||
|
|
||||||
cgi->env = qse_env_open (httpd->mmgr, 0, 0);
|
|
||||||
if (cgi->env == QSE_NULL) goto oops;
|
|
||||||
|
|
||||||
qse_env_insertm (cgi->env, QSE_MT("QUERY_STRING"), QSE_MT("what the hell"));
|
|
||||||
qse_env_insertm (cgi->env, QSE_MT("CLIENT_IPADDR"), QSE_MT("2.3.4.5"));
|
|
||||||
|
|
||||||
qse_printf (QSE_T("[pio open for %s]\n"), cgi->path);
|
|
||||||
cgi->pio = qse_pio_open (
|
cgi->pio = qse_pio_open (
|
||||||
httpd->mmgr, 0, cgi->path, cgi->env,
|
httpd->mmgr, 0, (const qse_char_t*)cgi->path, cgi->env,
|
||||||
QSE_PIO_READOUT | QSE_PIO_WRITEIN | QSE_PIO_ERRTONUL
|
QSE_PIO_READOUT | QSE_PIO_WRITEIN | QSE_PIO_ERRTONUL | QSE_PIO_MBSCMD
|
||||||
);
|
);
|
||||||
if (cgi->pio == QSE_NULL) goto oops;
|
if (cgi->pio == QSE_NULL) goto oops;
|
||||||
|
|
||||||
qse_printf (QSE_T("[calling cgi_2 ]\n"));
|
|
||||||
task->main = task_main_cgi_2; /* cause this function to be called subsequently */
|
task->main = task_main_cgi_2; /* cause this function to be called subsequently */
|
||||||
return task_main_cgi_2 (httpd, client, task); /* let me call it here once */
|
return task_main_cgi_2 (httpd, client, task); /* let me call it here once */
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
/* TODO: internal server error */
|
|
||||||
if (cgi->env) qse_env_close (cgi->env);
|
|
||||||
if (cgi->res) qse_mbs_close (cgi->res);
|
if (cgi->res) qse_mbs_close (cgi->res);
|
||||||
if (cgi->htrd) qse_htrd_close (cgi->htrd);
|
if (cgi->htrd) qse_htrd_close (cgi->htrd);
|
||||||
qse_printf (QSE_T("internal server error....\n"));
|
|
||||||
|
qse_httpd_entaskformat (
|
||||||
|
httpd, client, task,
|
||||||
|
QSE_MT("HTTP/%d.%d 500 Internal Server Error\r\nContent-Type: text/plain\r\nContent-Length: %lu\r\n\r\n%s"),
|
||||||
|
cgi->version.major,
|
||||||
|
cgi->version.minor,
|
||||||
|
(unsigned long)qse_mbslen(msg),
|
||||||
|
msg
|
||||||
|
);
|
||||||
|
/* TODO: can i return something else if this fails... */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1136,14 +1184,14 @@ qse_httpd_task_t* qse_httpd_entaskcgi (
|
|||||||
qse_httpd_t* httpd,
|
qse_httpd_t* httpd,
|
||||||
qse_httpd_client_t* client,
|
qse_httpd_client_t* client,
|
||||||
const qse_httpd_task_t* pred,
|
const qse_httpd_task_t* pred,
|
||||||
const qse_char_t* path,
|
const qse_mchar_t* path,
|
||||||
const qse_http_version_t* version)
|
const qse_htre_t* req)
|
||||||
{
|
{
|
||||||
qse_httpd_task_t task;
|
qse_httpd_task_t task;
|
||||||
task_cgi_arg_t arg;
|
task_cgi_arg_t arg;
|
||||||
|
|
||||||
arg.path = path;
|
arg.path = path;
|
||||||
arg.version = *version;
|
arg.req = req;
|
||||||
|
|
||||||
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
||||||
task.init = task_init_cgi;
|
task.init = task_init_cgi;
|
||||||
@ -1153,7 +1201,7 @@ qse_httpd_task_t* qse_httpd_entaskcgi (
|
|||||||
|
|
||||||
return qse_httpd_entask (
|
return qse_httpd_entask (
|
||||||
httpd, client, pred, &task,
|
httpd, client, pred, &task,
|
||||||
QSE_SIZEOF(task_cgi_t) + ((qse_strlen(path) + 1) * QSE_SIZEOF(*path))
|
QSE_SIZEOF(task_cgi_t) + ((qse_mbslen(path) + 1) * QSE_SIZEOF(*path))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,44 +14,38 @@ static void dump (qse_env_t* env)
|
|||||||
qse_env_char_t** envarr;
|
qse_env_char_t** envarr;
|
||||||
|
|
||||||
envstr = qse_env_getstr (env);
|
envstr = qse_env_getstr (env);
|
||||||
if (envstr)
|
|
||||||
{
|
|
||||||
#if (defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)) || \
|
#if (defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)) || \
|
||||||
(defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR))
|
(defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR))
|
||||||
while (*envstr != QSE_T('\0'))
|
while (*envstr != QSE_T('\0'))
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("%p [%s]\n"), envstr, envstr);
|
qse_printf (QSE_T("%p [%s]\n"), envstr, envstr);
|
||||||
envstr += qse_strlen(envstr) + 1;
|
envstr += qse_strlen(envstr) + 1;
|
||||||
}
|
|
||||||
#elif defined(QSE_ENV_CHAR_IS_WCHAR)
|
|
||||||
while (*envstr != QSE_WT('\0'))
|
|
||||||
{
|
|
||||||
qse_printf (QSE_T("%p [%S]\n"), envstr, envstr);
|
|
||||||
envstr += qse_wcslen(envstr) + 1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
while (*envstr != QSE_MT('\0'))
|
|
||||||
{
|
|
||||||
qse_printf (QSE_T("%p [%S]\n"), envstr, envstr);
|
|
||||||
envstr += qse_mbslen(envstr) + 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#elif defined(QSE_ENV_CHAR_IS_WCHAR)
|
||||||
qse_printf (QSE_T("=====\n"));
|
while (*envstr != QSE_WT('\0'))
|
||||||
envarr = qse_env_getarr (env);
|
{
|
||||||
if (envarr)
|
qse_printf (QSE_T("%p [%S]\n"), envstr, envstr);
|
||||||
|
envstr += qse_wcslen(envstr) + 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
while (*envstr != QSE_MT('\0'))
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("%p [%S]\n"), envstr, envstr);
|
||||||
|
envstr += qse_mbslen(envstr) + 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
qse_printf (QSE_T("-------------\n"));
|
||||||
|
envarr = qse_env_getarr (env);
|
||||||
|
while (*envarr)
|
||||||
{
|
{
|
||||||
while (*envarr)
|
|
||||||
{
|
|
||||||
#if (defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)) || \
|
#if (defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)) || \
|
||||||
(defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR))
|
(defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR))
|
||||||
qse_printf (QSE_T("%p [%s]\n"), *envarr, *envarr);
|
qse_printf (QSE_T("%p [%s]\n"), *envarr, *envarr);
|
||||||
#else
|
#else
|
||||||
qse_printf (QSE_T("%p [%S]\n"), *envarr, *envarr);
|
qse_printf (QSE_T("%p [%S]\n"), *envarr, *envarr);
|
||||||
#endif
|
#endif
|
||||||
envarr++;
|
envarr++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,9 +99,28 @@ static int test2 (void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test3 (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
qse_env_t* env;
|
||||||
|
|
||||||
|
env = qse_env_open (QSE_NULL, 0, 0);
|
||||||
|
|
||||||
|
qse_printf (QSE_T("%d\n"), qse_env_insertsys (env, QSE_T("PATH")));
|
||||||
|
qse_printf (QSE_T("%d\n"), qse_env_insertsysm (env, QSE_MT("HOME")));
|
||||||
|
qse_printf (QSE_T("%d\n"), qse_env_insertsysw (env, QSE_WT("USER")));
|
||||||
|
qse_printf (QSE_T("%d\n"), qse_env_insertsys (env, QSE_T("WHAT")));
|
||||||
|
|
||||||
|
dump (env);
|
||||||
|
|
||||||
|
qse_env_close (env);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
int main ()
|
int main ()
|
||||||
{
|
{
|
||||||
R (test1);
|
R (test1);
|
||||||
R (test2);
|
R (test2);
|
||||||
|
R (test3);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,8 @@ qse_printf (QSE_T("content = [%.*S]\n"),
|
|||||||
if (dot && qse_mbscmp (dot, QSE_MT(".cgi")) == 0)
|
if (dot && qse_mbscmp (dot, QSE_MT(".cgi")) == 0)
|
||||||
{
|
{
|
||||||
/* cgi */
|
/* cgi */
|
||||||
x = qse_httpd_entaskcgi (httpd, client, QSE_NULL, QSE_T("/tmp/test.cgi"), qse_htre_getversion(req));
|
x = qse_httpd_entaskcgi (
|
||||||
|
httpd, client, QSE_NULL, qpath, req);
|
||||||
if (x == QSE_NULL) goto oops;
|
if (x == QSE_NULL) goto oops;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -71,7 +72,7 @@ qse_printf (QSE_T("content = [%.*S]\n"),
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rangestr = qse_htre_getheaderval (req, "Range");
|
rangestr = qse_htre_getheaderval (req, QSE_MT("Range"));
|
||||||
if (rangestr && qse_parsehttprange (rangestr, &range) <= -1)
|
if (rangestr && qse_parsehttprange (rangestr, &range) <= -1)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
Loading…
Reference in New Issue
Block a user