external process: handle sigstop / sigcont in process

New state "resumed" added.
This commit is contained in:
Daniel Kochmański 2017-02-20 15:21:26 +01:00
parent 772262f1c6
commit abf580c9e4
4 changed files with 20 additions and 9 deletions

View file

@ -1988,6 +1988,7 @@ cl_symbols[] = {
{KEY_ "EXITED", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "SIGNALED", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "STOPPED", KEYWORD, NULL, -1, OBJNULL},
{KEY_ "RESUMED", KEYWORD, NULL, -1, OBJNULL},
/* ~ external-process extension */
/* unixsys.d */

View file

@ -1988,6 +1988,7 @@ cl_symbols[] = {
{KEY_ "EXITED",NULL},
{KEY_ "SIGNALED",NULL},
{KEY_ "STOPPED",NULL},
{KEY_ "RESUMED",NULL},
/* ~ external-process extension */
/* unixsys.d */

View file

@ -175,7 +175,12 @@ si_waitpid(cl_object pid, cl_object wait)
ecl_enable_interrupts_env(the_env);
#else
int code_int, error;
error = waitpid(ecl_to_fix(pid), &code_int, Null(wait)? WNOHANG : 0);
if (Null(wait))
error = waitpid(ecl_to_fix(pid), &code_int, WNOHANG | WUNTRACED | WCONTINUED);
else
error = waitpid(ecl_to_fix(pid), &code_int, WUNTRACED | WCONTINUED);
if (error < 0) {
if (errno == EINTR) {
status = @':abort';
@ -199,6 +204,9 @@ si_waitpid(cl_object pid, cl_object wait)
} else if (WIFSTOPPED(code_int)) {
status = @':stopped';
code = ecl_make_fixnum(WSTOPSIG(code_int));
} else if (WIFCONTINUED(code_int)) {
status = @':resumed';
code = ecl_make_fixnum(SIGCONT);
} else {
status = @':running';
code = ECL_NIL;

View file

@ -50,13 +50,14 @@
(ext:external-process-wait external-process nil)
(values status (external-process-%code external-process)))))
;;; ---------------------------------------------------------------------------
;;; si:waitpid -> (values status code pid)
;;; ---------------------------------------------------------------------------
;;; nochg :: (values nil nil nil)
;;; error :: (values (member :abort :error) nil nil)
;;; chang :: (values (member :exited :signalled :stopped :running) code pid)
;;; ---------------------------------------------------------------------------
;;; ---------------------------------------------------------------------
;;; si:waitpid -> (values status code pid)
;;; ---------------------------------------------------------------------
;;; no change :: (values nil nil nil)
;;; error :: (values (member :abort :error) nil nil)
;;; finished :: (values (member :exited :signalled) code pid)
;;; running :: (values (member :stopped :resumed :running) code pid)
;;; ---------------------------------------------------------------------
(defun external-process-wait (process &optional wait)
(let ((pid (external-process-pid process)))
(when pid
@ -68,7 +69,7 @@
(external-process-pid process) nil
(external-process-%status process) status
(external-process-%code process) code)))
((:stopped :running)
((:stopped :resumed :running)
(setf (external-process-%status process) status
(external-process-%code process) code))
((nil) #| wait was nil and process didn't change |#)))))