[m-dev.] diff: io__call_system/4
Christopher Rodd SPEIRS
crs at students.cs.mu.oz.au
Sun Oct 5 00:49:10 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 returns the exit code of the
system call or an error indication. If a signal kills the system call
then an error is returned indicating which signal occured.
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.77
diff -u -r1.77 NEWS
--- NEWS 1997/10/04 06:49:29 1.77
+++ NEWS 1997/10/04 09:09:47
@@ -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. If a signal causes the system call to
+ exit, then io__call_system/4 returns an error.
+
* 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/04 14:32:05
@@ -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,62 @@
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/04 09:13:25
@@ -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 or the return value of the system call
+% otherwise. If a signal kills the system call, then Result
+% will be an error indicating which signal occured.
:- pred io__error_message(io__error, string).
:- mode io__error_message(in, out) is det.
@@ -987,9 +991,11 @@
:- pred io__call_system_code(string, int, io__state, io__state).
:- mode io__call_system_code(in, out, di, uo) is det.
-% io__call_system(Command, Status, IO0, IO1).
+% io__call_system_code(Command, Status, IO0, IO1).
% Invokes the operating system shell with the specified
-% Command. Returns Status = -1 on failure.
+% Command. Returns Status = 127 on failure. Otherwise
+% returns the exit status as a positive integer, or the
+% signal which killed the command as a negative integer.
:- pred io__do_open(string, string, int, io__input_stream,
io__state, io__state).
@@ -1954,9 +1960,15 @@
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")
+ ; Status < 0 ->
+ Signal is - Status,
+ string__int_to_string(Signal, SignalStr),
+ string__append("system command killed by signal number ",
+ SignalStr, ErrMsg),
+ Result = error(ErrMsg)
;
Result = ok(Status)
}.
@@ -1994,6 +2006,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 +2570,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
+ Status = 127;
+
+ #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