|
From: | Lassi Kortela |
Subject: | Re: [Chicken-users] Interaction of subprocess and condition handling |
Date: | Fri, 19 Jul 2019 23:46:51 +0300 |
User-agent: | Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 |
Thanks for helping out :)
*Normally*, closing both ports returned from "process" will do a waitpid(2) (or the equivalent) and throw an exception if WIFEXITED returns false.
So WIFEXITED checks for a normal exit (instead of being terminated by signal, e.g. segfault or kill -9). But what if the execve() itself fails so the forked child process doesn't get the chance to replace the Chicken process image with the other program that it was asked to start?
When coding in C, the forked child process is usually programmed to call _exit() in case the execve() fails. But _exit() causes a normal exit of the child process - it doesn't terminate abnormally by signal. This is tricky for the parent process, which can't tell the difference between a failed execve() and a successful execve() of another program that then chooses to exit with a non-zero exit code.
I'm under the impression that a special exit code (arbitrarily chosen magic number, often 126?) is usually reserved to indicate a failed execve(). What does Chicken do - if execve() fails, will the lingering Chicken child process call _exit() with a particular exit code to notify the parent? My test suggests that the child will keep running Scheme code instead of exiting. But I may have messed something up myself.
Sorry for not posting the verbatim source code of a program that reproduces the bug. Here is one:
;;;; csc -R r7rs test.scm && ./test (import (r7rs) (chicken process) (chicken process-context posix)) (define (show . xs) (for-each display xs) (newline)) (define (demo) (receive (from-child to-child child) (condition-case (process "does-not-exist-so-execve-will-fail" '()) (_ () (show "exception handler entered in pid " (current-process-id)) (values #f #f #f))) (and child (let ((output (read-string #f from-child))) (close-port from-child) (close-port to-child) output)))) (show "subprocess result = " (demo)) (show "current-process-id = " (current-process-id))
[Prev in Thread] | Current Thread | [Next in Thread] |