diff --git a/qse/configure b/qse/configure index 698058f1..ba7ac523 100755 --- a/qse/configure +++ b/qse/configure @@ -19922,6 +19922,42 @@ cat >>confdefs.h <<_ACEOF _ACEOF + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of struct sockaddr_un" >&5 +$as_echo_n "checking size of struct sockaddr_un... " >&6; } +if ${ac_cv_sizeof_struct_sockaddr_un+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_un))" "ac_cv_sizeof_struct_sockaddr_un" " + #include + #include +"; then : + +else + if test "$ac_cv_type_struct_sockaddr_un" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (struct sockaddr_un) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_struct_sockaddr_un=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_struct_sockaddr_un" >&5 +$as_echo "$ac_cv_sizeof_struct_sockaddr_un" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_STRUCT_SOCKADDR_UN $ac_cv_sizeof_struct_sockaddr_un +_ACEOF + + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -20074,6 +20110,42 @@ cat >>confdefs.h <<_ACEOF _ACEOF + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of struct sockaddr_un" >&5 +$as_echo_n "checking size of struct sockaddr_un... " >&6; } +if ${ac_cv_sizeof_struct_sockaddr_un+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (struct sockaddr_un))" "ac_cv_sizeof_struct_sockaddr_un" " + #include + #include +"; then : + +else + if test "$ac_cv_type_struct_sockaddr_un" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (struct sockaddr_un) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_struct_sockaddr_un=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_struct_sockaddr_un" >&5 +$as_echo "$ac_cv_sizeof_struct_sockaddr_un" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_STRUCT_SOCKADDR_UN $ac_cv_sizeof_struct_sockaddr_un +_ACEOF + + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -20468,6 +20540,11 @@ cat >>confdefs.h <<_ACEOF _ACEOF +cat >>confdefs.h <<_ACEOF +#define QSE_SIZEOF_STRUCT_SOCKADDR_UN ${ac_cv_sizeof_struct_sockaddr_un} +_ACEOF + + cat >>confdefs.h <<_ACEOF #define QSE_SIZEOF_SOCKLEN_T ${ac_cv_sizeof_socklen_t} _ACEOF diff --git a/qse/configure.ac b/qse/configure.ac index a477da3d..73aa9402 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -375,6 +375,9 @@ then AC_CHECK_SIZEOF(struct sockaddr_in6,,[ #include #include ]) + AC_CHECK_SIZEOF(struct sockaddr_un,,[ + #include + #include ]) AC_CHECK_SIZEOF(socklen_t,, [ #include #include ]) @@ -394,6 +397,9 @@ else AC_CHECK_SIZEOF(struct sockaddr_in6,,[ #include #include ]) + AC_CHECK_SIZEOF(struct sockaddr_un,,[ + #include + #include ]) AC_CHECK_SIZEOF(socklen_t,, [ #include #include ]) @@ -535,6 +541,7 @@ AC_DEFINE_UNQUOTED(QSE_MBLEN_MAX, ${ax_cv_numvalof_MB_LEN_MAX}, [MB_LEN_MAX]) AC_DEFINE_UNQUOTED(QSE_SIZEOF_STRUCT_SOCKADDR_IN, ${ac_cv_sizeof_struct_sockaddr_in}, [sizeof(struct sockaddr_in)]) AC_DEFINE_UNQUOTED(QSE_SIZEOF_STRUCT_SOCKADDR_IN6, ${ac_cv_sizeof_struct_sockaddr_in6}, [sizeof(struct sockaddr_in6)]) +AC_DEFINE_UNQUOTED(QSE_SIZEOF_STRUCT_SOCKADDR_UN, ${ac_cv_sizeof_struct_sockaddr_un}, [sizeof(struct sockaddr_un)]) AC_DEFINE_UNQUOTED(QSE_SIZEOF_SOCKLEN_T, ${ac_cv_sizeof_socklen_t}, [sizeof(socklen_t)]) diff --git a/qse/include/qse/cmn/mbwc.h b/qse/include/qse/cmn/mbwc.h index 52e03f10..00519f04 100644 --- a/qse/include/qse/cmn/mbwc.h +++ b/qse/include/qse/cmn/mbwc.h @@ -64,7 +64,7 @@ extern "C" { #endif /** - * The qse_findcmgrbyid() function returns a built-in cmgr for a given @a id. + * The qse_findcmgrbyid() function returns a built-in cmgr for a given \a id. */ QSE_EXPORT qse_cmgr_t* qse_findcmgrbyid ( qse_cmgr_id_t id @@ -72,8 +72,8 @@ QSE_EXPORT qse_cmgr_t* qse_findcmgrbyid ( /** * The qse_getfindcmgr() function find a built-in cmgr matching a given - * @a name and returns it. It returns #QSE_NULL if no match is found. - * The @a name can be one of "slmb", "utf8", "mb8", "cp949", "cp950", and an + * \a name and returns it. It returns #QSE_NULL if no match is found. + * The \a name can be one of "slmb", "utf8", "mb8", "cp949", "cp950", and an * empty string. Calling this function with an empty string is the same * as calling qse_getdflcmgr(). */ @@ -102,7 +102,7 @@ QSE_EXPORT void qse_setdflcmgr ( /** * The qse_setdflcmgrbyid() function finds a built-in - * cmgr for the @a id and sets it as a default cmgr. + * cmgr for the \a id and sets it as a default cmgr. */ QSE_EXPORT void qse_setdflcmgrbyid ( qse_cmgr_id_t id @@ -254,9 +254,9 @@ QSE_EXPORT qse_mchar_t* qse_wcsnatombsdupwithcmgr ( * The qse_mbstowcs() function converts a null-terminated multibyte string to * a wide character string. * - * It never returns -2 if @a wcs is #QSE_NULL. + * It never returns -2 if \a wcs is #QSE_NULL. * - * @code + * \code * const qse_mchar_t* mbs = QSE_MT("a multibyte string"); * qse_wchar_t wcs[100]; * qse_size_t wcslen = QSE_COUNTOF(buf), n; @@ -264,12 +264,12 @@ QSE_EXPORT qse_mchar_t* qse_wcsnatombsdupwithcmgr ( * int n; * n = qse_mbstowcs (mbs, &mbslen, wcs, &wcslen); * if (n <= -1) { invalid/incomplenete sequence or buffer to small } - * @endcode + * \endcode * - * @return 0 on success. - * -1 if @a mbs contains an illegal character. + * \return 0 on success. + * -1 if \a mbs contains an illegal character. * -2 if the wide-character string buffer is too small. - * -3 if @a mbs is not a complete sequence. + * -3 if \a mbs is not a complete sequence. */ QSE_EXPORT int qse_mbstowcs ( const qse_mchar_t* mbs, /**< [in] multibyte string to convert */ @@ -280,6 +280,11 @@ QSE_EXPORT int qse_mbstowcs ( number of characters in the buffer for out */ ); +/** + * The qse_mbstowcsall() functions behaves like qse_mbstowcs() except + * it converts an invalid sequence or an incomplete sequence to a question + * mark. it never returns -1 or -3. + */ QSE_EXPORT int qse_mbstowcsall ( const qse_mchar_t* mbs, /**< [in] multibyte string to convert */ qse_size_t* mbslen, /**< [out] number of multibyte characters @@ -293,12 +298,12 @@ QSE_EXPORT int qse_mbstowcsall ( * The qse_mbsntowcsn() function converts a multibyte string to a * wide character string. * - * It never returns -2 if @a wcs is #QSE_NULL. + * It never returns -2 if \a wcs is #QSE_NULL. * - * @return 0 on success. - * -1 if @a mbs contains an illegal character. + * \return 0 on success. + * -1 if \a mbs contains an illegal character. * -2 if the wide-character string buffer is too small. - * -3 if @a mbs is not a complete sequence. + * -3 if \a mbs is not a complete sequence. */ QSE_EXPORT int qse_mbsntowcsn ( const qse_mchar_t* mbs, @@ -316,7 +321,7 @@ QSE_EXPORT int qse_mbsntowcsnall ( /** * The qse_mbsntowcsnupto() function is the same as qse_mbsntowcsn() - * except that it stops once it has processed the @a stopper character. + * except that it stops once it has processed the \a stopper character. */ QSE_EXPORT int qse_mbsntowcsnupto ( const qse_mchar_t* mbs, @@ -366,22 +371,22 @@ QSE_EXPORT qse_wchar_t* qse_mbsatowcsalldup ( /** * The qse_wcstombs() function converts a null-terminated wide character - * string @a wcs to a multibyte string and writes it into the buffer pointed to - * by @a mbs, but not more than @a mbslen bytes including the terminating null. + * string \a wcs to a multibyte string and writes it into the buffer pointed to + * by \a mbs, but not more than \a mbslen bytes including the terminating null. * - * Upon return, @a mbslen is modifed to the actual bytes written to @a mbs - * excluding the terminating null; @a wcslen is modifed to the number of + * Upon return, \a mbslen is modified to the actual bytes written to \a mbs + * excluding the terminating null; \a wcslen is modified to the number of * wide characters converted. * - * You may pass #QSE_NULL for @a mbs to dry-run conversion or to get the + * You may pass #QSE_NULL for \a mbs to dry-run conversion or to get the * required buffer size for conversion. -2 is never returned in this case. * - * @return + * \return * - 0 on full conversion, * - -1 on no or partial conversion for an illegal character encountered, * - -2 on no or partial conversion for a small buffer. * - * @code + * \code * const qse_wchar_t* wcs = QSE_T("hello"); * qse_mchar_t mbs[10]; * qse_size_t wcslen; @@ -391,7 +396,7 @@ QSE_EXPORT qse_wchar_t* qse_mbsatowcsalldup ( * { * // conversion error * } - * @endcode + * \endcode */ QSE_EXPORT int qse_wcstombs ( const qse_wchar_t* wcs, /**< [in] wide-character string to convert*/ @@ -402,27 +407,27 @@ QSE_EXPORT int qse_wcstombs ( ); /** - * The qse_wcsntombsn() function converts the first @a wcslen characters from - * a wide character string @a wcs to a multibyte string and writes it to a - * buffer @a mbs not more than @a mbslen bytes. + * The qse_wcsntombsn() function converts the first \a wcslen characters from + * a wide character string \a wcs to a multibyte string and writes it to a + * buffer \a mbs not more than \a mbslen bytes. * - * Upon return, it modifies @a mbslen to the actual bytes written to @a mbs - * and @a wcslen to the number of wide characters converted. + * Upon return, it modifies \a mbslen to the actual bytes written to \a mbs + * and \a wcslen to the number of wide characters converted. * - * You may pass #QSE_NULL for @a mbs to dry-run conversion or to get the + * You may pass #QSE_NULL for \a mbs to dry-run conversion or to get the * required buffer size for conversion. * * 0 is returned on full conversion. The number of wide characters handled - * is stored into @a wcslen and the number of produced multibyte characters - * is stored into @a mbslen. -1 is returned if an illegal character is + * is stored into \a wcslen and the number of produced multibyte characters + * is stored into \a mbslen. -1 is returned if an illegal character is * encounterd during conversion and -2 is returned if the buffer is not * large enough to perform full conversion. however, the number of wide - * characters handled so far stored into @a wcslen and the number of produced - * multibyte characters so far stored into @a mbslen are still valid. - * If @a mbs is #QSE_NULL, -2 is never returned. + * characters handled so far stored into \a wcslen and the number of produced + * multibyte characters so far stored into \a mbslen are still valid. + * If \a mbs is #QSE_NULL, -2 is never returned. * - * @return 0 on success, - * -1 if @a wcs contains an illegal character, + * \return 0 on success, + * -1 if \a wcs contains an illegal character, * -2 if the multibyte string buffer is too small. */ QSE_EXPORT int qse_wcsntombsn ( diff --git a/qse/include/qse/cmn/nwad.h b/qse/include/qse/cmn/nwad.h index e2bd981c..5c99bf86 100644 --- a/qse/include/qse/cmn/nwad.h +++ b/qse/include/qse/cmn/nwad.h @@ -57,7 +57,11 @@ struct qse_nwad_t struct { /* no port number. path is the address */ - qse_uint8_t path[64]; + + /* note: 128 is chosen based on common path length in existing + * systems. most systems have different sizes. some + * trailers may get truncated, when itconverted to skad. */ + qse_char_t path[128]; } local; } u; }; @@ -82,17 +86,27 @@ typedef struct qse_skad_t qse_skad_t; struct qse_skad_t { - /* TODO: is this large enough?? */ -#if (QSE_SIZEOF_STRUCT_SOCKADDR_IN > 0) && \ - (QSE_SIZEOF_STRUCT_SOCKADDR_IN >= QSE_SIZEOF_STRUCT_SOCKADDR_IN6) - qse_uint8_t data[QSE_SIZEOF_STRUCT_SOCKADDR_IN]; -#elif (QSE_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) && \ - (QSE_SIZEOF_STRUCT_SOCKADDR_IN6 >= QSE_SIZEOF_STRUCT_SOCKADDR_IN) - qse_uint8_t data[QSE_SIZEOF_STRUCT_SOCKADDR_IN6]; -#else - /* no sockaddr_xxx is available */ - qse_uint8_t data[QSE_SIZEOF(qse_nwad_t)]; +#define QSE_SKAD_DATA_SIZE 0 + +#if (QSE_SIZEOF_STRUCT_SOCKADDR_IN > QSE_SKAD_DATA_SIZE) +# undef QSE_SKAD_DATA_SIZE +# define QSE_SKAD_DATA_SIZE QSE_SIZEOF_STRUCT_SOCKADDR_IN #endif +#if (QSE_SIZEOF_STRUCT_SOCKADDR_IN6 > QSE_SKAD_DATA_SIZE) +# undef QSE_SKAD_DATA_SIZE +# define QSE_SKAD_DATA_SIZE QSE_SIZEOF_STRUCT_SOCKADDR_IN6 +#endif +#if (QSE_SIZEOF_STRUCT_SOCKADDR_UN > QSE_SKAD_DATA_SIZE) +# undef QSE_SKAD_DATA_SIZE +# define QSE_SKAD_DATA_SIZE QSE_SIZEOF_STRUCT_SOCKADDR_UN +#endif + +#if (QSE_SKAD_DATA_SIZE == 0) +# undef QSE_SKAD_DATA_SIZE +# define QSE_SKAD_DATA_SIZE QSE_SIZEOF(qse_nwad_t) +#endif + /* TODO: is this large enough?? */ + qse_uint8_t data[QSE_SKAD_DATA_SIZE]; }; #ifdef __cplusplus diff --git a/qse/include/qse/config.h.in b/qse/include/qse/config.h.in index 33e0df0d..b2ff9178 100644 --- a/qse/include/qse/config.h.in +++ b/qse/include/qse/config.h.in @@ -871,6 +871,9 @@ /* sizeof(struct sockaddr_in6) */ #undef QSE_SIZEOF_STRUCT_SOCKADDR_IN6 +/* sizeof(struct sockaddr_un) */ +#undef QSE_SIZEOF_STRUCT_SOCKADDR_UN + /* sizeof(void*) */ #undef QSE_SIZEOF_VOID_P @@ -952,6 +955,9 @@ /* The size of `struct sockaddr_in6', as computed by sizeof. */ #undef SIZEOF_STRUCT_SOCKADDR_IN6 +/* The size of `struct sockaddr_un', as computed by sizeof. */ +#undef SIZEOF_STRUCT_SOCKADDR_UN + /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P diff --git a/qse/lib/cmn/nwad-skad.c b/qse/lib/cmn/nwad-skad.c index 0a0d412b..d58572f6 100644 --- a/qse/lib/cmn/nwad-skad.c +++ b/qse/lib/cmn/nwad-skad.c @@ -22,16 +22,16 @@ #include "mem.h" #if defined(_WIN32) -# include -# include /* sockaddr_in6 */ -# include +# include +# include /* sockaddr_in6 */ +# include # if (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) /* the header files shipped with watcom 11 doesn't contain * proper inet6 support. note using the compiler version * in the contidional isn't that good idea since you * can use newer header files with this old compiler. * never mind it for the time being. - */ + */ # undef AF_INET6 # endif #elif defined(__OS2__) @@ -47,21 +47,30 @@ #else # include # include +# include -# if defined(QSE_SIZEOF_STRUCT_SOCKADDR_IN6) && (QSE_SIZEOF_STRUCT_SOCKADDR_IN6 == 0) +# if defined(QSE_SIZEOF_STRUCT_SOCKADDR_IN6) && (QSE_SIZEOF_STRUCT_SOCKADDR_IN6 <= 0) # undef AF_INET6 # endif + +# if defined(QSE_SIZEOF_STRUCT_SOCKADDR_UN) && (QSE_SIZEOF_STRUCT_SOCKADDR_UN <= 0) +# undef AF_UNIX +# endif + #endif union sockaddr_t { -#if defined(AF_INET) || defined(AF_INET6) +#if defined(AF_INET) || defined(AF_INET6) || defined(AF_UNIX) #if defined(AF_INET) struct sockaddr_in in4; #endif #if defined(AF_INET6) struct sockaddr_in6 in6; #endif + #if defined(AF_UNIX) + struct sockaddr_un un; + #endif #else int dummy; #endif @@ -73,6 +82,8 @@ typedef union sockaddr_t sockaddr_t; # define FAMILY(x) (((struct sockaddr_in*)(x))->sin_family) #elif defined(AF_INET6) # define FAMILY(x) (((struct sockaddr_in6*)(x))->sin6_family) +#elif defined(AF_UNIX) +# define FAMILY(x) (((struct sockaddr_un*)(x))->sun_family) #else # define FAMILY(x) (-1) #endif @@ -116,6 +127,28 @@ static QSE_INLINE int skad_to_nwad (const sockaddr_t* skad, qse_nwad_t* nwad) } #endif +#if defined(AF_UNIX) + case AF_UNIX: + { + struct sockaddr_un* un; + un = (struct sockaddr_un*)skad; + addrsize = QSE_SIZEOF(*un); + + QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad)); + nwad->type = QSE_NWAD_LOCAL; + #if defined(QSE_CHAR_IS_MCHAR) + qse_mbsxcpy (nwad->u.local.path, QSE_COUNTOF(nwad->u.local.path), un->sun_path); + #else + { + qse_size_t wcslen, mbslen; + mbslen = QSE_COUNTOF(nwad->u.local.path); + qse_wcstombs (un->sun_path, &wcslen, nwad->u.local.path, &mbslen); + /* don't care about conversion errors */ + } + #endif + break; + } +#endif default: break; } @@ -163,6 +196,33 @@ static QSE_INLINE int nwad_to_skad (const qse_nwad_t* nwad, sockaddr_t* skad) #endif break; } + + + case QSE_NWAD_LOCAL: + { +#if defined(AF_UNIX) + struct sockaddr_un* un; + + un = (struct sockaddr_un*)skad; + addrsize = QSE_SIZEOF(*un); + QSE_MEMSET (un, 0, addrsize); + + un->sun_family = AF_UNIX; + #if defined(QSE_CHAR_IS_MCHAR) + qse_mbsxcpy (un->sun_path, QSE_COUNTOF(un->sun_path), nwad->u.local.path); + #else + { + qse_size_t wcslen, mbslen; + mbslen = QSE_COUNTOF(un->sun_path); + qse_wcstombs (nwad->u.local.path, &wcslen, un->sun_path, &mbslen); + /* don't care about conversion errors */ + } + + #endif +#endif + break; + } + } return addrsize; diff --git a/qse/lib/cmn/nwad.c b/qse/lib/cmn/nwad.c index e565f5d4..82ae5109 100644 --- a/qse/lib/cmn/nwad.c +++ b/qse/lib/cmn/nwad.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "mem.h" int qse_nwadequal (const qse_nwad_t* x, const qse_nwad_t* y) @@ -40,6 +41,9 @@ int qse_nwadequal (const qse_nwad_t* x, const qse_nwad_t* y) x->u.in6.scope == y->u.in6.scope && QSE_MEMCMP (&x->u.in6.addr, &y->u.in6.addr, QSE_SIZEOF(x->u.in6.addr)) == 0)? 1: 0; + case QSE_NWAD_LOCAL: + return qse_strcmp (x->u.local.path, y->u.local.path) == 0; + default: /* can't compare */ return -1; @@ -63,6 +67,10 @@ void qse_setnwadport (qse_nwad_t* nwad, qse_uint16_t port) case QSE_NWAD_IN6: nwad->u.in6.port = port; break; + + case QSE_NWAD_LOCAL: + /* no port for QSE_NWAD_LOCAL */ + break; } } @@ -76,6 +84,7 @@ qse_uint16_t qse_getnwadport (qse_nwad_t* nwad) case QSE_NWAD_IN6: return nwad->u.in6.port; + case QSE_NWAD_LOCAL: default: return 0; } @@ -100,6 +109,22 @@ int qse_mbsntonwad (const qse_mchar_t* str, qse_size_t len, qse_nwad_t* nwad) if (p >= end) return -1; + if (*p == QSE_MT('/')) + { + /* support the absolute path only */ + #if defined(QSE_CHAR_IS_MCHAR) + qse_mbsxncpy (tmpad.u.local.path, QSE_COUNTOF(tmpad.u.local.path), str, len); + #else + qse_size_t mbslen = len; + qse_size_t wcslen = QSE_COUNTOF(tmpad.u.local.path) - 1; + if (qse_mbsntowcsn (str, &mbslen, tmpad.u.local.path, &wcslen) <= -1) return -1; + tmpad.u.local.path[wcslen] = QSE_WT('\0'); + #endif + + tmpad.type = QSE_NWAD_LOCAL; + goto done; + } + if (*p == QSE_MT('[')) { /* IPv6 address */ @@ -266,6 +291,23 @@ int qse_wcsntonwad (const qse_wchar_t* str, qse_size_t len, qse_nwad_t* nwad) if (p >= end) return -1; + if (*p == QSE_WT('/')) + { + /* support the absolute path only */ + #if defined(QSE_CHAR_IS_MCHAR) + qse_size_t wcslen = len; + qse_size_t mbslen = QSE_COUNTOF(tmpad.u.local.path) - 1; + if (qse_wcsntombsn (str, &wcslen, tmpad.u.local.path, &mbslen) <= -1) return -1; + tmpad.u.local.path[mbslen] = QSE_MT('\0'); + #else + qse_wcsxncpy (tmpad.u.local.path, QSE_COUNTOF(tmpad.u.local.path), str, len); + #endif + + tmpad.type = QSE_NWAD_LOCAL; + qse_wcsxncpy (tmpad.u.local.path, QSE_COUNTOF(tmpad.u.local.path), str, len); + goto done; + } + if (*p == QSE_WT('[')) { /* IPv6 address */ @@ -497,7 +539,7 @@ qse_size_t qse_nwadtombs ( if (flags & QSE_NWADTOMBS_ADDR) { if (xlen + 1 >= len) goto done; - buf[xlen++] = QSE_MT(']'); + buf[xlen++] = QSE_MT(']'); if (xlen + 1 >= len) goto done; buf[xlen++] = QSE_MT(':'); @@ -513,6 +555,20 @@ qse_size_t qse_nwadtombs ( break; + case QSE_NWAD_LOCAL: + if (flags & QSE_NWADTOMBS_ADDR) + { + #if defined(QSE_CHAR_IS_MCHAR) + xlen = qse_mbsxcpy (buf, len, nwad->u.local.path) + #else + qse_size_t wcslen, mbslen = len; + qse_wcstombs (nwad->u.local.path, &wcslen, buf, &mbslen); + /* i don't care about conversion errors */ + xlen = mbslen; + #endif + } + + break; } done: @@ -620,6 +676,18 @@ qse_size_t qse_nwadtowcs ( break; + case QSE_NWAD_LOCAL: + if (flags & QSE_NWADTOMBS_ADDR) + { + #if defined(QSE_CHAR_IS_MCHAR) + qse_size_t wcslen = len, mbslen; + qse_mbstowcs (nwad->u.local.path, &mbslen, buf, &wcslen); + /* i don't care about conversion errors */ + xlen = wcslen; + #else + xlen = qse_wcsxcpy (buf, len, nwad->u.local.path); + #endif + } } done: diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index 5147dc4b..9c577ebd 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -107,6 +107,9 @@ # include #endif +#if defined(__linux) && !defined(SO_REUSEPORT) +# define SO_REUSEPORT 15 +#endif #define HANDLE_TO_FIO(x) ((qse_fio_t*)(x)) #define FIO_TO_HANDLE(x) ((qse_httpd_hnd_t)(x)) @@ -836,11 +839,18 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) flag = 1; setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, QSE_SIZEOF(flag)); #endif - + #if defined(SO_REUSEPORT) flag = 1; - setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, (void*)&flag, QSE_SIZEOF(flag)); + if (setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, &flag, QSE_SIZEOF(flag)) <= -1) + { + /* TODO: logging. warning only */ + /* this is not a hard failure */ +qse_printf (QSE_STDERR, QSE_T("Failed to enable SO_REUSEPORT\n")); + } #endif + + /* TODO: linux. use capset() to set required capabilities just in case */ #if defined(IP_TRANSPARENT) @@ -876,6 +886,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag)); #endif + if (server->dope.flags & QSE_HTTPD_SERVER_BINDTONWIF) { #if defined(SO_BINDTODEVICE)