* added QSE_PIO_MBSCMD
* added qse_env_insertsys() and related functions
This commit is contained in:
		| @ -93,8 +93,13 @@ void qse_env_clear ( | ||||
| 	qse_env_t* env | ||||
| ); | ||||
|  | ||||
| #define qse_env_getstr(env) ((env)->str.ptr) | ||||
| #define qse_env_getarr(env) ((env)->arr.ptr) | ||||
| const qse_env_char_t* qse_env_getstr ( | ||||
| 	qse_env_t* env | ||||
| ); | ||||
|  | ||||
| qse_env_char_t** qse_env_getarr ( | ||||
| 	qse_env_t* env | ||||
| ); | ||||
|  | ||||
| int qse_env_insertw ( | ||||
| 	qse_env_t*        env, | ||||
| @ -118,12 +123,26 @@ int qse_env_deletem ( | ||||
| 	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) | ||||
| #	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_insertsys(env,name) qse_env_insertsysw(env,name) | ||||
| #else | ||||
| #	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_insertsys(env,name) qse_env_insertsysm(env,name) | ||||
| #endif | ||||
|  | ||||
| #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. | ||||
|     This file is part of QSE. | ||||
| @ -44,6 +44,10 @@ enum qse_pio_oflag_t | ||||
| 	 * (/bin/sh on *nix, cmd.exe on windows) */ | ||||
| 	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 */ | ||||
| 	QSE_PIO_WRITEIN    = (1 << 8), | ||||
| 	/** read stdout of a child process */ | ||||
| @ -51,9 +55,9 @@ enum qse_pio_oflag_t | ||||
| 	/** read stderr of a child process */ | ||||
| 	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),	 | ||||
| 	/** 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), | ||||
|  | ||||
| 	/** 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. | ||||
|  * 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  | ||||
|  * 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 | ||||
|  */ | ||||
| qse_pio_t* qse_pio_open ( | ||||
|  | ||||
| @ -213,8 +213,8 @@ qse_httpd_task_t* qse_httpd_entaskcgi ( | ||||
| 	qse_httpd_t*              httpd, | ||||
| 	qse_httpd_client_t*       client, | ||||
| 	const qse_httpd_task_t*   pred, | ||||
| 	const qse_char_t*         path, | ||||
| 	const qse_http_version_t* version | ||||
| 	const qse_mchar_t*        path, | ||||
| 	const qse_htre_t*         req | ||||
| ); | ||||
|  | ||||
| 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) | ||||
| { | ||||
| 	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.ptr[++env->str.len] = QSE_WT('\0');  | ||||
|  | ||||
| 	return -1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| 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.ptr[++env->str.len] = QSE_MT('\0');  | ||||
|  | ||||
| 	return -1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| 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 | ||||
| } | ||||
|  | ||||
| #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) | ||||
| { | ||||
| #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. | ||||
|     This file is part of QSE. | ||||
| @ -104,9 +104,7 @@ qse_pio_t* qse_pio_init ( | ||||
| 	SECURITY_ATTRIBUTES secattr;  | ||||
| 	PROCESS_INFORMATION procinfo; | ||||
| 	STARTUPINFO startup; | ||||
| 	qse_char_t* dup = QSE_NULL; | ||||
| 	HANDLE windevnul = INVALID_HANDLE_VALUE; | ||||
| 	BOOL x; | ||||
|  | ||||
| #elif defined(__OS2__) | ||||
| 	APIRET rc; | ||||
| @ -245,47 +243,48 @@ qse_pio_t* qse_pio_init ( | ||||
| 	/* there is nothing to do for QSE_PIO_SHELL as CreateProcess | ||||
| 	 * takes the entire command line */ | ||||
|  | ||||
| 	{ | ||||
| 		const qse_char_t* dupcmd; | ||||
| 		BOOL x; | ||||
|  | ||||
| 		if (oflags & QSE_PIO_SHELL)  | ||||
| 		{ | ||||
| 		dup = QSE_MMGR_ALLOC ( | ||||
| 			dupcmd = QSE_MMGR_ALLOC ( | ||||
| 				mmgr, (11+qse_strlen(cmd)+1 )*QSE_SIZEOF(qse_char_t)); | ||||
| 		if (dup == QSE_NULL) goto oops; | ||||
| 			if (dupcmd == QSE_NULL) goto oops; | ||||
|  | ||||
| 		qse_strcpy (dup, QSE_T("cmd.exe /c ")); | ||||
| 		qse_strcpy (&dup[11], cmd); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		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 ( | ||||
| 		NULL, /* LPCTSTR lpApplicationName */ | ||||
| 		dup,  /* LPTSTR lpCommandLine */ | ||||
| 		NULL, /* LPSECURITY_ATTRIBUTES lpProcessAttributes */ | ||||
| 		NULL, /* LPSECURITY_ATTRIBUTES lpThreadAttributes */ | ||||
| 			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 | ||||
| 		#ifdef QSE_CHAR_IS_MCHAR | ||||
| 			0,         /* DWORD dwCreationFlags */ | ||||
| #else | ||||
| 		#else | ||||
| 			CREATE_UNICODE_ENVIRONMENT, /* DWORD dwCreationFlags */ | ||||
| #endif | ||||
| 		#endif | ||||
| 			(env? qse_env_getstr(env): QSE_NULL), /* LPVOID lpEnvironment */ | ||||
| 		NULL, /* LPCTSTR lpCurrentDirectory */ | ||||
| 			QSE_NULL, /* LPCTSTR lpCurrentDirectory */ | ||||
| 			&startup, /* LPSTARTUPINFO lpStartupInfo */ | ||||
| 			&procinfo /* LPPROCESS_INFORMATION lpProcessInformation */ | ||||
| 		); | ||||
|  | ||||
| 	QSE_MMGR_FREE (mmgr, dup); dup = QSE_NULL; | ||||
| 		if (dupcmd != cmd) QSE_MMGR_FREE (mmgr, dupcmd);  | ||||
| 		if (x == FALSE) goto oops; | ||||
| 	} | ||||
|  | ||||
| 	if (windevnul != INVALID_HANDLE_VALUE) | ||||
| 	{ | ||||
| 		CloseHandle (windevnul);  | ||||
| 		windevnul = INVALID_HANDLE_VALUE; | ||||
| 	} | ||||
|  | ||||
| 	if (x == FALSE) goto oops; | ||||
|  | ||||
| 	if (oflags & QSE_PIO_WRITEIN) | ||||
| 	{ | ||||
| 		CloseHandle (handle[0]); | ||||
| @ -577,8 +576,6 @@ qse_pio_t* qse_pio_init ( | ||||
| 		qse_mchar_t* mcmd; | ||||
| 		int fcnt = 0; | ||||
| 	#ifndef QSE_CHAR_IS_MCHAR | ||||
| 		qse_size_t n, mn, wl; | ||||
| 		qse_char_t* wcmd = QSE_NULL; | ||||
| 		qse_mchar_t buf[64]; | ||||
| 	#endif | ||||
|  | ||||
| @ -694,6 +691,31 @@ qse_pio_t* qse_pio_init ( | ||||
| 			} | ||||
| 		} | ||||
| 	#else	 | ||||
| 		if (oflags & QSE_PIO_MBSCMD)  | ||||
| 		{ | ||||
| 			/* the cmd is flagged to be of qse_mchar_t  | ||||
| 			 * while the default character type is qse_wchar_t. */ | ||||
|  | ||||
| 			if (oflags & QSE_PIO_SHELL) mcmd = (qse_mchar_t*)cmd; | ||||
| 			else | ||||
| 			{ | ||||
| 				mcmd =  qse_mbsdup ((const qse_mchar_t*)cmd, pio->mmgr); | ||||
| 				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 | ||||
| 		{ | ||||
| 			qse_size_t n, mn, wl; | ||||
| 			qse_char_t* wcmd = QSE_NULL; | ||||
|  | ||||
| 			if (oflags & QSE_PIO_SHELL) | ||||
| 			{ | ||||
| 				n = qse_wcstombslen (cmd, &mn); | ||||
| @ -758,6 +780,7 @@ qse_pio_t* qse_pio_init ( | ||||
| 				/* qse_wcsntombsn() doesn't null-terminate mcmd */ | ||||
| 				mcmd[mn] = QSE_MT('\0'); | ||||
| 			} | ||||
| 		} | ||||
| 	#endif | ||||
|  | ||||
| 		if (oflags & QSE_PIO_SHELL) | ||||
| @ -880,7 +903,6 @@ oops: | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| 	if (windevnul != INVALID_HANDLE_VALUE) CloseHandle (windevnul); | ||||
| 	if (dup) QSE_MMGR_FREE (mmgr, dup); | ||||
|  | ||||
| #elif defined(__OS2__) | ||||
| 	if (cmd_line) QSE_MMGR_FREE (mmgr, cmd_line); | ||||
|  | ||||
| @ -34,7 +34,7 @@ | ||||
| #ifdef HAVE_SYS_SENDFILE_H | ||||
| #	include <sys/sendfile.h> | ||||
| #else | ||||
| qse_ssize_t sendfile ( | ||||
| static qse_ssize_t sendfile ( | ||||
| 	int out_fd, int in_fd, qse_foff_t* offset, qse_size_t count) | ||||
| { | ||||
| 	qse_mchar_t buf[MAX_SEND_SIZE]; | ||||
| @ -55,7 +55,6 @@ qse_ssize_t sendfile ( | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| /*------------------------------------------------------------------------*/ | ||||
|  | ||||
| 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; | ||||
| struct task_cgi_arg_t  | ||||
| { | ||||
| 	const qse_char_t* path; | ||||
| 	qse_http_version_t version; | ||||
| 	const qse_mchar_t* path; | ||||
| 	const qse_htre_t* req; | ||||
| }; | ||||
|  | ||||
| typedef struct task_cgi_t 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_env_t* env; | ||||
| @ -822,6 +823,45 @@ static qse_htrd_recbs_t cgi_htrd_cbs = | ||||
|      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 ( | ||||
| 	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; | ||||
|  | ||||
| 	QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn)); | ||||
| 	qse_strcpy ((qse_char_t*)(xtn + 1), arg->path); | ||||
| 	xtn->path = (qse_char_t*)(xtn + 1); | ||||
| 	xtn->version = arg->version; | ||||
| 	qse_mbscpy ((qse_mchar_t*)(xtn + 1), arg->path); | ||||
| 	xtn->path = (qse_mchar_t*)(xtn + 1); | ||||
| 	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; | ||||
| 	return 0; | ||||
| } | ||||
| @ -1090,6 +1134,10 @@ static int task_main_cgi ( | ||||
| { | ||||
| 	task_cgi_t* cgi = (task_cgi_t*)task->ctx; | ||||
| 	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)); | ||||
| 	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); | ||||
| 	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 ( | ||||
| 		httpd->mmgr, 0, cgi->path, cgi->env, | ||||
| 		QSE_PIO_READOUT | QSE_PIO_WRITEIN | QSE_PIO_ERRTONUL | ||||
| 		httpd->mmgr, 0, (const qse_char_t*)cgi->path, cgi->env, | ||||
| 		QSE_PIO_READOUT | QSE_PIO_WRITEIN | QSE_PIO_ERRTONUL | QSE_PIO_MBSCMD | ||||
| 	); | ||||
| 	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 */ | ||||
| 	return task_main_cgi_2 (httpd, client, task); /* let me call it here once */ | ||||
|  | ||||
| oops: | ||||
| /* TODO: internal server error */ | ||||
| 	if (cgi->env) qse_env_close (cgi->env); | ||||
| 	if (cgi->res) qse_mbs_close (cgi->res); | ||||
| 	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; | ||||
| } | ||||
|  | ||||
| @ -1136,14 +1184,14 @@ qse_httpd_task_t* qse_httpd_entaskcgi ( | ||||
| 	qse_httpd_t* httpd, | ||||
| 	qse_httpd_client_t* client, | ||||
| 	const qse_httpd_task_t* pred,  | ||||
| 	const qse_char_t* path, | ||||
| 	const qse_http_version_t* version) | ||||
| 	const qse_mchar_t* path, | ||||
| 	const qse_htre_t* req) | ||||
| { | ||||
| 	qse_httpd_task_t task; | ||||
| 	task_cgi_arg_t arg; | ||||
|  | ||||
| 	arg.path = path; | ||||
| 	arg.version = *version; | ||||
| 	arg.req = req; | ||||
|  | ||||
| 	QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); | ||||
| 	task.init = task_init_cgi; | ||||
| @ -1153,7 +1201,7 @@ qse_httpd_task_t* qse_httpd_entaskcgi ( | ||||
|  | ||||
| 	return qse_httpd_entask ( | ||||
| 		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,8 +14,6 @@ static void dump (qse_env_t* env) | ||||
| 	qse_env_char_t** envarr; | ||||
|  | ||||
| 	envstr = qse_env_getstr (env); | ||||
| 	if (envstr) | ||||
| 	{ | ||||
| #if (defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)) || \ | ||||
|     (defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR))  | ||||
| 	while (*envstr != QSE_T('\0')) | ||||
| @ -36,12 +34,9 @@ static void dump (qse_env_t* env) | ||||
| 		envstr += qse_mbslen(envstr) + 1; | ||||
| 	} | ||||
| #endif | ||||
| 	} | ||||
|  | ||||
| 	qse_printf (QSE_T("=====\n")); | ||||
| 	qse_printf (QSE_T("-------------\n")); | ||||
| 	envarr = qse_env_getarr (env); | ||||
| 	if (envarr) | ||||
| 	{ | ||||
| 	while (*envarr) | ||||
| 	{ | ||||
| #if (defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)) || \ | ||||
| @ -52,7 +47,6 @@ static void dump (qse_env_t* env) | ||||
| #endif | ||||
| 		envarr++; | ||||
| 	} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int test1 (void) | ||||
| @ -105,9 +99,28 @@ static int test2 (void) | ||||
| 	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 () | ||||
| { | ||||
| 	R (test1); | ||||
| 	R (test2); | ||||
| 	R (test3); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -62,7 +62,8 @@ qse_printf (QSE_T("content = [%.*S]\n"), | ||||
| 		if (dot && qse_mbscmp (dot, QSE_MT(".cgi")) == 0) | ||||
| 		{ | ||||
| 			/* 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 0 | ||||
| @ -71,7 +72,7 @@ qse_printf (QSE_T("content = [%.*S]\n"), | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			rangestr = qse_htre_getheaderval (req, "Range"); | ||||
| 			rangestr = qse_htre_getheaderval (req, QSE_MT("Range")); | ||||
| 			if (rangestr && qse_parsehttprange (rangestr, &range) <= -1) | ||||
| 			{ | ||||
| #if 0 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user