aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--builtin.c4
-rw-r--r--nonposix.h15
-rw-r--r--pc/ChangeLog10
-rw-r--r--pc/config.h4
-rw-r--r--pc/config.sed4
-rw-r--r--pc/gawkmisc.pc44
7 files changed, 84 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index d34c136e..d25772c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2016-04-07 Eli Zaretskii <eliz@gnu.org>
+
+ * nonposix.h (WEXITSTATUS, WIFEXITED, WIFSIGNALED, WTERMSIG)
+ (WIFSTOPPED, WSTOPSIG) [__MINGW32__]: New macros to replace the
+ missing header sys/wait.h.
+ (w32_status_to_termsig): Add prototype.
+
+ * builtin.c (do_system) [__MINGW32__]: Compute the exit status of
+ 'system' differently under --traditional, as the low 8 bits are
+ the most interesting.
+
2016-04-04 Arnold D. Robbins <arnold@skeeve.com>
* builtin.c (do_fflush): Add warning for flush to two-way
diff --git a/builtin.c b/builtin.c
index a1c09d5a..8aee1177 100644
--- a/builtin.c
+++ b/builtin.c
@@ -2101,7 +2101,11 @@ do_system(int nargs)
if (do_posix)
; /* leave it alone, full 16 bits */
else if (do_traditional)
+#ifdef __MINGW32__
+ ret = (((unsigned)status) & ~0xC0000000);
+#else
ret = (status / 256.0);
+#endif
else if (WIFEXITED(status))
ret = WEXITSTATUS(status); /* normal exit */
else if (WIFSIGNALED(status)) {
diff --git a/nonposix.h b/nonposix.h
index 88fd9e69..976e0b7d 100644
--- a/nonposix.h
+++ b/nonposix.h
@@ -29,3 +29,18 @@
*/
#define FAKE_FD_VALUE 42
+
+#ifdef __MINGW32__
+/* Replacements for sys/wait.h macros. */
+# define WEXITSTATUS(stv) (((unsigned)(stv)) & ~0xC0000000)
+/* MS-Windows programs that crash due to a fatal exception exit with
+ an exit code whose 2 MSB bits are set. */
+# define WIFEXITED(stv) ((((unsigned)(stv)) & 0xC0000000) == 0)
+# define WIFSIGNALED(stv) ((((unsigned)(stv)) & 0xC0000000) == 0xC0000000)
+# define WTERMSIG(stv) w32_status_to_termsig ((unsigned)stv)
+# define WIFSTOPPED(stv) (0)
+# define WSTOPSIG(stv) (0)
+
+int w32_status_to_termsig (unsigned);
+
+#endif
diff --git a/pc/ChangeLog b/pc/ChangeLog
index 5a7d9676..ba2bcd1f 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,3 +1,13 @@
+2016-04-07 Eli Zaretskii <eliz@gnu.org>
+
+ * config.h: Don't define WEXITSTATUS, it is now defined in
+ nonposix.h.
+
+ * config.sed: Don't define WEXITSTATUS, it is now defined in
+ nonposix.h.
+
+ * gawkmisc.pc (w32_status_to_termsig) [__MINGW32__]: New function.
+
2016-03-16 Eli Zaretskii <eliz@gnu.org>
* gawkmisc.pc (usleep): Condition on MinGW runtime version older
diff --git a/pc/config.h b/pc/config.h
index d6fee701..74577361 100644
--- a/pc/config.h
+++ b/pc/config.h
@@ -618,7 +618,3 @@ typedef int int32_t;
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
-
-#if defined(__MINGW32__)
-# define WEXITSTATUS(stat_val) ((stat_val) & ~0xC0000000)
-#endif
diff --git a/pc/config.sed b/pc/config.sed
index e18a6e68..024abab8 100644
--- a/pc/config.sed
+++ b/pc/config.sed
@@ -297,8 +297,4 @@ typedef int int32_t;\
#if defined(__EMX__)\
#define strcasecmp stricmp\
#define strncasecmp strnicmp\
-#endif\
-\
-#if defined(__MINGW32__)\
-# define WEXITSTATUS(stat_val) ((stat_val) & ~0xC0000000)\
#endif
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc
index 486b1853..3f66db44 100644
--- a/pc/gawkmisc.pc
+++ b/pc/gawkmisc.pc
@@ -852,6 +852,50 @@ w32_shutdown (int fd, int how)
#endif /* HAVE_SOCKETS */
+/* Translate abnormal exit status of Windows programs into the signal
+ that terminated the program. This is required to support scm_kill
+ and WTERMSIG. */
+
+#include <signal.h>
+
+struct signal_and_status {
+ int sig;
+ unsigned status;
+};
+
+static const struct signal_and_status sigtbl[] = {
+ {SIGSEGV, 0xC0000005}, /* access to invalid address */
+ {SIGSEGV, 0xC0000008}, /* invalid handle */
+ {SIGILL, 0xC000001D}, /* illegal instruction */
+ {SIGILL, 0xC0000025}, /* non-continuable instruction */
+ {SIGSEGV, 0xC000008C}, /* array bounds exceeded */
+ {SIGFPE, 0xC000008D}, /* float denormal */
+ {SIGFPE, 0xC000008E}, /* float divide by zero */
+ {SIGFPE, 0xC000008F}, /* float inexact */
+ {SIGFPE, 0xC0000090}, /* float invalid operation */
+ {SIGFPE, 0xC0000091}, /* float overflow */
+ {SIGFPE, 0xC0000092}, /* float stack check */
+ {SIGFPE, 0xC0000093}, /* float underflow */
+ {SIGFPE, 0xC0000094}, /* integer divide by zero */
+ {SIGFPE, 0xC0000095}, /* integer overflow */
+ {SIGILL, 0xC0000096}, /* privileged instruction */
+ {SIGSEGV, 0xC00000FD}, /* stack overflow */
+ {SIGTERM, 0xC000013A}, /* Ctrl-C exit */
+ {SIGINT, 0xC000013A}
+};
+
+int
+w32_status_to_termsig (unsigned status)
+{
+ int i;
+
+ for (i = 0; i < sizeof (sigtbl) / sizeof (sigtbl[0]); i++)
+ if (status == sigtbl[i].status)
+ return sigtbl[i].sig;
+
+ return SIGTERM;
+}
+
#endif /* __MINGW32__ */
#if defined(__DJGPP__) || defined(__MINGW32__) || defined(__EMX__)