diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 44a2deba..be61edd5 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 470 2011-05-21 16:20:01Z hyunghwan.chung $ + * $Id: awk.c 510 2011-07-20 16:17:16Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -248,7 +248,7 @@ static qse_htb_walk_t print_awk_value ( dprint (QSE_T("%.*s = %.*s\n"), (int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair), (int)len, str); - qse_awk_free (qse_awk_rtx_getawk(rtx), str); + qse_awk_freemem (qse_awk_rtx_getawk(rtx), str); } return QSE_HTB_WALK_FORWARD; @@ -318,7 +318,7 @@ static void dprint_return (qse_awk_rtx_t* rtx, qse_awk_val_t* ret) else { dprint (QSE_T("[RETURN] - [%.*s]\n"), (int)len, str); - qse_awk_free (qse_awk_rtx_getawk(rtx), str); + qse_awk_freemem (qse_awk_rtx_getawk(rtx), str); } } diff --git a/qse/configure b/qse/configure index f19e69ce..936bc763 100755 --- a/qse/configure +++ b/qse/configure @@ -15300,7 +15300,7 @@ fi done -for ac_header in time.h sys/time.h utime.h sys/resource.h sys/syscall.h +for ac_header in time.h sys/time.h utime.h sys/resource.h sys/syscall.h sys/sendfile.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/qse/configure.ac b/qse/configure.ac index d6814580..6a4feb8a 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -79,7 +79,7 @@ AC_SUBST(LIBM, $LIBM) dnl check header files. AC_HEADER_STDC AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h]) -AC_CHECK_HEADERS([time.h sys/time.h utime.h sys/resource.h sys/syscall.h]) +AC_CHECK_HEADERS([time.h sys/time.h utime.h sys/resource.h sys/syscall.h sys/sendfile.h]) AC_CHECK_HEADERS([execinfo.h]) dnl check data types diff --git a/qse/doc/page/main.doc b/qse/doc/page/main.doc index 9af24080..efa45701 100644 --- a/qse/doc/page/main.doc +++ b/qse/doc/page/main.doc @@ -81,7 +81,7 @@ Under the wide character mode: - #QSE_CHAR_IS_WCHAR is defined. - #qse_char_t maps to #qse_wchar_t. -#qse_mchar_t maps @b char and #qse_wchar_t maps to @b wchar_t or equivalent. +#qse_mchar_t maps to @b char and #qse_wchar_t maps to @b wchar_t or equivalent. @section library_modules LIBRARY MODULES @b QSE contains a set of APIs. Each set is organized into a library module diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index cdbfe78c..8826bed0 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 485 2011-05-29 15:15:52Z hyunghwan.chung $ + * $Id: awk.h 510 2011-07-20 16:17:16Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -1442,28 +1442,28 @@ int qse_awk_parse ( ); /** - * The qse_awk_alloc() function allocates dynamic memory. + * The qse_awk_allocmem() function allocates dynamic memory. * @return a pointer to a memory block on success, #QSE_NULL on failure */ -void* qse_awk_alloc ( +void* qse_awk_allocmem ( qse_awk_t* awk, /**< awk */ qse_size_t size /**< size of memory to allocate in bytes */ ); /** - * The qse_awk_realloc() function resizes a dynamic memory block. + * The qse_awk_reallocmem() function resizes a dynamic memory block. * @return a pointer to a memory block on success, #QSE_NULL on failure */ -void* qse_awk_realloc ( +void* qse_awk_reallocmem ( qse_awk_t* awk, /**< awk */ void* ptr, /**< memory block */ qse_size_t size /**< new block size in bytes */ ); /** - * The qse_awk_free() function frees dynamic memory allocated. + * The qse_awk_freemem() function frees dynamic memory allocated. */ -void qse_awk_free ( +void qse_awk_freemem ( qse_awk_t* awk, /**< awk */ void* ptr /**< memory block to free */ ); @@ -2237,32 +2237,32 @@ int qse_awk_rtx_strtonum ( ); /** - * The qse_awk_rtx_alloc() function allocats a memory block of @a size bytes + * The qse_awk_rtx_allocmem() function allocats a memory block of @a size bytes * using the memory manager associated with a runtime context @a rtx. * @return the pointer to a memory block on success, #QSE_NULL on failure. */ -void* qse_awk_rtx_alloc ( +void* qse_awk_rtx_allocmem ( qse_awk_rtx_t* rtx, /**< runtime context */ qse_size_t size /**< block size in bytes */ ); /** - * The qse_awk_rtx_realloc() function resizes a memory block pointed to + * The qse_awk_rtx_reallocmem() function resizes a memory block pointed to * by @a ptr to @a size bytes using the memory manager associated with * a runtime context @a rtx. * @return the pointer to a memory block on success, #QSE_NULL on failure. */ -void* qse_awk_rtx_realloc ( +void* qse_awk_rtx_reallocmem ( qse_awk_rtx_t* rtx, /**< runtime context */ void* ptr, /**< memory block */ qse_size_t size /**< block size in bytes */ ); /** - * The qse_awk_rtx_free() function frees a memory block pointed to by @a ptr + * The qse_awk_rtx_freemem() function frees a memory block pointed to by @a ptr * using the memory manager of a runtime ocntext @a rtx. */ -void qse_awk_rtx_free ( +void qse_awk_rtx_freemem ( qse_awk_rtx_t* rtx, /**< runtime context */ void* ptr /**< memory block pointer */ ); diff --git a/qse/include/qse/cmn/xma.h b/qse/include/qse/cmn/xma.h index d5c9b5af..23e6c136 100644 --- a/qse/include/qse/cmn/xma.h +++ b/qse/include/qse/cmn/xma.h @@ -104,7 +104,15 @@ struct qse_xma_t #endif }; -typedef int (*qse_xma_dumper_t) (void* target, const qse_char_t* fmt,...); +/** + * The qse_xma_dumper_t type defines a printf-like output function + * for qse_xma_dump(). + */ +typedef int (*qse_xma_dumper_t) ( + void* ctx, + const qse_char_t* fmt, + ... +); #ifdef __cplusplus extern "C" { @@ -187,13 +195,13 @@ void qse_xma_free ( /** * The qse_xma_dump() function dumps the contents of the memory zone - * with the output function @a printf provided. The debug build shows + * with the output function @a dumper provided. The debug build shows * more statistical counters. */ void qse_xma_dump ( qse_xma_t* xma, /**< memory allocator */ qse_xma_dumper_t dumper, /**< output function */ - void* target /**< first parameter to output function */ + void* ctx /**< first parameter to output function */ ); #ifdef __cplusplus diff --git a/qse/include/qse/config.h.in b/qse/include/qse/config.h.in index f1181e3b..0beed710 100644 --- a/qse/include/qse/config.h.in +++ b/qse/include/qse/config.h.in @@ -144,6 +144,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SENDFILE_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H diff --git a/qse/include/qse/net/httpd.h b/qse/include/qse/net/httpd.h index 43589826..1beb6732 100644 --- a/qse/include/qse/net/httpd.h +++ b/qse/include/qse/net/httpd.h @@ -128,11 +128,35 @@ int qse_httpd_entasksendfmt ( ... ); +int qse_httpd_entasksendfile ( + qse_httpd_t* httpd, + qse_httpd_client_t* client, + int fd, + qse_foff_t offset, + qse_foff_t size +); + int qse_httpd_entaskdisconnect ( qse_httpd_t* httpd, qse_httpd_client_t* client ); +void* qse_httpd_allocmem ( + qse_httpd_t* httpd, + qse_size_t size +); + +void* qse_httpd_reallocmem ( + qse_httpd_t* httpd, + void* ptr, + qse_size_t size +); + +void qse_httpd_freemem ( + qse_httpd_t* httpd, + void* ptr +); + #ifdef __cplusplus } #endif diff --git a/qse/include/qse/types.h b/qse/include/qse/types.h index 592049da..8b5ba5c3 100644 --- a/qse/include/qse/types.h +++ b/qse/include/qse/types.h @@ -1,5 +1,5 @@ /* - * $Id: types.h 504 2011-07-11 16:31:33Z hyunghwan.chung $ + * $Id: types.h 510 2011-07-20 16:17:16Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -336,7 +336,6 @@ typedef qse_int_t qse_intptr_t; typedef double qse_real_t; #endif - /** * The qse_mchar_t type defines a multi-byte character type. */ @@ -575,4 +574,66 @@ typedef struct qse_mmgr_t qse_mmgr_t; # error Unsupported platform #endif +/* The qse_ubi_t type defines a union type that includes most of built-in + * data types and numeric types defined in the library. */ +union qse_ubi_t +{ + char c; + unsigned char uc; + short s; + unsigned short us; + int i; + unsigned int ui; + long l; + unsigned long ul; +#if defined(QSE_SIZEOF_LONG_LONG) && (QSE_SIZEOF_LONG_LONG > 0) + long long ll; + unsigned long long ull; +#endif + float f; + double d; +#if defined(QSE_SIZEOF_LONG_DOUBLE) && (QSE_SIZEOF_LONG_DOUBLE > 0) + long double ld; +#endif + void* ptr; + + qse_byte_t byte; + qse_int_t sint; + qse_uint_t uint; + qse_long_t slong; + qse_ulong_t ulong; + qse_size_t size; + qse_ssize_t ssize; + qse_word_t word; + qse_intptr_t intptr; + qse_uintptr_t uintptr; + qse_real_t real; + + qse_char_t cha; + qse_mchar_t mchar; + qse_wchar_t wchar; + qse_cint_t cint; + qse_mcint_t mcint; + qse_wcint_t wcint; + + qse_int8_t int8; + qse_uint8_t uint8; + qse_int16_t int16; + qse_uint16_t uint16; + qse_int32_t int32; + qse_uint32_t uint32; +#if defined(QSE_HAVE_INT64_T) + qse_int64_t int64; + qse_uint64_t uint64; +#endif +#if defined(QSE_HAVE_INT128_T) + qse_int128_t int128; + qse_uint128_t uint128; +#endif + qse_foff_t foff; +}; +typedef union qse_ubi_t qse_ubi_t; + + + #endif diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 46f684e4..922589d5 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 480 2011-05-25 14:00:19Z hyunghwan.chung $ + * $Id: Awk.cpp 510 2011-07-20 16:17:16Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -139,7 +139,7 @@ Awk::Console::~Console () { if (filename != QSE_NULL) { - qse_awk_free ((awk_t*)this, filename); + qse_awk_freemem ((awk_t*)this, filename); } } @@ -230,7 +230,7 @@ Awk::Value::IntIndex::IntIndex (long_t x) void* Awk::Value::operator new (size_t n, Run* run) throw () { - void* ptr = qse_awk_rtx_alloc (run->rtx, QSE_SIZEOF(run) + n); + void* ptr = qse_awk_rtx_allocmem (run->rtx, QSE_SIZEOF(run) + n); if (ptr == QSE_NULL) return QSE_NULL; *(Run**)ptr = run; @@ -239,7 +239,7 @@ void* Awk::Value::operator new (size_t n, Run* run) throw () void* Awk::Value::operator new[] (size_t n, Run* run) throw () { - void* ptr = qse_awk_rtx_alloc (run->rtx, QSE_SIZEOF(run) + n); + void* ptr = qse_awk_rtx_allocmem (run->rtx, QSE_SIZEOF(run) + n); if (ptr == QSE_NULL) return QSE_NULL; *(Run**)ptr = run; @@ -249,25 +249,25 @@ void* Awk::Value::operator new[] (size_t n, Run* run) throw () #if !defined(__BORLANDC__) void Awk::Value::operator delete (void* ptr, Run* run) { - qse_awk_rtx_free (run->rtx, (char*)ptr-QSE_SIZEOF(run)); + qse_awk_rtx_freemem (run->rtx, (char*)ptr-QSE_SIZEOF(run)); } void Awk::Value::operator delete[] (void* ptr, Run* run) { - qse_awk_rtx_free (run->rtx, (char*)ptr-QSE_SIZEOF(run)); + qse_awk_rtx_freemem (run->rtx, (char*)ptr-QSE_SIZEOF(run)); } #endif void Awk::Value::operator delete (void* ptr) { void* p = (char*)ptr-QSE_SIZEOF(Run*); - qse_awk_rtx_free ((*(Run**)p)->rtx, p); + qse_awk_rtx_freemem ((*(Run**)p)->rtx, p); } void Awk::Value::operator delete[] (void* ptr) { void* p = (char*)ptr-QSE_SIZEOF(Run*); - qse_awk_rtx_free ((*(Run**)p)->rtx, p); + qse_awk_rtx_freemem ((*(Run**)p)->rtx, p); } Awk::Value::Value (): run (QSE_NULL), val (qse_awk_val_nil) @@ -303,7 +303,7 @@ Awk::Value::~Value () { qse_awk_rtx_refdownval (run->rtx, val); if (cached.str.ptr != QSE_NULL) - qse_awk_rtx_free (run->rtx, cached.str.ptr); + qse_awk_rtx_freemem (run->rtx, cached.str.ptr); } } @@ -316,7 +316,7 @@ Awk::Value& Awk::Value::operator= (const Value& v) qse_awk_rtx_refdownval (run->rtx, val); if (cached.str.ptr != QSE_NULL) { - qse_awk_rtx_free (run->rtx, cached.str.ptr); + qse_awk_rtx_freemem (run->rtx, cached.str.ptr); cached.str.ptr = QSE_NULL; cached.str.len = 0; } @@ -339,7 +339,7 @@ void Awk::Value::clear () if (cached.str.ptr != QSE_NULL) { - qse_awk_rtx_free (run->rtx, cached.str.ptr); + qse_awk_rtx_freemem (run->rtx, cached.str.ptr); cached.str.ptr = QSE_NULL; cached.str.len = 0; } @@ -485,7 +485,7 @@ int Awk::Value::setVal (Run* r, val_t* v) qse_awk_rtx_refdownval (this->run->rtx, val); if (cached.str.ptr != QSE_NULL) { - qse_awk_rtx_free (this->run->rtx, cached.str.ptr); + qse_awk_rtx_freemem (this->run->rtx, cached.str.ptr); cached.str.ptr = QSE_NULL; cached.str.len = 0; } @@ -1062,7 +1062,7 @@ static void free_function_map_value ( Awk::htb_t* map, void* dptr, Awk::size_t dlen) { Awk* awk = *(Awk**) QSE_XTN (map); - qse_awk_free ((Awk::awk_t*)*awk, dptr); + qse_awk_freemem ((Awk::awk_t*)*awk, dptr); } int Awk::open () @@ -1214,7 +1214,7 @@ int Awk::call ( if (nargs <= QSE_COUNTOF(buf)) ptr = buf; else { - ptr = (val_t**) qse_awk_alloc ( + ptr = (val_t**) qse_awk_allocmem ( awk, QSE_SIZEOF(val_t*) * nargs); if (ptr == QSE_NULL) { @@ -1229,7 +1229,7 @@ int Awk::call ( val_t* rv = qse_awk_rtx_call (runctx.rtx, name, ptr, nargs); - if (ptr != QSE_NULL && ptr != buf) qse_awk_free (awk, ptr); + if (ptr != QSE_NULL && ptr != buf) qse_awk_freemem (awk, ptr); if (rv == QSE_NULL) { @@ -1409,7 +1409,7 @@ int Awk::xstrs_t::add (awk_t* awk, const char_t* arg, size_t len) size_t capa = this->capa; capa += 64; - ptr = (qse_xstr_t*) qse_awk_realloc ( + ptr = (qse_xstr_t*) qse_awk_reallocmem ( awk, this->ptr, QSE_SIZEOF(qse_xstr_t)*(capa+1)); if (ptr == QSE_NULL) return -1; @@ -1433,9 +1433,9 @@ void Awk::xstrs_t::clear (awk_t* awk) if (this->ptr != QSE_NULL) { while (this->len > 0) - qse_awk_free (awk, this->ptr[--this->len].ptr); + qse_awk_freemem (awk, this->ptr[--this->len].ptr); - qse_awk_free (awk, this->ptr); + qse_awk_freemem (awk, this->ptr); this->ptr = QSE_NULL; this->capa = 0; } @@ -1517,7 +1517,7 @@ int Awk::addFunction ( QSE_ASSERT (awk != QSE_NULL); FunctionHandler* tmp = (FunctionHandler*) - qse_awk_alloc (awk, QSE_SIZEOF(handler)); + qse_awk_allocmem (awk, QSE_SIZEOF(handler)); if (tmp == QSE_NULL) { setError (QSE_AWK_ENOMEM); @@ -1540,7 +1540,7 @@ int Awk::addFunction ( functionHandler); if (p == QSE_NULL) { - qse_awk_free (awk, tmp); + qse_awk_freemem (awk, tmp); retrieveError (); return -1; } @@ -1550,7 +1550,7 @@ int Awk::addFunction ( if (pair == QSE_NULL) { qse_awk_delfnc (awk, name, nameLen); - qse_awk_free (awk, tmp); + qse_awk_freemem (awk, tmp); setError (QSE_AWK_ENOMEM); return -1; diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index 49d90de1..4e2f13b8 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.cpp 480 2011-05-25 14:00:19Z hyunghwan.chung $ + * $Id: StdAwk.cpp 510 2011-07-20 16:17:16Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -114,7 +114,7 @@ int StdAwk::system (Run& run, Value& ret, const Value* args, size_t nargs, #elif defined(QSE_CHAR_IS_MCHAR) return ret.setInt ((long_t)::system(ptr)); #else - char* mbs = (char*) qse_awk_alloc ((awk_t*)(Awk*)run, l*5+1); + char* mbs = (char*) qse_awk_allocmem ((awk_t*)(Awk*)run, l*5+1); if (mbs == QSE_NULL) return -1; /* at this point, the string is guaranteed to be @@ -126,14 +126,14 @@ int StdAwk::system (Run& run, Value& ret, const Value* args, size_t nargs, { /* not the entire string is converted. * mbs is not null-terminated properly. */ - qse_awk_free ((awk_t*)(Awk*)run, mbs); + qse_awk_freemem ((awk_t*)(Awk*)run, mbs); return -1; } mbs[mbl] = '\0'; int n = ret.setInt ((long_t)::system(mbs)); - qse_awk_free ((awk_t*)(Awk*)run, mbs); + qse_awk_freemem ((awk_t*)(Awk*)run, mbs); return n; #endif } @@ -381,7 +381,7 @@ int StdAwk::open_console_in (Console& io) if (out.u.cpldup.len == 0) { /* the name is empty */ - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); runarg_index++; goto nextfile; } @@ -393,7 +393,7 @@ int StdAwk::open_console_in (Console& io) arg.ptr = out.u.cpldup.ptr; arg.len = qse_strlen (arg.ptr); ((Run*)io)->setError (QSE_AWK_EIONMNL, &arg); - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); return -1; } @@ -414,7 +414,7 @@ int StdAwk::open_console_in (Console& io) arg.ptr = file; arg.len = qse_strlen (arg.ptr); ((Run*)io)->setError (QSE_AWK_EOPEN, &arg); - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); return -1; } } @@ -423,11 +423,11 @@ int StdAwk::open_console_in (Console& io) rtx, file, qse_strlen(file)) == -1) { if (sio != qse_sio_in) qse_sio_close (sio); - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); return -1; } - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); io.setHandle (sio); /* increment the counter of files successfully opened */ diff --git a/qse/lib/awk/misc.c b/qse/lib/awk/misc.c index 8f7a726d..52ccfd5e 100644 --- a/qse/lib/awk/misc.c +++ b/qse/lib/awk/misc.c @@ -1,5 +1,5 @@ /* - * $Id: misc.c 462 2011-05-18 14:36:40Z hyunghwan.chung $ + * $Id: misc.c 510 2011-07-20 16:17:16Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -20,29 +20,37 @@ #include "awk.h" -void* qse_awk_alloc (qse_awk_t* awk, qse_size_t size) +void* qse_awk_allocmem (qse_awk_t* awk, qse_size_t size) { - return QSE_AWK_ALLOC (awk, size); + void* ptr = QSE_AWK_ALLOC (awk, size); + if (ptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return ptr; } -void* qse_awk_realloc (qse_awk_t* awk, void* ptr, qse_size_t size) +void* qse_awk_reallocmem (qse_awk_t* awk, void* ptr, qse_size_t size) { - return QSE_AWK_REALLOC (awk, ptr, size); + void* nptr = QSE_AWK_REALLOC (awk, ptr, size); + if (nptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return nptr; } -void qse_awk_free (qse_awk_t* awk, void* ptr) +void qse_awk_freemem (qse_awk_t* awk, void* ptr) { QSE_AWK_FREE (awk, ptr); } qse_char_t* qse_awk_strdup (qse_awk_t* awk, const qse_char_t* s) { - return QSE_AWK_STRDUP (awk, s); + qse_char_t* ptr = QSE_AWK_STRDUP (awk, s); + if (ptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return ptr; } qse_char_t* qse_awk_strxdup (qse_awk_t* awk, const qse_char_t* s, qse_size_t l) { - return QSE_AWK_STRXDUP (awk, s, l); + qse_char_t* ptr = QSE_AWK_STRXDUP (awk, s, l); + if (ptr == QSE_NULL) qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return ptr; } qse_long_t qse_awk_strxtolong ( @@ -1085,18 +1093,18 @@ int qse_awk_matchrex ( return x; } -void* qse_awk_rtx_alloc (qse_awk_rtx_t* rtx, qse_size_t size) +void* qse_awk_rtx_allocmem (qse_awk_rtx_t* rtx, qse_size_t size) { - return qse_awk_alloc (rtx->awk, size); + return qse_awk_allocmem (rtx->awk, size); } -void* qse_awk_rtx_realloc (qse_awk_rtx_t* rtx, void* ptr, qse_size_t size) +void* qse_awk_rtx_reallocmem (qse_awk_rtx_t* rtx, void* ptr, qse_size_t size) { - return qse_awk_realloc (rtx->awk, ptr, size); + return qse_awk_reallocmem (rtx->awk, ptr, size); } -void qse_awk_rtx_free (qse_awk_rtx_t* rtx, void* ptr) +void qse_awk_rtx_freemem (qse_awk_rtx_t* rtx, void* ptr) { - qse_awk_free (rtx->awk, ptr); + qse_awk_freemem (rtx->awk, ptr); } diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 3a0aaa49..f9ba3df0 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -1,5 +1,5 @@ /* - * $Id: std.c 481 2011-05-25 14:42:26Z hyunghwan.chung $ + * $Id: std.c 510 2011-07-20 16:17:16Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -1013,7 +1013,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) if (out.u.cpldup.len == 0) { /* the name is empty */ - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); rxtn->c.in.index++; goto nextfile; } @@ -1031,7 +1031,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) qse_awk_rtx_seterrnum ( rtx, QSE_AWK_EIONMNL, &errarg); - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); return -1; } @@ -1056,7 +1056,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) qse_awk_rtx_seterrnum ( rtx, QSE_AWK_EOPEN, &errarg); - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); return -1; } } @@ -1065,11 +1065,11 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) rtx, file, qse_strlen(file)) <= -1) { if (sio != qse_sio_in) qse_sio_close (sio); - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); return -1; } - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); riod->handle = sio; /* increment the counter of files successfully opened */ @@ -1465,7 +1465,7 @@ static int fnc_system (qse_awk_rtx_t* run, const qse_cstr_t* fnm) char* mbs; qse_size_t mbl; - mbs = (char*) qse_awk_alloc (run->awk, len*5+1); + mbs = (char*) qse_awk_allocmem (run->awk, len*5+1); if (mbs == QSE_NULL) { n = -1; @@ -1489,7 +1489,7 @@ static int fnc_system (qse_awk_rtx_t* run, const qse_cstr_t* fnm) n = system (mbs); skip_system_mbs: - qse_awk_free (run->awk, mbs); + qse_awk_freemem (run->awk, mbs); } #endif diff --git a/qse/lib/cmn/xma.c b/qse/lib/cmn/xma.c index e9c02514..1a82bad0 100644 --- a/qse/lib/cmn/xma.c +++ b/qse/lib/cmn/xma.c @@ -704,7 +704,7 @@ void qse_xma_free (qse_xma_t* xma, void* b) } } -void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* target) +void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* ctx) { qse_xma_blk_t* tmp; qse_ulong_t fsum, asum; @@ -712,31 +712,31 @@ void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* target) qse_ulong_t isum; #endif - dumper (target, QSE_T("\n")); + dumper (ctx, QSE_T("\n")); #ifdef QSE_XMA_ENABLE_STAT - dumper (target, QSE_T("== statistics ==\n")); + dumper (ctx, QSE_T("== statistics ==\n")); #if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG - dumper (target, QSE_T("total = %lu\n"), (unsigned long)xma->stat.total); - dumper (target, QSE_T("alloc = %lu\n"), (unsigned long)xma->stat.alloc); - dumper (target, QSE_T("avail = %lu\n"), (unsigned long)xma->stat.avail); + dumper (ctx, QSE_T("total = %lu\n"), (unsigned long)xma->stat.total); + dumper (ctx, QSE_T("alloc = %lu\n"), (unsigned long)xma->stat.alloc); + dumper (ctx, QSE_T("avail = %lu\n"), (unsigned long)xma->stat.avail); #else - dumper (target, QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total); - dumper (target, QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc); - dumper (target, QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail); + dumper (ctx, QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total); + dumper (ctx, QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc); + dumper (ctx, QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail); #endif #endif - dumper (target, QSE_T("== blocks ==\n")); - dumper (target, QSE_T(" size avail address\n")); + dumper (ctx, QSE_T("== blocks ==\n")); + dumper (ctx, QSE_T(" size avail address\n")); for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next) { #if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG - dumper (target, QSE_T(" %-18lu %-5d %p\n"), + dumper (ctx, QSE_T(" %-18lu %-5d %p\n"), (unsigned long)tmp->size, tmp->avail, tmp ); #else - dumper (target, QSE_T(" %-18llu %-5d %p\n"), + dumper (ctx, QSE_T(" %-18llu %-5d %p\n"), (unsigned long long)tmp->size, tmp->avail, tmp ); #endif @@ -748,22 +748,22 @@ void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* target) isum = (xma->stat.nfree + xma->stat.nused) * HDRSIZE; #endif - dumper (target, QSE_T("---------------------------------------\n")); + dumper (ctx, QSE_T("---------------------------------------\n")); #if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG - dumper (target, QSE_T("Allocated blocks: %18lu bytes\n"), (unsigned long)asum); - dumper (target, QSE_T("Available blocks: %18lu bytes\n"), (unsigned long)fsum); + dumper (ctx, QSE_T("Allocated blocks: %18lu bytes\n"), (unsigned long)asum); + dumper (ctx, QSE_T("Available blocks: %18lu bytes\n"), (unsigned long)fsum); #else - dumper (target, QSE_T("Allocated blocks: %18llu bytes\n"), (unsigned long long)asum); - dumper (target, QSE_T("Available blocks: %18llu bytes\n"), (unsigned long long)fsum); + dumper (ctx, QSE_T("Allocated blocks: %18llu bytes\n"), (unsigned long long)asum); + dumper (ctx, QSE_T("Available blocks: %18llu bytes\n"), (unsigned long long)fsum); #endif #ifdef QSE_XMA_ENABLE_STAT #if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG - dumper (target, QSE_T("Internal use : %18lu bytes\n"), (unsigned long)isum); - dumper (target, QSE_T("Total : %18lu bytes\n"), (unsigned long)(asum + fsum + isum)); + dumper (ctx, QSE_T("Internal use : %18lu bytes\n"), (unsigned long)isum); + dumper (ctx, QSE_T("Total : %18lu bytes\n"), (unsigned long)(asum + fsum + isum)); #else - dumper (target, QSE_T("Internal use : %18llu bytes\n"), (unsigned long long)isum); - dumper (target, QSE_T("Total : %18llu bytes\n"), (unsigned long long)(asum + fsum + isum)); + dumper (ctx, QSE_T("Internal use : %18llu bytes\n"), (unsigned long long)isum); + dumper (ctx, QSE_T("Total : %18llu bytes\n"), (unsigned long long)(asum + fsum + isum)); #endif #endif diff --git a/qse/lib/net/Makefile.am b/qse/lib/net/Makefile.am index acd6013c..92ac556d 100644 --- a/qse/lib/net/Makefile.am +++ b/qse/lib/net/Makefile.am @@ -10,7 +10,8 @@ libqsenet_la_SOURCES = \ http.c \ htre.c \ htrd.c \ - httpd.c + httpd.c \ + httpd_task.c libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir) libqsenet_la_LIBADD = -lqsecmn diff --git a/qse/lib/net/Makefile.in b/qse/lib/net/Makefile.in index d212ec1e..1662895c 100644 --- a/qse/lib/net/Makefile.in +++ b/qse/lib/net/Makefile.in @@ -71,7 +71,8 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libqsenet_la_DEPENDENCIES = -am_libqsenet_la_OBJECTS = http.lo htre.lo htrd.lo httpd.lo +am_libqsenet_la_OBJECTS = http.lo htre.lo htrd.lo httpd.lo \ + httpd_task.lo libqsenet_la_OBJECTS = $(am_libqsenet_la_OBJECTS) libqsenet_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -242,7 +243,8 @@ libqsenet_la_SOURCES = \ http.c \ htre.c \ htrd.c \ - httpd.c + httpd.c \ + httpd_task.c libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir) libqsenet_la_LIBADD = -lqsecmn @@ -324,6 +326,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htre.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd_task.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/qse/lib/net/httpd.c b/qse/lib/net/httpd.c index fe112d14..08233565 100644 --- a/qse/lib/net/httpd.c +++ b/qse/lib/net/httpd.c @@ -21,11 +21,28 @@ #include "httpd.h" #include "../cmn/mem.h" #include +#include + +#include +#include +#include +#include +#include #if 0 #include #endif +#include + +typedef struct htrd_xtn_t htrd_xtn_t; + +struct htrd_xtn_t +{ + qse_size_t client_index; + qse_httpd_t* httpd; +}; + QSE_IMPLEMENT_COMMON_FUNCTIONS (httpd) #define DEFAULT_PORT 80 @@ -114,46 +131,25 @@ void qse_httpd_setcbs (qse_httpd_t* httpd, qse_httpd_cbs_t* cbs) httpd->cbs = cbs; } -static QSE_INLINE void* httpd_alloc (qse_httpd_t* httpd, qse_size_t n) +QSE_INLINE void* qse_httpd_allocmem (qse_httpd_t* httpd, qse_size_t size) { - void* ptr = QSE_MMGR_ALLOC (httpd->mmgr, n); - if (ptr == QSE_NULL) httpd->errnum = QSE_HTTPD_ENOMEM; + void* ptr = QSE_MMGR_ALLOC (httpd->mmgr, size); + if (ptr == QSE_NULL) httpd->errnum = QSE_HTTPD_ENOMEM; return ptr; } -static void httpd_free (qse_httpd_t* httpd, void* ptr) +QSE_INLINE void* qse_httpd_reallocmem (qse_httpd_t* httpd, void* ptr, qse_size_t size) +{ + void* nptr = QSE_MMGR_REALLOC (httpd->mmgr, ptr, size); + if (nptr == QSE_NULL) httpd->errnum = QSE_HTTPD_ENOMEM; + return nptr; +} + +QSE_INLINE void qse_httpd_freemem (qse_httpd_t* httpd, void* ptr) { QSE_MMGR_FREE (httpd->mmgr, ptr); } -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define MAX_SENDFILE_SIZE 4096 -//#define MAX_SENDFILE_SIZE 64 - -typedef struct htrd_xtn_t htrd_xtn_t; - -struct htrd_xtn_t -{ - qse_size_t client_index; - qse_httpd_t* httpd; -}; - static int enqueue_task_unlocked ( qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_httpd_task_t* task, qse_size_t xtnsize) @@ -167,12 +163,8 @@ static int enqueue_task_unlocked ( return -1; } */ - node = QSE_MMGR_ALLOC (httpd->mmgr, QSE_SIZEOF(*node) + xtnsize); - if (node == QSE_NULL) - { - httpd->errnum = QSE_HTTPD_ENOMEM; - return -1; - } + node = qse_httpd_allocmem (httpd, QSE_SIZEOF(*node) + xtnsize); + if (node == QSE_NULL) return -1; node->task = *task; @@ -183,7 +175,7 @@ static int enqueue_task_unlocked ( { if (httpd->errnum == QSE_HTTPD_ENOERR) httpd->errnum = QSE_HTTPD_ETASK; - QSE_MMGR_FREE (httpd->mmgr, node); + qse_httpd_freemem (httpd, node); return -1; } } @@ -237,7 +229,7 @@ static int dequeue_task_unlocked ( client->task.queue.count--; if (node->task.fini) node->task.fini (httpd, client, &node->task); - QSE_MMGR_FREE (httpd->mmgr, node); + qse_httpd_freemem (httpd, node); return 0; } @@ -633,7 +625,7 @@ static void fini_client_array (qse_httpd_t* httpd) for (fd = 0; fd < array->capa; fd++) delete_from_client_array (httpd, fd); - free (array->data); + qse_httpd_freemem (httpd, array->data); array->capa = 0; array->size = 0; array->data = QSE_NULL; @@ -651,7 +643,7 @@ static qse_httpd_client_t* insert_into_client_array (qse_httpd_t* httpd, int fd, qse_httpd_client_t* tmp; qse_size_t capa = ((fd + ALIGN) / ALIGN) * ALIGN; - tmp = realloc (array->data, capa * QSE_SIZEOF(*tmp)); + tmp = qse_httpd_reallocmem (httpd, array->data, capa * QSE_SIZEOF(*tmp)); if (tmp == QSE_NULL) return QSE_NULL; QSE_MEMSET (&tmp[array->capa], 0, @@ -1012,9 +1004,9 @@ oops: static void free_listener (qse_httpd_t* httpd, listener_t* l) { - if (l->host) QSE_MMGR_FREE (httpd->mmgr, l->host); + if (l->host) qse_httpd_freemem (httpd, l->host); if (l->handle >= 0) close (l->handle); - QSE_MMGR_FREE (httpd->mmgr, l); + qse_httpd_freemem (httpd, l); } static void free_listener_list (qse_httpd_t* httpd, listener_t* l) @@ -1042,7 +1034,7 @@ static listener_t* parse_listener_string ( /* skip spaces */ while (QSE_ISSPACE(*p)) p++; - ltmp = httpd_alloc (httpd, QSE_SIZEOF(*ltmp)); + ltmp = qse_httpd_allocmem (httpd, QSE_SIZEOF(*ltmp)); if (ltmp == QSE_NULL) goto oops; /* alloc set error number. so goto oops */ QSE_MEMSET (ltmp, 0, QSE_SIZEOF(*ltmp)); @@ -1112,7 +1104,7 @@ static listener_t* parse_listener_string ( x = inet_pton (ltmp->family, host, <mp->addr); #ifdef QSE_CHAR_IS_WCHAR - httpd_free (httpd, host); + qse_httpd_freemem (httpd, host); #endif if (x != 1) { @@ -1249,246 +1241,3 @@ int qse_httpd_entask ( return ret; } -/*------------------------------------------------------------------------*/ - -typedef struct task_sendtext_t task_sendtext_t; -struct task_sendtext_t -{ - const qse_mchar_t* ptr; - qse_size_t left; -}; - -static int httpd_init_sendtext ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - task_sendtext_t* xtn = qse_httpd_gettaskxtn (httpd, task); - - QSE_MEMCPY (xtn, task->ctx, QSE_SIZEOF(*xtn)); - QSE_MEMCPY (xtn + 1, xtn->ptr, xtn->left); - xtn->ptr = (qse_mchar_t*)(xtn + 1); - - task->ctx = xtn; - return 0; -} - -static int httpd_main_sendtext ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - ssize_t n; - size_t count; - task_sendtext_t* ctx = (task_sendtext_t*)task->ctx; - - count = MAX_SENDFILE_SIZE; - if (count >= ctx->left) count = ctx->left; - - n = send ( - client->fd, - ctx->ptr, - count, - 0 - ); - - if (n <= -1) return -1; - - ctx->left -= n; - if (ctx->left <= 0) return 0; - - ctx->ptr += n; - return 1; /* more work to do */ -} - -int qse_httpd_entasksendtext ( - qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_mchar_t* text) -{ - qse_httpd_task_t task; - task_sendtext_t data; - - QSE_MEMSET (&data, 0, QSE_SIZEOF(data)); - data.ptr = text; - data.left = qse_mbslen(text); - - QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); - task.init = httpd_init_sendtext; - task.main = httpd_main_sendtext; - task.ctx = &data; - - return qse_httpd_entask ( - httpd, client, &task, QSE_SIZEOF(data) + data.left); -} - -/*------------------------------------------------------------------------*/ - -/* TODO: send wide character string when QSE_CHAR_IS_WCHAR */ - -/*------------------------------------------------------------------------*/ - -typedef struct task_sendfmt_t task_sendfmt_t; -struct task_sendfmt_t -{ - qse_mchar_t* org; - const qse_mchar_t* ptr; - qse_size_t left; -}; - -static int httpd_init_sendfmt ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - task_sendfmt_t* xtn = qse_httpd_gettaskxtn (httpd, task); - - QSE_MEMCPY (xtn, task->ctx, QSE_SIZEOF(*xtn)); - task->ctx = xtn; - return 0; -} - -static void httpd_fini_sendfmt ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - task_sendfmt_t* ctx = (task_sendfmt_t*)task->ctx; - httpd_free (httpd, ctx->org); -} - -static int httpd_main_sendfmt ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - ssize_t n; - size_t count; - task_sendfmt_t* ctx = (task_sendfmt_t*)task->ctx; - - count = MAX_SENDFILE_SIZE; - if (count >= ctx->left) count = ctx->left; - - n = send ( - client->fd, - ctx->ptr, - count, - 0 - ); - - if (n <= -1) return -1; - - ctx->left -= n; - if (ctx->left <= 0) return 0; - - ctx->ptr += n; - return 1; /* more work to do */ -} - -int qse_httpd_entasksendfmt ( - qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_mchar_t* fmt, ...) -{ - qse_httpd_task_t task; - task_sendfmt_t data; - - va_list ap; - qse_mchar_t n[2]; - qse_mchar_t* buf; - int bytes_req, l; - - va_start (ap, fmt); -#if defined(_WIN32) && defined(_MSC_VER) - bytes_req = _vsnprintf (n, 1, fmt, ap); -#else - bytes_req = vsnprintf (n, 1, fmt, ap); -#endif - va_end (ap); - - if (bytes_req == -1) - { - qse_size_t capa = 256; - - buf = (qse_mchar_t*) httpd_alloc (httpd, (capa + 1) * QSE_SIZEOF(*buf)); - if (buf == QSE_NULL) return -1; - - /* an old vsnprintf behaves differently from C99 standard. - * thus, it returns -1 when it can't write all the input given. */ - for (;;) - { - va_start (ap, fmt); -#if defined(_WIN32) && defined(_MSC_VER) - l = _vsnprintf (buf, capa + 1, fmt, ap); -#else - l = vsnprintf (buf, capa + 1, fmt, ap); -#endif - va_end (ap); - - if (l == -1) - { - httpd_free (httpd, buf); - - capa = capa * 2; - buf = (qse_mchar_t*) httpd_alloc (httpd, (capa + 1) * QSE_SIZEOF(*buf)); - if (buf == QSE_NULL) return -1; - } - else break; - } - } - else - { - /* vsnprintf returns the number of characters that would - * have been written not including the terminating '\0' - * if the _data buffer were large enough */ - buf = (qse_mchar_t*) httpd_alloc (httpd, (bytes_req + 1) * QSE_SIZEOF(*buf)); - if (buf == QSE_NULL) return -1; - - va_start (ap, fmt); -#if defined(_WIN32) && defined(_MSC_VER) - l = _vsnprintf (buf, bytes_req + 1, fmt, ap); -#else - l = vsnprintf (buf, bytes_req + 1, fmt, ap); -#endif - va_end (ap); - - if (l != bytes_req) - { - /* something got wrong ... */ - httpd_free (httpd, buf); - - httpd->errnum = QSE_HTTPD_EINTERN; - return -1; - } - } - - QSE_MEMSET (&data, 0, QSE_SIZEOF(data)); - data.org = buf; - data.ptr = buf; - data.left = l; - - QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); - task.init = httpd_init_sendfmt; - task.fini = httpd_fini_sendfmt; - task.main = httpd_main_sendfmt; - task.ctx = &data; - - return qse_httpd_entask ( - httpd, client, &task, QSE_SIZEOF(data)); -} - -/* TODO: send wide character string when QSE_CHAR_IS_WCHAR */ - -/*------------------------------------------------------------------------*/ - -int qse_httpd_entasksendfile ( - qse_httpd_t* httpd, qse_httpd_client_t* client, int fd) -{ - /* TODO: */ - return -1; -} - -/*------------------------------------------------------------------------*/ - -static int task_main_disconnect ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - shutdown (client->fd, SHUT_RDWR); - return 0; -} - -int qse_httpd_entaskdisconnect (qse_httpd_t* httpd, qse_httpd_client_t* client) -{ - qse_httpd_task_t task; - - QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); - task.main = task_main_disconnect; - - return qse_httpd_entask (httpd, client, &task, 0); -} diff --git a/qse/lib/net/httpd_task.c b/qse/lib/net/httpd_task.c new file mode 100644 index 00000000..a4cc5d0e --- /dev/null +++ b/qse/lib/net/httpd_task.c @@ -0,0 +1,379 @@ +#include "httpd.h" +#include "../cmn/mem.h" +#include +#include + +#include +#include + +#ifdef HAVE_SYS_SENDFILE_H +#include +#endif + +#include +#include + +#define MAX_SENDFILE_SIZE 4096 + +/*------------------------------------------------------------------------*/ + +static int task_main_disconnect ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + shutdown (client->fd, SHUT_RDWR); + return 0; +} + +int qse_httpd_entaskdisconnect (qse_httpd_t* httpd, qse_httpd_client_t* client) +{ + qse_httpd_task_t task; + + QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); + task.main = task_main_disconnect; + + return qse_httpd_entask (httpd, client, &task, 0); +} + +/*------------------------------------------------------------------------*/ + +typedef struct task_sendtext_t task_sendtext_t; +struct task_sendtext_t +{ + const qse_mchar_t* ptr; + qse_size_t left; +}; + +static int httpd_init_sendtext ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + task_sendtext_t* xtn = qse_httpd_gettaskxtn (httpd, task); + + QSE_MEMCPY (xtn, task->ctx, QSE_SIZEOF(*xtn)); + QSE_MEMCPY (xtn + 1, xtn->ptr, xtn->left); + xtn->ptr = (qse_mchar_t*)(xtn + 1); + + task->ctx = xtn; + return 0; +} + +static int httpd_main_sendtext ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + ssize_t n; + size_t count; + task_sendtext_t* ctx = (task_sendtext_t*)task->ctx; + + count = MAX_SENDFILE_SIZE; + if (count >= ctx->left) count = ctx->left; + + n = send ( + client->fd, + ctx->ptr, + count, + 0 + ); + + if (n <= -1) return -1; + + ctx->left -= n; + if (ctx->left <= 0) return 0; + + ctx->ptr += n; + return 1; /* more work to do */ +} + +int qse_httpd_entasksendtext ( + qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_mchar_t* text) +{ + qse_httpd_task_t task; + task_sendtext_t data; + + QSE_MEMSET (&data, 0, QSE_SIZEOF(data)); + data.ptr = text; + data.left = qse_mbslen(text); + + QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); + task.init = httpd_init_sendtext; + task.main = httpd_main_sendtext; + task.ctx = &data; + + return qse_httpd_entask ( + httpd, client, &task, QSE_SIZEOF(data) + data.left); +} + +/*------------------------------------------------------------------------*/ + +/* TODO: send wide character string when QSE_CHAR_IS_WCHAR */ + +/*------------------------------------------------------------------------*/ + +typedef struct task_sendfmt_t task_sendfmt_t; +struct task_sendfmt_t +{ + qse_mchar_t* org; + const qse_mchar_t* ptr; + qse_size_t left; +}; + +static int httpd_init_sendfmt ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + task_sendfmt_t* xtn = qse_httpd_gettaskxtn (httpd, task); + + QSE_MEMCPY (xtn, task->ctx, QSE_SIZEOF(*xtn)); + task->ctx = xtn; + return 0; +} + +static void httpd_fini_sendfmt ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + task_sendfmt_t* ctx = (task_sendfmt_t*)task->ctx; + qse_httpd_freemem (httpd, ctx->org); +} + +static int httpd_main_sendfmt ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + ssize_t n; + size_t count; + task_sendfmt_t* ctx = (task_sendfmt_t*)task->ctx; + + count = MAX_SENDFILE_SIZE; + if (count >= ctx->left) count = ctx->left; + + n = send ( + client->fd, + ctx->ptr, + count, + 0 + ); + + if (n <= -1) return -1; + + ctx->left -= n; + if (ctx->left <= 0) return 0; + + ctx->ptr += n; + return 1; /* more work to do */ +} + +int qse_httpd_entasksendfmt ( + qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_mchar_t* fmt, ...) +{ + qse_httpd_task_t task; + task_sendfmt_t data; + + va_list ap; + qse_mchar_t n[2]; + qse_mchar_t* buf; + int bytes_req, l; + + va_start (ap, fmt); +#if defined(_WIN32) && defined(_MSC_VER) + bytes_req = _vsnprintf (n, 1, fmt, ap); +#else + bytes_req = vsnprintf (n, 1, fmt, ap); +#endif + va_end (ap); + + if (bytes_req == -1) + { + qse_size_t capa = 256; + + buf = (qse_mchar_t*) qse_httpd_allocmem (httpd, (capa + 1) * QSE_SIZEOF(*buf)); + if (buf == QSE_NULL) return -1; + + /* an old vsnprintf behaves differently from C99 standard. + * thus, it returns -1 when it can't write all the input given. */ + for (;;) + { + va_start (ap, fmt); +#if defined(_WIN32) && defined(_MSC_VER) + l = _vsnprintf (buf, capa + 1, fmt, ap); +#else + l = vsnprintf (buf, capa + 1, fmt, ap); +#endif + va_end (ap); + + if (l == -1) + { + qse_httpd_freemem (httpd, buf); + + capa = capa * 2; + buf = (qse_mchar_t*) qse_httpd_allocmem (httpd, (capa + 1) * QSE_SIZEOF(*buf)); + if (buf == QSE_NULL) return -1; + } + else break; + } + } + else + { + /* vsnprintf returns the number of characters that would + * have been written not including the terminating '\0' + * if the _data buffer were large enough */ + buf = (qse_mchar_t*) qse_httpd_allocmem (httpd, (bytes_req + 1) * QSE_SIZEOF(*buf)); + if (buf == QSE_NULL) return -1; + + va_start (ap, fmt); +#if defined(_WIN32) && defined(_MSC_VER) + l = _vsnprintf (buf, bytes_req + 1, fmt, ap); +#else + l = vsnprintf (buf, bytes_req + 1, fmt, ap); +#endif + va_end (ap); + + if (l != bytes_req) + { + /* something got wrong ... */ + qse_httpd_freemem (httpd, buf); + + httpd->errnum = QSE_HTTPD_EINTERN; + return -1; + } + } + + QSE_MEMSET (&data, 0, QSE_SIZEOF(data)); + data.org = buf; + data.ptr = buf; + data.left = l; + + QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); + task.init = httpd_init_sendfmt; + task.fini = httpd_fini_sendfmt; + task.main = httpd_main_sendfmt; + task.ctx = &data; + + return qse_httpd_entask ( + httpd, client, &task, QSE_SIZEOF(data)); +} + +/* TODO: send wide character string when QSE_CHAR_IS_WCHAR */ + +/*------------------------------------------------------------------------*/ + +typedef struct httpd_task_sendfile_t httpd_task_sendfile_t; +struct httpd_task_sendfile_t +{ + int fd; + qse_foff_t left; + qse_foff_t offset; +}; + +static int httpd_init_sendfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + httpd_task_sendfile_t* xtn = qse_httpd_gettaskxtn (httpd, task); + QSE_MEMCPY (xtn, task->ctx, QSE_SIZEOF(*xtn)); + task->ctx = xtn; + return 0; +} + +static void httpd_fini_sendfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + httpd_task_sendfile_t* ctx = (httpd_task_sendfile_t*)task->ctx; + close (ctx->fd); +} + +static int httpd_main_sendfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + ssize_t n; + size_t count; + httpd_task_sendfile_t* ctx = (httpd_task_sendfile_t*)task->ctx; + + count = MAX_SENDFILE_SIZE; + if (count >= ctx->left) count = ctx->left; + + n = sendfile ( + client->fd, + ctx->fd, + &ctx->offset, + count + ); + + if (n <= -1) return -1; + + ctx->left -= n; + if (ctx->left <= 0) return 0; + + return 1; /* more work to do */ +} + +int qse_httpd_entasksendfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, + int fd, qse_foff_t offset, qse_foff_t size) +{ + qse_httpd_task_t task; + httpd_task_sendfile_t data; + + QSE_MEMSET (&data, 0, QSE_SIZEOF(data)); + data.fd = fd; + data.offset = offset; + data.left = size; + + QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); + task.init = httpd_init_sendfile; + task.main = httpd_main_sendfile; + task.fini = httpd_fini_sendfile; + task.ctx = &data; + + return qse_httpd_entask (httpd, client, &task, QSE_SIZEOF(data)); +} + +/*------------------------------------------------------------------------*/ + +#if 0 +typedef struct httpd_task_cgi_t httpd_task_cgi_t; +struct httpd_task_cgi_t +{ + qse_pio_t* pio; +}; + +static int httpd_init_cgi ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + httpd_task_cgi_t* xtn = qse_httpd_gettaskxtn (httpd, task); + + QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn)); + xtn->pio = qse_pio_open (httpd->mmgr, task->ctx); + if (xtn->pio == QSE_NULL) + { + httpd->errnum = QSE_HTTPD_ECGI; + return -1; + } + + task->ctx = xtn; + return 0; +} + +static void httpd_fini_cgi ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + httpd_task_cgi_t* xtn = task->ctx; + qse_pio_close (xtn->pio); +} + +static void httpd_main_cgi ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ +/* TODO */ + return -1; +} + +int qse_httpd_entaskcgi ( + qse_httpd_t* httpd, qse_httpd_client_t* client, const qse_char_t* path) +{ + qse_httpd_task_t task; + httpd_task_cgi_t data; + + QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); + task.init = httpd_init_cgi; + task.main = httpd_main_cgi; + task.fini = httpd_fini_cgi; + task.ctx = path; + + return qse_httpd_entask (httpd, client, &task, QSE_SIZEOF(data)); +} +#endif diff --git a/qse/samples/net/http01.c b/qse/samples/net/http01.c index a869b761..d13b60ed 100644 --- a/qse/samples/net/http01.c +++ b/qse/samples/net/http01.c @@ -17,82 +17,6 @@ struct httpd_xtn_t const qse_httpd_cbs_t* orgcbs; }; -typedef struct httpd_task_sendfile_t httpd_task_sendfile_t; -struct httpd_task_sendfile_t -{ - int fd; - qse_foff_t left; - qse_foff_t offset; -}; - -typedef struct httpd_task_sendtext_t httpd_task_sendtext_t; -struct httpd_task_sendtext_t -{ - const qse_mchar_t* ptr; - qse_size_t left; -}; - -static int httpd_init_sendfile ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - httpd_task_sendfile_t* xtn = qse_httpd_gettaskxtn (httpd, task); - memcpy (xtn, task->ctx, QSE_SIZEOF(*xtn)); - task->ctx = xtn; - return 0; -} - -static void httpd_fini_sendfile ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - httpd_task_sendfile_t* ctx = (httpd_task_sendfile_t*)task->ctx; - close (ctx->fd); -} - -static int httpd_main_sendfile ( - qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) -{ - ssize_t n; - size_t count; - httpd_task_sendfile_t* ctx = (httpd_task_sendfile_t*)task->ctx; - - count = MAX_SENDFILE_SIZE; - if (count >= ctx->left) count = ctx->left; - - n = sendfile ( - /* TODO: client->fd, */ *(int*)client, - ctx->fd, - &ctx->offset, - count - ); - - if (n <= -1) return -1; - - ctx->left -= n; - if (ctx->left <= 0) return 0; - - return 1; /* more work to do */ -} - -static int entask_sendfile ( - qse_httpd_t* httpd, qse_httpd_client_t* client, int fd, qse_foff_t size) -{ - qse_httpd_task_t task; - httpd_task_sendfile_t data; - - memset (&data, 0, QSE_SIZEOF(data)); - data.fd = fd; - data.left = size; - - memset (&task, 0, QSE_SIZEOF(task)); - task.init = httpd_init_sendfile; - task.main = httpd_main_sendfile; - task.fini = httpd_fini_sendfile; - task.ctx = &data; - - return qse_httpd_entask (httpd, client, &task, QSE_SIZEOF(data)); -} - - static qse_htb_walk_t walk (qse_htb_t* htb, qse_htb_pair_t* pair, void* ctx) { qse_printf (QSE_T("HEADER OK %d[%S] %d[%S]\n"), (int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair), (int)QSE_HTB_VLEN(pair), QSE_HTB_VPTR(pair)); @@ -177,7 +101,7 @@ snprintf (text, sizeof(text), ); if (n <= -1) return -1; - if (entask_sendfile (httpd, client, fd, st.st_size) <= -1) return -1; + if (qse_httpd_entasksendfile (httpd, client, fd, 0, st.st_size) <= -1) return -1; } }