diff options
author | Steve Bennett <steveb@workware.net.au> | 2010-10-12 20:29:05 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2010-10-15 11:02:57 +1000 |
commit | 92083f41130290f9e2cf1eedc5750a348fd11809 (patch) | |
tree | 7f848baf4a549979cf495c6347a6d5385e008a45 | |
parent | 0e2703df31a67c57e23954943f7980c5cc309755 (diff) | |
download | jimtcl-92083f41130290f9e2cf1eedc5750a348fd11809.zip jimtcl-92083f41130290f9e2cf1eedc5750a348fd11809.tar.gz jimtcl-92083f41130290f9e2cf1eedc5750a348fd11809.tar.bz2 |
Portability fixes
Especially for eCos, mingw32 and cygwin
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | Makefile.in | 2 | ||||
-rwxr-xr-x | configure | 237 | ||||
-rwxr-xr-x | configure.ac | 45 | ||||
-rw-r--r-- | jim-aio.c | 126 | ||||
-rw-r--r-- | jim-eventloop.c | 21 | ||||
-rw-r--r-- | jim-file.c | 8 | ||||
-rw-r--r-- | jim-interactive.c | 1 | ||||
-rw-r--r-- | jim-signal.c | 5 | ||||
-rw-r--r-- | jim-win32compat.c | 26 | ||||
-rw-r--r-- | jim.c | 2 | ||||
-rw-r--r-- | jim.h | 3 | ||||
-rw-r--r-- | jimautoconf.h.in | 30 | ||||
-rw-r--r-- | tclcompat.tcl | 2 | ||||
-rw-r--r-- | tests/event.test | 6 |
14 files changed, 454 insertions, 60 deletions
diff --git a/Makefile.in b/Makefile.in index 8425174..6824ae3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -19,7 +19,7 @@ EXTENSIONS := @JIM_EXTENSIONS@ # Set an initial, default library and auto_path CPPFLAGS += -DTCL_LIBRARY=\"/lib/jim\" -CPPFLAGS += -DJIM_TCL_COMPAT -DJIM_REFERENCES +CPPFLAGS += -DJIM_TCL_COMPAT -DJIM_REFERENCES -D_GNU_SOURCE CPPFLAGS += -Wall -g $(OPTIM) -I@SRCDIR@ -I. @EXTRA_CFLAGS@ VPATH := @SRCDIR@ @@ -606,6 +606,7 @@ LIBOBJS SRCDIR EXTRA_CFLAGS JIM_EXTENSIONS +LIBSOCK LIBDL JIM_LIBTYPE CROSS @@ -1638,6 +1639,97 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_header_compile +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------- ## +## Report this to steveb@workware.net.au ## +## ------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -3538,6 +3630,19 @@ fi JIM_LIBTYPE=$JIM_LIBTYPE +for ac_header in sys/un.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_un_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_UN_H 1 +_ACEOF + +fi + +done + + for ac_func in ualarm sysinfo lstat fork vfork do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -3574,7 +3679,7 @@ _ACEOF fi done -for ac_func in syslog opendir +for ac_func in syslog opendir readlink sleep usleep pipe inet_ntop getaddrinfo do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -3649,6 +3754,134 @@ $as_echo "#define HAVE_DLOPEN 1" >>confdefs.h fi +ac_fn_c_check_header_mongrel "$LINENO" "winsock.h" "ac_cv_header_winsock_h" "$ac_includes_default" +if test "x$ac_cv_header_winsock_h" = xyes; then : + LIBSOCK=-lwsock32 + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 +$as_echo_n "checking for library containing socket... " >&6; } +if ${ac_cv_search_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_socket=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_socket+:} false; then : + break +fi +done +if ${ac_cv_search_socket+:} false; then : + +else + ac_cv_search_socket=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 +$as_echo "$ac_cv_search_socket" >&6; } +ac_res=$ac_cv_search_socket +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + LIBSOCK=${ac_cv_search_socket%none required} + + +fi + + +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for environ in unistd.h" >&5 +$as_echo_n "checking for environ in unistd.h... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include <unistd.h> +int main(int argc, char **argv) { char **ep = environ; } + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + has_environ=yes + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + # Possibility #2: can environ be found in an available library? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extern environ" >&5 +$as_echo_n "checking for extern environ... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +extern char **environ; +int main(int argc, char **argv) { char **ep = environ; } + + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +$as_echo "#define NEED_ENVIRON_EXTERN 1" >>confdefs.h + + has_environ=yes + +else + + has_environ=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${has_environ}" >&5 +$as_echo "${has_environ}" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test "${has_environ}" != "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 $? "Could find 'environ' in unistd.h or available libraries. +See \`config.log' for more details" "$LINENO" 5; } +fi + # Now that we know what the platform supports: # For all known extensions: @@ -3662,7 +3895,7 @@ needs_syslog="ac_cv_func_syslog" needs_exec="ac_cv_func_vfork" needs_posix="ac_cv_func_waitpid" needs_load="ac_cv_search_dlopen" -needs_signal="ac_cv_func_sigaction" +needs_signal="ac_cv_func_sigaction ac_cv_func_vfork" needs_readdir="ac_cv_func_opendir" ext_add=$(echo $with_jim_ext | tr ' ' '\n') diff --git a/configure.ac b/configure.ac index b604538..e728be7 100755 --- a/configure.ac +++ b/configure.ac @@ -117,16 +117,57 @@ AC_ARG_WITH(jim-shared, ) AC_SUBST(JIM_LIBTYPE,$JIM_LIBTYPE) +AC_CHECK_HEADERS([sys/un.h]) + AC_CHECK_FUNCS([ualarm sysinfo lstat fork vfork]) AC_CHECK_FUNCS([backtrace geteuid mkstemp realpath strptime]) AC_CHECK_FUNCS([regcomp waitpid sigaction sys_signame sys_siglist]) -AC_CHECK_FUNCS([syslog opendir]) +AC_CHECK_FUNCS([syslog opendir readlink sleep usleep pipe inet_ntop getaddrinfo]) AC_SEARCH_LIBS(dlopen, dl, AC_SUBST(LIBDL,${ac_cv_search_dlopen%none required}) AC_DEFINE([HAVE_DLOPEN],[1],[Have the dlopen function]) ) +dnl AC_SEARCH_LIBS doesn't work for mingw, so check for winsock.h instead +AC_CHECK_HEADER(winsock.h,[AC_SUBST(LIBSOCK,-lwsock32)], + AC_SEARCH_LIBS(socket, socket, + AC_SUBST(LIBSOCK,${ac_cv_search_socket%none required}) + ) +) + +dnl Look for environ alternatives. Possibility #1: is environ in unistd.h? +AC_MSG_CHECKING([for environ in unistd.h]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#define _GNU_SOURCE +#include <unistd.h> +int main(int argc, char **argv) { char **ep = environ; } + ]])], [ + AC_MSG_RESULT([yes]) + has_environ=yes + ], [ + AC_MSG_RESULT([no]) + + # Possibility #2: can environ be found in an available library? + AC_MSG_CHECKING([for extern environ]) + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ +extern char **environ; +int main(int argc, char **argv) { char **ep = environ; } + ]]) + ], [ + AC_DEFINE(NEED_ENVIRON_EXTERN, [1], [Must declare 'environ' to use it.]) + has_environ=yes + ], [ + has_environ=no + ]) + AC_MSG_RESULT([${has_environ}]) +]) + +if test "${has_environ}" != "yes" ; then + AC_MSG_FAILURE([Could find 'environ' in unistd.h or available libraries.]) +fi + # Now that we know what the platform supports: # For all known extensions: @@ -140,7 +181,7 @@ needs_syslog="ac_cv_func_syslog" needs_exec="ac_cv_func_vfork" needs_posix="ac_cv_func_waitpid" needs_load="ac_cv_search_dlopen" -needs_signal="ac_cv_func_sigaction" +needs_signal="ac_cv_func_sigaction ac_cv_func_vfork" needs_readdir="ac_cv_func_opendir" ext_add=$(echo $with_jim_ext | tr ' ' '\n') @@ -48,18 +48,19 @@ #include "jim.h" -#ifndef JIM_ANSIC +#if !defined(JIM_ANSIC) #include <sys/socket.h> -#include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif #endif #include "jim-eventloop.h" #include "jim-subcmd.h" - #define AIO_CMD_LEN 32 /* e.g. aio.handleXXXXXX */ #define AIO_BUF_LEN 256 /* Can keep this small and rely on stdio buffering */ @@ -69,8 +70,8 @@ #define IPV6 1 #else #define IPV6 0 -#ifndef AF_INET6 -#define AF_INET6 0 +#ifndef PF_INET6 +#define PF_INET6 0 #endif #endif @@ -82,6 +83,17 @@ union sockaddr_any { struct sockaddr_in6 sin6; #endif }; + +#ifndef HAVE_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, int size) +{ + if (af != PF_INET) { + return NULL; + } + snprintf(dst, size, "%s", inet_ntoa(((struct sockaddr_in *)src)->sin_addr)); + return dst; +} +#endif #endif typedef struct AioFile @@ -181,11 +193,9 @@ static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union soc * If the address is missing, INADDR_ANY is used. * If the port is missing, 0 is used (only useful for server sockets). */ - char *sthost = NULL; - const char *stport; - int ret = JIM_OK; - struct addrinfo req; - struct addrinfo *ai; + char *sthost = NULL; + const char *stport; + int ret = JIM_OK; stport = strrchr(hostport, ':'); if (!stport) { @@ -198,26 +208,48 @@ static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union soc stport++; } - memset(&req, '\0', sizeof(req)); - req.ai_family = PF_INET; - - if (getaddrinfo(sthost, NULL, &req, &ai)) { - Jim_SetResultFormatted(interp, "Not a valid address: %s", hostport); + { +#ifdef HAVE_GETADDRINFO + struct addrinfo req; + struct addrinfo *ai; + memset(&req, '\0', sizeof(req)); + req.ai_family = PF_INET; + + if (getaddrinfo(sthost, NULL, &req, &ai)) { + ret = JIM_ERR; + } + else { + memcpy(&sa->sin, ai->ai_addr, ai->ai_addrlen); + *salen = ai->ai_addrlen; + freeaddrinfo(ai); + } +#else + struct hostent *he; + ret = JIM_ERR; - } - else { - memcpy(&sa->sin, ai->ai_addr, ai->ai_addrlen); - *salen = ai->ai_addrlen; - sa->sin.sin_port = htons(atoi(stport)); + if ((he = gethostbyname(sthost)) != NULL) { + if (he->h_length == sizeof(sa->sin.sin_addr)) { + *salen = sizeof(sa->sin); + sa->sin.sin_family= he->h_addrtype; + memcpy(&sa->sin.sin_addr, he->h_addr, he->h_length); /* set address */ + ret = JIM_OK; + } + } +#endif - freeaddrinfo(ai); + sa->sin.sin_port = htons(atoi(stport)); } Jim_Free(sthost); + if (ret != JIM_OK) { + Jim_SetResultFormatted(interp, "Not a valid address: %s", hostport); + } + return ret; } +#ifdef HAVE_SYS_UN_H static int JimParseDomainAddress(Jim_Interp *interp, const char *path, struct sockaddr_un *sa) { sa->sun_family = PF_UNIX; @@ -226,6 +258,7 @@ static int JimParseDomainAddress(Jim_Interp *interp, const char *path, struct so return JIM_OK; } #endif +#endif static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name) { @@ -271,21 +304,24 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int nonewline = 0; int neededLen = -1; /* -1 is "read as much as possible" */ - if (argc) { - if (Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { - nonewline = 1; - } - else { - jim_wide wideValue; + if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { + nonewline = 1; + argv++; + argc--; + } + if (argc == 1) { + jim_wide wideValue; - if (Jim_GetWide(interp, argv[0], &wideValue) != JIM_OK) - return JIM_ERR; - if (wideValue < 0) { - Jim_SetResultString(interp, "invalid parameter: negative len", -1); - return JIM_ERR; - } - neededLen = (int)wideValue; + if (Jim_GetWide(interp, argv[0], &wideValue) != JIM_OK) + return JIM_ERR; + if (wideValue < 0) { + Jim_SetResultString(interp, "invalid parameter: negative len", -1); + return JIM_ERR; } + neededLen = (int)wideValue; + } + else if (argc) { + return -1; } objPtr = Jim_NewStringObj(interp, NULL, 0); while (neededLen != 0) { @@ -450,7 +486,7 @@ static int aio_cmd_recvfrom(Jim_Interp *interp, int argc, Jim_Obj *const *argv) char addrbuf[60]; #if IPV6 - if (sa.sa.sa_family == AF_INET6) { + if (sa.sa.sa_family == PF_INET6) { addrbuf[0] = '['; /* Allow 9 for []:65535\0 */ inet_ntop(sa.sa.sa_family, &sa.sin6.sin6_addr, addrbuf + 1, sizeof(addrbuf) - 9); @@ -483,7 +519,7 @@ static int aio_cmd_sendto(Jim_Interp *interp, int argc, Jim_Obj *const *argv) const char *addr = Jim_GetString(argv[1], NULL); int salen; - if (IPV6 && af->addr_family == AF_INET6) { + if (IPV6 && af->addr_family == PF_INET6) { if (JimParseIPv6Address(interp, addr, &sa, &salen) != JIM_OK) { return JIM_ERR; } @@ -577,8 +613,7 @@ static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv) else if (Jim_CompareStringImmediate(interp, argv[1], "end")) orig = SEEK_END; else { - Jim_SetResultFormatted(interp, "bad origin \"%#s\": must be start, current, or end", argv[1]); - return JIM_ERR; + return -1; } } if (Jim_GetLong(interp, argv[0], &offset) != JIM_OK) { @@ -701,10 +736,10 @@ static int aio_cmd_onexception(Jim_Interp *interp, int argc, Jim_Obj *const *arg static const jim_subcmd_type aio_command_table[] = { { .cmd = "read", - .args = "?-nonewline|len?", + .args = "?-nonewline? ?len?", .function = aio_cmd_read, .minargs = 0, - .maxargs = 1, + .maxargs = 2, .description = "Read and return bytes from the stream. To eof if no len." }, { .cmd = "gets", @@ -955,7 +990,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int res; int on = 1; const char *mode = "r+"; - int family = AF_INET; + int family = PF_INET; Jim_Obj *argv0 = argv[0]; int ipv6 = 0; @@ -965,7 +1000,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } ipv6 = 1; - family = AF_INET6; + family = PF_INET6; } argc -= ipv6; argv += ipv6; @@ -1055,7 +1090,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } /* Enable address reuse */ - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); res = bind(sock, &sa.sa, salen); if (res) { @@ -1075,6 +1110,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } break; +#ifdef HAVE_SYS_UN_H case SOCK_UNIX: { struct sockaddr_un sa; @@ -1140,7 +1176,9 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) hdlfmt = "aio.sockunixsrv%ld"; break; } +#endif +#ifdef HAVE_PIPE case SOCK_STREAM_PIPE: { int p[2]; @@ -1166,7 +1204,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) sock = p[1]; } break; - +#endif default: Jim_SetResultString(interp, "Unsupported socket type", -1); return JIM_ERR; diff --git a/jim-eventloop.c b/jim-eventloop.c index 7192745..b7c20ea 100644 --- a/jim-eventloop.c +++ b/jim-eventloop.c @@ -48,9 +48,22 @@ #include <sys/types.h> #include <string.h> #include <unistd.h> -#include <sys/select.h> #include <errno.h> +#if defined(__MINGW32__) +#include <windows.h> +#include <winsock.h> +#define msleep Sleep +#else +#include <sys/select.h> + +#ifndef HAVE_USLEEP +/* XXX: Implement this in terms of select() or nanosleep() */ +#define usleep(US) +#endif +#define msleep(MS) sleep((MS) / 1000); usleep(((MS) % 1000) * 1000); +#endif + /* --- */ /* File event structure */ @@ -622,8 +635,7 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } else if (argc == 2) { /* Simply a sleep */ - sleep(ms / 1000); - usleep((ms % 1000) * 1000); + msleep(ms); return JIM_OK; } @@ -679,9 +691,10 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_TimeEvent *te = eventLoop->timeEventHead; Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); char buf[30]; + const char *fmt = "after#%" JIM_WIDE_MODIFIER; while (te) { - snprintf(buf, sizeof(buf), "after#%" JIM_WIDE_MODIFIER, te->id); + snprintf(buf, sizeof(buf), fmt, te->id); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, buf, -1)); te = te->next; } @@ -58,6 +58,10 @@ #include "jim.h" #include "jim-subcmd.h" +#ifndef MAXPATHLEN +#define MAXPATHLEN JIM_PATH_LEN +#endif + /* *---------------------------------------------------------------------- * @@ -588,7 +592,7 @@ static int file_cmd_owned(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #endif -#ifdef S_IFLNK +#if defined(HAVE_READLINK) static int file_cmd_readlink(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { const char *path = Jim_GetString(argv[0], NULL); @@ -760,7 +764,7 @@ static const jim_subcmd_type file_command_table[] = { .maxargs = 3, .description = "Renames a file" }, -#ifdef S_IFLNK +#if defined(HAVE_READLINK) { .cmd = "readlink", .args = "name", .function = file_cmd_readlink, diff --git a/jim-interactive.c b/jim-interactive.c index 15b4cba..00813a7 100644 --- a/jim-interactive.c +++ b/jim-interactive.c @@ -36,7 +36,6 @@ int Jim_InteractivePrompt(Jim_Interp *interp) char state; int len; - errno = 0; if (fgets(buf, MAX_LINE_LEN, stdin) == NULL) { if (errno == EINTR) { continue; diff --git a/jim-signal.c b/jim-signal.c index 506c08a..2a3ec4c 100644 --- a/jim-signal.c +++ b/jim-signal.c @@ -433,12 +433,13 @@ static int Jim_SleepCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ret = Jim_GetDouble(interp, argv[1], &t); if (ret == JIM_OK) { +#ifdef HAVE_USLEEP if (t < 1) { usleep(t * 1e6); } - else { + else +#endif sleep(t); - } } } diff --git a/jim-win32compat.c b/jim-win32compat.c index d99f5b2..76e7a96 100644 --- a/jim-win32compat.c +++ b/jim-win32compat.c @@ -88,3 +88,29 @@ struct dirent *readdir(DIR * dir) } return result; } + +void *dlopen(const char *path, int mode) +{ + JIM_NOTUSED(mode); + + return (void *)LoadLibraryA(path); +} + +int dlclose(void *handle) +{ + FreeLibrary((HANDLE)handle); + return 0; +} + +void *dlsym(void *handle, const char *symbol) +{ + return GetProcAddress((HMODULE)handle, symbol); +} + +const char *dlerror(void) +{ + static char msg[121]; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + LANG_NEUTRAL, msg, sizeof(msg) - 1, NULL); + return msg; +} @@ -13184,7 +13184,9 @@ static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv const char *val; if (argc == 1) { +#ifdef NEED_ENVIRON_EXTERN extern char **environ; +#endif int i; Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); @@ -87,6 +87,9 @@ extern "C" { #if defined(__MINGW32__) #define JIM_ANSIC +#define MKDIR_ONE_ARG +#define rand_r(S) ((void)(S), rand()) +#define localtime_r(T,TM) ((void)(TM), localtime(T)) #endif #ifndef HAVE_NO_AUTOCONF diff --git a/jimautoconf.h.in b/jimautoconf.h.in index 6c0772f..fbb871f 100644 --- a/jimautoconf.h.in +++ b/jimautoconf.h.in @@ -9,9 +9,15 @@ /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + /* Define to 1 if you have the `geteuid' function. */ #undef HAVE_GETEUID +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H @@ -27,6 +33,15 @@ /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP +/* Define to 1 if you have the `opendir' function. */ +#undef HAVE_OPENDIR + +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + +/* Define to 1 if you have the `readlink' function. */ +#undef HAVE_READLINK + /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH @@ -36,6 +51,9 @@ /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION +/* Define to 1 if you have the `sleep' function. */ +#undef HAVE_SLEEP + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -54,6 +72,9 @@ /* Define to 1 if you have the `sysinfo' function. */ #undef HAVE_SYSINFO +/* Define to 1 if you have the `syslog' function. */ +#undef HAVE_SYSLOG + /* Define to 1 if you have the `sys_siglist' function. */ #undef HAVE_SYS_SIGLIST @@ -66,18 +87,27 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the <sys/un.h> header file. */ +#undef HAVE_SYS_UN_H + /* Define to 1 if you have the `ualarm' function. */ #undef HAVE_UALARM /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK /* Define to 1 if you have the `waitpid' function. */ #undef HAVE_WAITPID +/* Must declare 'environ' to use it. */ +#undef NEED_ENVIRON_EXTERN + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT diff --git a/tclcompat.tcl b/tclcompat.tcl index 398a916..d6fa23e 100644 --- a/tclcompat.tcl +++ b/tclcompat.tcl @@ -170,6 +170,7 @@ proc popen {cmd {mode r}} { } # A wrapper around 'pid' which can return the pids for 'popen' +if {[info commands pid] ne ""} { rename pid .pid proc pid {{chan {}}} { if {$chan eq ""} { @@ -183,6 +184,7 @@ proc pid {{chan {}}} { } return $pids } +} # try/on/finally conceptually similar to Tcl 8.6 # diff --git a/tests/event.test b/tests/event.test index 0f681af..725d63b 100644 --- a/tests/event.test +++ b/tests/event.test @@ -105,15 +105,16 @@ foreach i [after info] { after cancel $i } +if {[info commands socket] ne ""} { test event-11.5 {Tcl_VwaitCmd procedure: round robin scheduling, 2 sources} { set f1 [open test1 w] proc accept {s args} { puts $s foobar close $s } - catch {set s1 [socket stream.server 5001]} + set s1 [socket stream.server 5001] after 1000 - catch {set s2 [socket stream 5001]} + set s2 [socket stream 127.0.0.1:5001] close $s1 set x 0 set y 0 @@ -128,6 +129,7 @@ test event-11.5 {Tcl_VwaitCmd procedure: round robin scheduling, 2 sources} { file delete test1 test2 list $x $y $z } {3 3 done} +} test event-11.6 {Tcl_VwaitCmd procedure: round robin scheduling, same source} { file delete test1 test2 set f1 [open test1 w] |