diff: io__call_system/4
Christopher Rodd SPEIRS
crs at students.cs.mu.oz.au
Fri Oct 3 14:51:52 AEST 1997
Fergus, could you please review this.
I realise that the AC_TRY_CONFIGURE section is not the most beautiful
code, but it is reasonably clear. I didnt just try using those macros,
because that only causes a warning, not a compiler error. I didnt use
#if ! (...) because autoconf didnt like the ) being on a different line
to the (.
Chris
Changes io__call_system/4 so that it either returns the exit code of the
system call as a positive integer, or the number of the signal which
killed the system call as a negative integer.
NEWS:
Document the change to the interface of io__call_system.
configure.in:
Added a test for sys/wait.h and added a check that we are
able to get the return value and signal number from the
number returned by system().
runtime/conf.h.in:
Added a #undef HAVE_SYS_WAIT line.
library/io.m:
Added code to get the return value/signal number from the
return value of system();
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.76
diff -u -r1.76 NEWS
--- NEWS 1997/10/02 01:47:37 1.76
+++ NEWS 1997/10/03 04:26:09
@@ -69,6 +69,10 @@
solutions and then aggregating them. This allows you
to print out solutions as they are found, for example.
+* We've changed the result produced by io__call_system/4 so that it returns
+ the exit code of the system call as a positive integer, or the signal that
+ caused the system call to exit as a negative integer.
+
* We've improved the C interface.
We now handle the case when `main' is defined in C rather than in Mercury
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.110
diff -u -r1.110 configure.in
--- configure.in 1997/10/02 02:53:42 1.110
+++ configure.in 1997/10/03 02:20:33
@@ -221,6 +221,11 @@
esac
AC_HAVE_FUNCS(sysconf getpagesize memalign mprotect sigaction setitimer strerror memmove)
#-----------------------------------------------------------------------------#
+AC_CHECK_HEADER(sys/wait.h, HAVE_SYS_WAIT_H=1)
+if test "$HAVE_SYS_WAIT_H" = 1; then
+ AC_DEFINE(HAVE_SYS_WAIT)
+fi
+#-----------------------------------------------------------------------------#
AC_CHECK_HEADER(sys/siginfo.h, HAVE_SYS_SIGINFO_H=1)
if test "$HAVE_SYS_SIGINFO_H" = 1; then
AC_DEFINE(HAVE_SYS_SIGINFO)
@@ -876,6 +881,59 @@
AC_DEFINE(MR_LITTLE_ENDIAN)
fi
AC_SUBST(MR_LITTLE_ENDIAN)
+#-----------------------------------------------------------------------------#
+AC_MSG_CHECKING(return values of system)
+AC_CACHE_VAL(mercury_cv_normal_system_retval,
+ AC_TRY_RUN([
+ #include <stdlib.h>
+ #ifdef HAVE_SYS_WAIT
+ #include <sys/wait.h>
+ #endif
+ int main() {
+ #if defined (WIFEXITED) && defined (WEXITSTATUS) && \
+ defined (WIFSIGNALED) && defined (WTERMSIG)
+ /*
+ ** All the necessary macros for handling the return values of
+ ** system() are defined, so we do not need to test the return
+ ** value of system()
+ */
+ exit(0);
+
+ #else
+ /*
+ ** normal return values from system() are considered to be when
+ ** high 8 bits of the return value give the exit status, and the
+ ** low 8 bits give the signal number which killed the process.
+ */
+ if( system("exit 0") == 0 &&
+ system("exit 42") == 42 << 8 &&
+ system("kill -9 $$") == 9 ) {
+ exit(0);
+ } else {
+ exit(1);
+ }
+ #endif
+ }],
+ [mercury_cv_normal_system_retval=yes],
+ [mercury_cv_normal_system_retval=no],
+ AC_TRY_COMPILE([#include <sys/wait.h>], [
+ #if defined (WIFEXITED) && defined (WEXITSTATUS) && \
+ defined (WIFSIGNALED) && defined (WTERMSIG)
+
+ #else
+ /* as these macros are not defined the compilation must fail
+ ** unmatched brackets should do that for us */
+ }
+ #endif
+ ],
+ [mercury_cv_normal_system_retval=yes],
+ [mercury_cv_normal_system_retval=no])
+)
+AC_MSG_RESULT($mercury_cv_normal_system_retval)
+if test "$mercury_cv_normal_system_retval" = no; then
+ AC_MSG_ERROR(Unable to interpret return values from system)
+ exit 1
+fi
#-----------------------------------------------------------------------------#
AC_MSG_CHECKING(for tempnam)
AC_CACHE_VAL(mercury_cv_has_tempnam,
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.140
diff -u -r1.140 io.m
--- io.m 1997/09/09 18:56:14 1.140
+++ io.m 1997/10/03 04:43:29
@@ -876,6 +876,10 @@
% Invokes the operating system shell with the specified
% Command. Result is either `ok(ExitStatus)', if it was
% possible to invoke the command, or `error(ErrorCode)' if not.
+% The ExitStatus will be 0 if the command completed
+% successfully, the return value of the system call as a
+% positive integer, or the number of the signal which killed
+% the system call as a negative integer.
:- pred io__error_message(io__error, string).
:- mode io__error_message(in, out) is det.
@@ -1954,7 +1958,7 @@
io__call_system(Command, Result) -->
io__call_system_code(Command, Status),
- { Status = -1 ->
+ { Status = 127 ->
% XXX improve error message
Result = error("can't invoke system command")
;
@@ -1994,6 +1998,10 @@
#include <string.h>
#include <errno.h>
+#ifdef HAVE_SYS_WAIT
+#include <sys/wait.h>
+#endif
+
/*
** Mercury files are not quite the same as C stdio FILEs,
** because we keep track of a little bit more information.
@@ -2554,6 +2562,33 @@
io__call_system_code(Command::in, Status::out, IO0::di, IO::uo),
"
Status = system(Command);
+ if ( Status == -1 || Status == 127 ) {
+ /*
+ ** Return values of 127 or -1 from system() indicate that
+ ** the system call failed. Dont return -1, as -1 indicates
+ ** that the system call was killed by signal number 1.
+ */
+ Status = 127;
+ } else {
+ #if defined (WIFEXITED) && defined (WEXITSTATUS) && \
+ defined (WIFSIGNALED) && defined (WTERMSIG)
+ if (WIFEXITED(Status))
+ Status = WEXITSTATUS(Status);
+ else if (WIFSIGNALED(Status))
+ Status = -WTERMSIG(Status);
+ else
+ fatal_error(""io__call_system_code: system() returned an unexpected value"");
+
+ #else
+ if (Status & 0xff != 0)
+ /* the process was killed by a signal */
+ Status = -(Status & 0xff);
+ else
+ /* the process terminated normally */
+ Status = (Status & 0xff00) >> 8;
+
+ #endif
+ }
update_io(IO0, IO);
").
Index: runtime/conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/conf.h.in,v
retrieving revision 1.22
diff -u -r1.22 conf.h.in
--- conf.h.in 1997/10/02 02:46:00 1.22
+++ conf.h.in 1997/10/03 01:16:28
@@ -53,6 +53,7 @@
** HAVE_ASM_SIGCONTEXT we have <asm/sigcontext.h> (e.g. i386 Linux)
** HAVE_SYS_TIME we have <sys/time.h>
** HAVE_SYS_PARAM we have <sys/param.h>
+** HAVE_SYS_WAIT we have <sys/wait.h>
*/
#undef HAVE_SYS_SIGINFO
#undef HAVE_UCONTEXT
@@ -60,6 +61,7 @@
#undef HAVE_ASM_SIGCONTEXT
#undef HAVE_SYS_TIME
#undef HAVE_SYS_PARAM
+#undef HAVE_SYS_WAIT
/*
** The following macros are defined iff the corresponding function or
More information about the developers
mailing list