aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rwxr-xr-xconfigure237
-rwxr-xr-xconfigure.ac45
-rw-r--r--jim-aio.c126
-rw-r--r--jim-eventloop.c21
-rw-r--r--jim-file.c8
-rw-r--r--jim-interactive.c1
-rw-r--r--jim-signal.c5
-rw-r--r--jim-win32compat.c26
-rw-r--r--jim.c2
-rw-r--r--jim.h3
-rw-r--r--jimautoconf.h.in30
-rw-r--r--tclcompat.tcl2
-rw-r--r--tests/event.test6
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@
diff --git a/configure b/configure
index 42150c5..528fbc0 100755
--- a/configure
+++ b/configure
@@ -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')
diff --git a/jim-aio.c b/jim-aio.c
index e606848..45b5c42 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -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;
}
diff --git a/jim-file.c b/jim-file.c
index 8c4450d..a53de58 100644
--- a/jim-file.c
+++ b/jim-file.c
@@ -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;
+}
diff --git a/jim.c b/jim.c
index f4a0d9c..241742e 100644
--- a/jim.c
+++ b/jim.c
@@ -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);
diff --git a/jim.h b/jim.h
index 7325eb2..79b209a 100644
--- a/jim.h
+++ b/jim.h
@@ -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]