# HG changeset patch # User jwe # Date 1126918258 0 # Node ID 89f5979e8552e1b4bc8aa5d56b4c3a33a8c16eeb # Parent 5a70e4162b25c1afc8c0de7043b1f811a0db7b16 [project @ 2005-09-17 00:50:58 by jwe] diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,19 @@ +2005-09-16 John W. Eaton + + * oct-syscalls.cc: Include lo-utils.h here. + (octave_syscalls::waitpid): Call octave_waitpid here. + + * lo-cutils.c (octave_waitpid): New function. + * lo-utils.h: Provide decl. Include syswait.h here, not in + oct-syscalls.cc + + + * syswait.h [__MINGW32__]: Define WAITPID here instead of defining + waitpid in src/sysdep.h. Make this header C-compatible. + + * oct-syscalls.cc (octave_syscalls::waitpid): New arg, status. + Change all uses. + 2005-09-15 John W. Eaton * Makefile.in (MAKEDEPS_2): Omit unnecessary variable. diff --git a/liboctave/lo-cutils.c b/liboctave/lo-cutils.c --- a/liboctave/lo-cutils.c +++ b/liboctave/lo-cutils.c @@ -51,6 +51,8 @@ #include #include +#include "syswait.h" + void octave_qsort (void *base, size_t n, size_t size, int (*cmp) (const void *, const void *)) @@ -100,12 +102,19 @@ #include /* Need this since in C++ can't cast from int(*)() to void* */ -void * octave_w32_library_search (HINSTANCE handle, const char * name) +void * +octave_w32_library_search (HINSTANCE handle, const char * name) { return (GetProcAddress (handle, name)); } #endif +pid_t +octave_waitpid (pid_t pid, int *status, int options) +{ + return WAITPID (pid, status, options); +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/lo-utils.h b/liboctave/lo-utils.h --- a/liboctave/lo-utils.h +++ b/liboctave/lo-utils.h @@ -31,6 +31,7 @@ #include "oct-cmplx.h" #include "oct-types.h" +#include "syswait.h" extern octave_idx_type NINTbig (double x); extern int NINT (double x); @@ -66,6 +67,8 @@ #endif #endif +extern "C" pid_t octave_waitpid (pid_t pid, int *status, int options); + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/oct-syscalls.cc b/liboctave/oct-syscalls.cc --- a/liboctave/oct-syscalls.cc +++ b/liboctave/oct-syscalls.cc @@ -46,9 +46,9 @@ #include +#include "lo-utils.h" #include "oct-syscalls.h" #include "str-vec.h" -#include "syswait.h" #define NOT_SUPPORTED(nm) \ nm ": not supported on this system" @@ -299,23 +299,22 @@ } pid_t -octave_syscalls::waitpid (pid_t pid, int options) +octave_syscalls::waitpid (pid_t pid, int *status, int options) { std::string msg; - return waitpid (pid, options, msg); + return waitpid (pid, status, options, msg); } pid_t -octave_syscalls::waitpid (pid_t pid, int options, std::string& msg) +octave_syscalls::waitpid (pid_t pid, int *status, int options, + std::string& msg) { msg = std::string (); - int status = -1; +#if defined (HAVE_WAITPID) + pid_t retval = ::octave_waitpid (pid, status, options); -#if defined (HAVE_WAITPID) - status = ::waitpid (pid, 0, options); - - if (status < 0) + if (retval < 0) { using namespace std; msg = ::strerror (errno); @@ -324,7 +323,7 @@ msg = NOT_SUPPORTED ("waitpid"); #endif - return status; + return retval; } int diff --git a/liboctave/oct-syscalls.h b/liboctave/oct-syscalls.h --- a/liboctave/oct-syscalls.h +++ b/liboctave/oct-syscalls.h @@ -61,8 +61,8 @@ static int pipe (int *); static int pipe (int *, std::string&); - static pid_t waitpid (pid_t, int); - static pid_t waitpid (pid_t, int, std::string&); + static pid_t waitpid (pid_t, int *status, int); + static pid_t waitpid (pid_t, int *status, int, std::string&); static int kill (pid_t, int); static int kill (pid_t, int, std::string&); diff --git a/liboctave/syswait.h b/liboctave/syswait.h --- a/liboctave/syswait.h +++ b/liboctave/syswait.h @@ -24,7 +24,11 @@ #if !defined (octave_syswait_h) #define octave_syswait_h 1 -// This mess suggested by the autoconf manual. +#ifdef __cplusplus +extern "C" { +#endif + +/* This mess suggested by the autoconf manual. */ #ifdef HAVE_SYS_TYPES_H #include @@ -40,17 +44,17 @@ #if defined (NeXT) #define HAVE_WAITPID 1 -#define waitpid(a, b, c) \ +#define WAITPID(a, b, c) \ wait4 ((a) == -1 ? 0 : (a), (union wait *)(b), c, 0) -// Use the defaults below +/* Use the defaults below. */ #undef WIFEXITED #undef WEXITSTATUS #undef WIFSIGNALLED #endif -// NeXT has sys/wait.h, but it is not compatible with POSIX.1, so we -// try to define waitpid in terms of wait4. +/* NeXT has sys/wait.h, but it is not compatible with POSIX.1, so we + try to define waitpid in terms of wait4. */ #if defined (NeXT) #include @@ -71,6 +75,20 @@ (((stat_val) & 0177) != 0177 && ((stat_val) & 0177) != 0) #endif +#if defined (__MINGW32__) +#define HAVE_WAITPID 1 +#include +#define WAITPID(a, b, c) _cwait (b, a, c) +/* Action argument is ignored for _cwait, so arbitrary definition. */ +#define WNOHANG 0 +#else +#define WAITPID(a, b, c) waitpid (a, b, c) +#endif + +#ifdef __cplusplus +} +#endif + #endif /* diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2005-09-16 John W. Eaton + + * syscalls.cc (Fwaitpid): Doc fix. Expect WNOHANG, WUNTRACED, + WCONTINUED as args instad of int values. + Return values are now [pid, status, msg] instad of [pid, msg]. + (WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, + WIFSTOPPED, WSTOPSIG, WIFCONTINUED): New functions. + (symbols_of_syscalls): DEFCONST WNOHANG, WUNTRACED, and WCONTINUE. + + * oct-procbuf.cc (octave_procbuf::close): Call octave_syscalls::waitpid + here instead of calling waitpid directly. + * sighandlers.cc (OCL_REP::wait): Likewise. + + * sysdep.h [__MINGW32__]: Don't define waitpid here. + 2005-09-15 John W. Eaton * sysdep.h [__MINGW32__]: Move to definition of waitpid sysdep.h. diff --git a/src/oct-procbuf.cc b/src/oct-procbuf.cc --- a/src/oct-procbuf.cc +++ b/src/oct-procbuf.cc @@ -39,7 +39,7 @@ #include "lo-mappers.h" #include "lo-utils.h" #include "oct-procbuf.h" -#include "syswait.h" +#include "oct-syscalls.h" #include "variables.h" #include "defun.h" @@ -214,7 +214,7 @@ do { - wait_pid = ::waitpid (proc_pid, &wstatus, 0); + wait_pid = octave_syscalls::waitpid (proc_pid, &wstatus, 0); } while (wait_pid == -1 && errno == EINTR); } diff --git a/src/sighandlers.cc b/src/sighandlers.cc --- a/src/sighandlers.cc +++ b/src/sighandlers.cc @@ -38,6 +38,7 @@ #endif #include "cmd-edit.h" +#include "oct-syscalls.h" #include "quit.h" #include "defun.h" @@ -951,7 +952,7 @@ { int status; - if (waitpid (pid, &status, WNOHANG) > 0) + if (octave_syscalls::waitpid (pid, &status, WNOHANG) > 0) { oc.have_status = 1; diff --git a/src/syscalls.cc b/src/syscalls.cc --- a/src/syscalls.cc +++ b/src/syscalls.cc @@ -57,7 +57,6 @@ #include "oct-stdstrm.h" #include "oct-stream.h" #include "sysdep.h" -#include "syswait.h" #include "utils.h" #include "variables.h" @@ -857,7 +856,7 @@ DEFUN (waitpid, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{pid}, @var{msg}] =} waitpid (@var{pid}, @var{options})\n\ +@deftypefn {Built-in Function} {[@var{pid}, @var{status}, @var{msg}] =} waitpid (@var{pid}, @var{options})\n\ Wait for process @var{pid} to terminate. The @var{pid} argument can be:\n\ \n\ @table @asis\n\ @@ -872,33 +871,38 @@ Wait for termination of the child process with ID @var{pid}.\n\ @end table\n\ \n\ -The @var{options} argument can be:\n\ +The @var{options} argument can be a bitwise OR of zero or more of\n\ +the following constants:\n\ \n\ -@table @asis\n\ +@table @code\n\ @item 0\n\ Wait until signal is received or a child process exits (this is the\n\ default if the @var{options} argument is missing).\n\ \n\ -@item 1\n\ +@item WNOHANG\n\ Do not hang if status is not immediately available.\n\ \n\ -@item 2\n\ +@item WUNTRACED\n\ Report the status of any child processes that are stopped, and whose\n\ status has not yet been reported since they stopped.\n\ \n\ -@item 3\n\ -Implies both 1 and 2.\n\ +@item WCONTINUED\n\ +Return if a stopped child has been resumed by delivery of @code{SIGCONT}.\n\ +This value may not be meaningful on all systems.\n\ @end table\n\ \n\ If the returned value of @var{pid} is greater than 0, it is the process\n\ ID of the child process that exited. If an error occurs, @var{pid} will\n\ be less than zero and @var{msg} will contain a system-dependent error\n\ -message.\n\ +message. The value of @var{status} contains additional system-depenent\n\ +information about the subprocess that exited.\n\ +@seealso{WNOHANG, WUNTRACED, WCONTINUED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\ @end deftypefn") { octave_value_list retval; - retval(1) = std::string (); + retval(2) = std::string (); + retval(1) = 0; retval(0) = -1; int nargin = args.length (); @@ -912,27 +916,22 @@ int options = 0; if (args.length () == 2) - { - options = args(1).int_value (true); - - if (! error_state) - { - if (options < 0 || options > 3) - error ("waitpid: invalid OPTIONS value specified"); - } - else - error ("waitpid: OPTIONS must be in integer"); - } + options = args(1).int_value (true); if (! error_state) { std::string msg; - pid_t status = octave_syscalls::waitpid (pid, options, msg); + int status = 0; + + pid_t result = octave_syscalls::waitpid (pid, &status, options, msg); - retval(0) = status; - retval(1) = msg; + retval(0) = result; + retval(1) = status; + retval(2) = msg; } + else + error ("waitpid: OPTIONS must be an integer"); } else error ("waitpid: PID must be an integer value"); @@ -943,6 +942,230 @@ return retval; } +DEFUNX ("WIFEXITED", FWIFEXITED, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WIFEXITED (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return true if the\n\ +child terminated normally.\n\ +@seealso{waitpid, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\ +@end deftypefn\n") +{ + octave_value retval = 0.0; + +#if defined (WIFEXITED) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WIFEXITED (status); + else + error ("WIFEXITED: expecting integer argument"); + } +#else + warning ("WIFEXITED always returns false in this version of Octave") +#endif + + return retval; +} + +DEFUNX ("WEXITSTATUS", FWEXITSTATUS, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WEXITSTATUS (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return the exit\n\ +status of the child. This function should only be employed if\n\ +@code{WIFEXITED} returned true.\n\ +@seealso{waitpid, WIFEXITED, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\ +@end deftypefn") +{ + octave_value retval = 0.0; + +#if defined (WEXITSTATUS) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WEXITSTATUS (status); + else + error ("WEXITSTATUS: expecting integer argument"); + } +#else + warning ("WEXITSTATUS always returns false in this version of Octave") +#endif + + return retval; +} + +DEFUNX ("WIFSIGNALED", FWIFSIGNALED, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WIFSIGNALED (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return true if the\n\ +child process was terminated by a signal.\n\ +@seealso{waitpid, WIFEXITED, WEXITSTATUS, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\ +@end deftypefn") +{ + octave_value retval = 0.0; + +#if defined (WIFSIGNALED) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WIFSIGNALED (status); + else + error ("WIFSIGNALED: expecting integer argument"); + } +#else + warning ("WIFSIGNALED always returns false in this version of Octave") +#endif + + return retval; +} + +DEFUNX ("WTERMSIG", FWTERMSIG, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WTERMSIG (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return the number of\n\ +the signal that caused the child process to terminate. This function\n\ +should only be employed if @code{WIFSIGNALED} returned true.\n\ +@seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WCOREDUMP, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\ +@end deftypefn") +{ + octave_value retval = 0.0; + +#if defined (WTERMSIG) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WTERMSIG (status); + else + error ("WTERMSIG: expecting integer argument"); + } +#else + warning ("WTERMSIG always returns false in this version of Octave") +#endif + + return retval; +} + +DEFUNX ("WCOREDUMP", FWCOREDUMP, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WCOREDUMP (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return true if the\n\ +child produced a core dump. This function should only be employed if\n\ +@code{WIFSIGNALED} returned true. The macro used to implement this\n\ +function is not specified in POSIX.1-2001 and is not available on some\n\ +Unix implementations (e.g., AIX, SunOS).\n\ +@seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG, WIFCONTINUED}\n\ +@end deftypefn") +{ + octave_value retval = 0.0; + +#if defined (WCOREDUMP) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WCOREDUMP (status); + else + error ("WCOREDUMP: expecting integer argument"); + } +#else + warning ("WCOREDUMP always returns false in this version of Octave") +#endif + + return retval; +} + +DEFUNX ("WIFSTOPPED", FWIFSTOPPED, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WIFSTOPPED (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return true if the\n\ +child process was stopped by delivery of a signal; this is only\n\ +possible if the call was done using @code{WUNTRACED} or when the child\n\ +is being traced (see ptrace(2)).\n\ +@seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WSTOPSIG, WIFCONTINUED}\n\ +@end deftypefn") +{ + octave_value retval = 0.0; + +#if defined (WIFSTOPPED) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WIFSTOPPED (status); + else + error ("WIFSTOPPED: expecting integer argument"); + } +#else + warning ("WIFSTOPPED always returns false in this version of Octave") +#endif + + return retval; +} + +DEFUNX ("WSTOPSIG", FWSTOPSIG, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WSTOPSIG (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return the number of\n\ +the signal which caused the child to stop. This function should only\n\ +be employed if @code{WIFSTOPPED} returned true.\n\ +@seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WIFCONTINUED}\n\ +@end deftypefn") +{ + octave_value retval = 0.0; + +#if defined (WSTOPSIG) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WSTOPSIG (status); + else + error ("WSTOPSIG: expecting integer argument"); + } +#else + warning ("WSTOPSIG always returns false in this version of Octave") +#endif + + return retval; +} + +DEFUNX ("WIFCONTINUED", FWIFCONTINUED, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} WIFCONTINUED (@var{status})\n\ +Given @var{status} from a call to @code{waitpid}, return true if the\n\ +child process was resumed by delivery of @code{SIGCONT}.\n\ +@seealso{waitpid, WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WCOREDUMP, WIFSTOPPED, WSTOPSIG}\n\ +@end deftypefn") +{ + octave_value retval = 0.0; + +#if defined (WIFCONTINUED) + if (args.length () == 1) + { + int status = args(0).int_value (); + + if (! error_state) + retval = WIFCONTINUED (status); + else + error ("WIFCONTINUED: expecting integer argument"); + } +#else + warning ("WIFCONTINUED always returns false in this version of Octave") +#endif + + return retval; +} + DEFUN (canonicalize_file_name, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{cname}, @var{status}, @var{msg}]} canonicalize_file_name (@var{name})\n\ @@ -1116,6 +1339,39 @@ @end defvr"); #endif +#if !defined (WNOHANG) +#define WNOHANG 0 +#endif + + DEFCONSTX ("WNOHANG", SBV_WNOHANG, WNOHANG, + "-*- texinfo -*-\n\ +@defvr {Built-in Constant} WNOHANG\n\ +Option value for @code{waitpid}.\n\ +@seealso{waitpid, WUNTRACED, WCONTINUE}\n\ +@end defvr"); + +#if !defined (WUNTRACED) +#define WUNTRACED 0 +#endif + + DEFCONSTX ("WUNTRACED", SBV_WUNTRACED, WUNTRACED, + "-*- texinfo -*-\n\ +@defvr {Built-in Constant} WUNTRACED\n\ +Option value for @code{waitpid}.\n\ +@seealso{waitpid, WNOHANG, WCONTINUE}\n\ +@end defvr"); + +#if !defined (WCONTINUE) +#define WCONTINUE 0 +#endif + + DEFCONSTX ("WCONTINUE", SBV_WCONTINUE, WCONTINUE, + "-*- texinfo -*-\n\ +@defvr {Built-in Constant} WCONINTUE\n\ +Option value for @code{waitpid}.\n\ +@seealso{waitpid, WNOHANG, WUNTRACED}\n\ +@end defvr"); + } /* diff --git a/src/sysdep.h b/src/sysdep.h --- a/src/sysdep.h +++ b/src/sysdep.h @@ -47,13 +47,6 @@ #define MINGW_SIGNAL_CLEANUP() do { } while (0) #endif -#if defined (__MINGW32__) -#include -#define waitpid(a, b, c) _cwait (b, a, c) -// action argument is ignored for _cwait, so arbitrary definition -#define WNOHANG 0 -#endif - #endif /* diff --git a/src/system.c b/src/system.c deleted file mode 100644 --- a/src/system.c +++ /dev/null @@ -1,94 +0,0 @@ -#if defined (__CYGWIN32__) - -#include -#include -#include -#include -#include -#include - -int -system (const char *cmd) -{ - pid_t pid; - - int status = 1; - - struct sigaction ignore, saved_sigint, saved_sigquit; - - sigset_t child_mask, saved_mask; - - if (cmd) - { - ignore.sa_handler = SIG_IGN; - - sigemptyset (&ignore.sa_mask); - - ignore.sa_flags = 0; - - if (sigaction (SIGINT, &ignore, &saved_sigint) < 0) - return -1; - - if (sigaction (SIGQUIT, &ignore, &saved_sigquit) < 0) - return -1; - - sigemptyset (&child_mask); - - sigaddset (&child_mask, SIGCHLD); - - if (sigprocmask (SIG_BLOCK, &child_mask, &saved_mask) < 0) - return -1; - - if ((pid = fork ()) < 0) - status = -1; - else if (pid == 0) - { - sigaction (SIGINT, &saved_sigint, 0); - sigaction (SIGQUIT, &saved_sigquit, 0); - - sigprocmask (SIG_SETMASK, &saved_mask, 0); - - execl ("/bin/sh", "sh", "-c", cmd, 0); - - exit (127); - } - else - { - while (waitpid (pid, &status, 0) < 0) - { - if (errno != EINTR) - { - status = -1; - break; - } - } - } - - if (sigaction (SIGINT, &saved_sigint, 0) < 0) - return -1; - - if (sigaction (SIGQUIT, &saved_sigquit, 0) < 0) - return -1; - - if (sigprocmask (SIG_SETMASK, &saved_mask, 0) < 0) - return -1; - } - - return status; -} - -#if defined (TEST) -int -main (void) -{ - system ("info"); - while (1) - { - printf ("foo-i-hithere\n"); - sleep (1); - } - return 0; -} -#endif - -#endif