* Support for (system '("echo" "foo" "bar")) @ 2003-10-28 21:15 Rob Browning 2003-10-28 22:13 ` Paul Jarc ` (2 more replies) 0 siblings, 3 replies; 34+ messages in thread From: Rob Browning @ 2003-10-28 21:15 UTC (permalink / raw) I've just finished adding support for calling (system cmd) with a list argument. This causes it to use fork/execlp/waitpid nstead of calling underlying OS's system() function. This should be safer in cases where it's acceptable because it avoids /bin/sh interpretation and the attendant risks like sneaky IFS settings, unexpected expansions, etc. This idea was borrowed from perl, and seems fairly useful, but I wanted to see if there were any substantial objections before I commit. I suppose if this addition is acceptable, I should probably also see about doing something similar to open-*-pipe. Also, if people don't like this approach, perhaps there's some alternate (and more suitable) way to accomplish something similar, i.e. making it easy to more safely execute a sub-process when you don't need shell interpolation. -- Rob Browning rlb @defaultvalue.org and @debian.org; previously @cs.utexas.edu GPG starting 2002-11-03 = 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-28 21:15 Support for (system '("echo" "foo" "bar")) Rob Browning @ 2003-10-28 22:13 ` Paul Jarc 2003-10-29 7:58 ` tomas 2003-10-29 13:58 ` Greg Troxel 2 siblings, 0 replies; 34+ messages in thread From: Paul Jarc @ 2003-10-28 22:13 UTC (permalink / raw) Rob Browning <rlb@defaultvalue.org> wrote: > I've just finished adding support for calling (system cmd) with a list > argument. That would certainly be useful. FWIW, I have a set of related functions in run.scm in my prjlibs package: <URL:http://multivac.cwru.edu./prjlibs/> paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-28 21:15 Support for (system '("echo" "foo" "bar")) Rob Browning 2003-10-28 22:13 ` Paul Jarc @ 2003-10-29 7:58 ` tomas 2003-10-29 13:58 ` Greg Troxel 2 siblings, 0 replies; 34+ messages in thread From: tomas @ 2003-10-29 7:58 UTC (permalink / raw) Cc: guile-devel On Tue, Oct 28, 2003 at 03:15:26PM -0600, Rob Browning wrote: > > I've just finished adding support for calling (system cmd) with a list [...] > This idea was borrowed from perl, [...] If I get you right, you duplicate Perl's magic: when the arg is a singleton, use system() (with all the shell implications), when it's a list use execlp etc. While I have no issues with that (on the contrary, I think those things are quite handy in a scripting tool!), it ``sticks out'' a bit in Scheme. I'd expect `system' to be system(), and a function by another name to do the magic you describe. Why not system* or somesuch? (doing the single-element/several-element magic). If I got you right, that is. Regards -- tomas _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-28 21:15 Support for (system '("echo" "foo" "bar")) Rob Browning 2003-10-28 22:13 ` Paul Jarc 2003-10-29 7:58 ` tomas @ 2003-10-29 13:58 ` Greg Troxel 2003-10-29 14:04 ` Rob Browning 2003-10-30 20:09 ` Kevin Ryde 2 siblings, 2 replies; 34+ messages in thread From: Greg Troxel @ 2003-10-29 13:58 UTC (permalink / raw) Cc: guile-devel This violates the Principle of Least Astonishment. In guile we have a lot of procedures that are essentially just the 'obvious' scheme-wrapped versions of system calls and libc functions. system(3) (on NetBSD, which claimes conformance with ANSI X3.159-1989 (``ANSI C'') and IEEE Std 1003.2-1992 (``POSIX.2'')), is specified to use sh(1). POLA to me says that system with a list of strings would append them with spaces and then behave as if it had been called with that single string. This means /bin/sh, with globbing, file redirection, and multiple commands, not the simpler exec treatment. That said, a procedure to encapsulate the safer fork/exec/wait process would be very nice. So IMHO another name is warranted, and system* as already suggested seems good, since it hints that it isn't really system(3), but something else that is similar. Also, it might be nice to have environments with system* but not system (as a kind of 'safe environment'). A good case can be made that system(3) should not be used, except perhaps with constant strings - certainly not with unchecked user input. Is it important/useful to you to have the extended functionality have the same name? -- Greg Troxel <gdt@ir.bbn.com> _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-29 13:58 ` Greg Troxel @ 2003-10-29 14:04 ` Rob Browning 2003-10-29 16:15 ` Marius Vollmer 2003-10-30 20:09 ` Kevin Ryde 1 sibling, 1 reply; 34+ messages in thread From: Rob Browning @ 2003-10-29 14:04 UTC (permalink / raw) Cc: guile-devel Greg Troxel <gdt@ir.bbn.com> writes: > Is it important/useful to you to have the extended functionality have > the same name? Nope, system* would be perfectly fine with me too. -- Rob Browning rlb @defaultvalue.org and @debian.org; previously @cs.utexas.edu GPG starting 2002-11-03 = 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-29 14:04 ` Rob Browning @ 2003-10-29 16:15 ` Marius Vollmer 2003-10-29 18:13 ` Rob Browning 0 siblings, 1 reply; 34+ messages in thread From: Marius Vollmer @ 2003-10-29 16:15 UTC (permalink / raw) Cc: guile-devel, Greg Troxel Rob Browning <rlb@defaultvalue.org> writes: > Nope, system* would be perfectly fine with me too. That's what I prefer as well. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-29 16:15 ` Marius Vollmer @ 2003-10-29 18:13 ` Rob Browning 2003-10-29 22:32 ` Paul Jarc 2003-10-30 1:41 ` Alex Shinn 0 siblings, 2 replies; 34+ messages in thread From: Rob Browning @ 2003-10-29 18:13 UTC (permalink / raw) Cc: guile-devel, Greg Troxel Marius Vollmer <mvo@zagadka.de> writes: >> Nope, system* would be perfectly fine with me too. > > That's what I prefer as well. So would we want (system* . args) or (system* arg-list)? What are guile's argument count limitations? (Suppose the underlying OS's could be relevant as well...) -- Rob Browning rlb @defaultvalue.org and @debian.org; previously @cs.utexas.edu GPG starting 2002-11-03 = 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-29 18:13 ` Rob Browning @ 2003-10-29 22:32 ` Paul Jarc 2003-10-30 1:41 ` Alex Shinn 1 sibling, 0 replies; 34+ messages in thread From: Paul Jarc @ 2003-10-29 22:32 UTC (permalink / raw) Cc: guile-devel, Marius Vollmer, Greg Troxel Rob Browning <rlb@defaultvalue.org> wrote: > So would we want (system* . args) or (system* arg-list)? I like (system* arg-list). > What are guile's argument count limitations? (Suppose the underlying > OS's could be relevant as well...) If the caller exceeds the OS limit, execve will fail, and we'll get a system-error exception, won't we? Or is that not what you're talking about? paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-29 18:13 ` Rob Browning 2003-10-29 22:32 ` Paul Jarc @ 2003-10-30 1:41 ` Alex Shinn 2003-10-30 10:31 ` tomas 1 sibling, 1 reply; 34+ messages in thread From: Alex Shinn @ 2003-10-30 1:41 UTC (permalink / raw) At Wed, 29 Oct 2003 12:13:11 -0600, Rob Browning wrote: > > Marius Vollmer <mvo@zagadka.de> writes: > > >> Nope, system* would be perfectly fine with me too. > > > > That's what I prefer as well. > > So would we want (system* . args) or (system* arg-list)? FWIW, MzScheme made the same choice of the name system* and uses (system* . args) Chicken uses (system* fmt . args) => (system (apply format fmt args)) -- Alex _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-30 1:41 ` Alex Shinn @ 2003-10-30 10:31 ` tomas 0 siblings, 0 replies; 34+ messages in thread From: tomas @ 2003-10-30 10:31 UTC (permalink / raw) Cc: guile-devel On Thu, Oct 30, 2003 at 10:41:05AM +0900, Alex Shinn wrote: > At Wed, 29 Oct 2003 12:13:11 -0600, Rob Browning wrote: > > > > Marius Vollmer <mvo@zagadka.de> writes: > > > > >> Nope, system* would be perfectly fine with me too. > > > > > > That's what I prefer as well. > > > > So would we want (system* . args) or (system* arg-list)? > > FWIW, MzScheme made the same choice of the name system* and uses > (system* . args) > > Chicken uses (system* fmt . args) => (system (apply format fmt args)) I'd prefer (systems . args) too, but I've stirred up enough already ;-) Cheers -- tomas _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-29 13:58 ` Greg Troxel 2003-10-29 14:04 ` Rob Browning @ 2003-10-30 20:09 ` Kevin Ryde 2003-10-31 5:51 ` Rob Browning 1 sibling, 1 reply; 34+ messages in thread From: Kevin Ryde @ 2003-10-30 20:09 UTC (permalink / raw) Greg Troxel <gdt@ir.bbn.com> writes: > > That said, a procedure to encapsulate the safer fork/exec/wait process > would be very nice. If it does a fork and exec then it could be called fork-exec :). The old DOS systems used to use "spawn" for that sort of thing I think (spawnl, spawnle, etc like the exec functions). Either way, if it can get the errno back to the parent when exec fails (and use _exit) then it'd be a nice improvement over a fork and exec one might write explicitly. (A close-on-exec pipe is a good way to do that.) _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-30 20:09 ` Kevin Ryde @ 2003-10-31 5:51 ` Rob Browning 2003-10-31 17:05 ` Paul Jarc 2003-10-31 20:19 ` Kevin Ryde 0 siblings, 2 replies; 34+ messages in thread From: Rob Browning @ 2003-10-31 5:51 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> writes: > If it does a fork and exec then it could be called fork-exec :). > > The old DOS systems used to use "spawn" for that sort of thing I think > (spawnl, spawnle, etc like the exec functions). > > Either way, if it can get the errno back to the parent when exec fails > (and use _exit) then it'd be a nice improvement over a fork and exec > one might write explicitly. (A close-on-exec pipe is a good way to do > that.) Right now I just have this first (quick) pass at (system* . args), which should provide access to errno via scm_execlp: { if (SCM_NULLP (cmds)) SCM_WRONG_TYPE_ARG (1, cmds); if (SCM_CONSP (cmds)) { // better be a list of strings, and we call exec. int pid = fork (); if (pid == -1) SCM_SYSERROR; else if (pid) { int wait_result; int status; SCM_SYSCALL (wait_result = waitpid (pid, &status, 0)); if (wait_result == -1) SCM_SYSERROR; return SCM_MAKINUM (0L + status); } else { scm_execlp (SCM_CAR(cmds), cmds); SCM_SYSERROR; /* not reached. */ return SCM_BOOL_F; } } else SCM_WRONG_TYPE_ARG (1, SCM_CAR (cmds)); } -- Rob Browning rlb @defaultvalue.org and @debian.org; previously @cs.utexas.edu GPG starting 2002-11-03 = 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 5:51 ` Rob Browning @ 2003-10-31 17:05 ` Paul Jarc 2003-10-31 17:47 ` Rob Browning 2003-10-31 20:19 ` Kevin Ryde 1 sibling, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 17:05 UTC (permalink / raw) Cc: guile-devel Rob Browning <rlb@defaultvalue.org> wrote: > { > if (SCM_NULLP (cmds)) > SCM_WRONG_TYPE_ARG (1, cmds); > > if (SCM_CONSP (cmds)) ... > else > SCM_WRONG_TYPE_ARG (1, SCM_CAR (cmds)); This doesn't look right - you're looking at (car cmds) when cmds is not a cons. How about: { if (! SCM_CONSP (cmds)) SCM_WRONG_TYPE_ARG (1, cmds); ... } That should catch the null case too. Or, to get the behavior Kevin described: (define (system* . args) (flush-all-ports) (let* ((p (pipe)) (pid (primitive-fork))) (if (zero? pid) (catch 'system-error (lambda () (close-port (car p)) (fcntl (cdr p) F_SETFD FD_CLOEXEC) (apply execlp (car args) args)) (lambda . exception (write exception (cdr p)) (force-output (cdr p)) (primitive-exit))) (begin (close-port (cdr p)) (let* ((exception (read (car p))) (status (cdr (waitpid pid)))) (close-port (car p)) (if (not (eof-object? exception)) (apply throw exception) status)))))) paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 17:05 ` Paul Jarc @ 2003-10-31 17:47 ` Rob Browning 2003-10-31 17:59 ` Paul Jarc 0 siblings, 1 reply; 34+ messages in thread From: Rob Browning @ 2003-10-31 17:47 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: >> SCM_WRONG_TYPE_ARG (1, SCM_CAR (cmds)); Oh, right. Good catch, that's a typo left over from a previous incarnation. > That should catch the null case too. Or, to get the behavior Kevin > described: Hmm, maybe that's better. > (lambda . exception > (write exception (cdr p)) > (force-output (cdr p)) > (primitive-exit))) Looks like maybe that should be (lambda exception ...). -- Rob Browning rlb @defaultvalue.org and @debian.org; previously @cs.utexas.edu GPG starting 2002-11-03 = 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 17:47 ` Rob Browning @ 2003-10-31 17:59 ` Paul Jarc 2003-10-31 20:15 ` Kevin Ryde 0 siblings, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 17:59 UTC (permalink / raw) Cc: guile-devel Rob Browning <rlb@defaultvalue.org> wrote: > prj@po.cwru.edu (Paul Jarc) writes: >> (lambda . exception >> (write exception (cdr p)) >> (force-output (cdr p)) >> (primitive-exit))) > > Looks like maybe that should be (lambda exception ...). Oops, right. Kevin also mentioned using _exit. I'm not sure why that would be important, but if it is, then we'd also need a primitive-_exit Scheme binding. paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 17:59 ` Paul Jarc @ 2003-10-31 20:15 ` Kevin Ryde 2003-10-31 20:31 ` Paul Jarc 2003-10-31 22:49 ` Jonathan Bartlett 0 siblings, 2 replies; 34+ messages in thread From: Kevin Ryde @ 2003-10-31 20:15 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: > > Oops, right. Kevin also mentioned using _exit. I'm not sure why that > would be important, When exiting due to an exec failure, you generally don't want to run atexit handlers or flush stdio buffers. Those things of course are not done if the exec succeeds. In particular in guile-gtk the gtk atexit handlers do some shutdowns on the X connection, rendering it unusable back in the parent. > but if it is, then we'd also need a primitive-_exit Scheme binding. There was a bug report requesting that, or that primitive-exit change to be _exit anyway. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 20:15 ` Kevin Ryde @ 2003-10-31 20:31 ` Paul Jarc 2003-10-31 21:00 ` Kevin Ryde 2003-10-31 22:49 ` Jonathan Bartlett 1 sibling, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 20:31 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> wrote: > prj@po.cwru.edu (Paul Jarc) writes: >> Oops, right. Kevin also mentioned using _exit. I'm not sure why that >> would be important, > > When exiting due to an exec failure, you generally don't want to run > atexit handlers or flush stdio buffers. Those things of course are > not done if the exec succeeds. Ok. My procedure uses flush-all-ports before the fork, but atexit could still be an issue. In this particular case, though, we don't need _exit; we can just do (raise SIGKILL). The parent ignores the exit status if an exception was passed back. paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 20:31 ` Paul Jarc @ 2003-10-31 21:00 ` Kevin Ryde 2003-10-31 21:18 ` Paul Jarc 0 siblings, 1 reply; 34+ messages in thread From: Kevin Ryde @ 2003-10-31 21:00 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: > > My procedure uses flush-all-ports before the fork, The current "system" function doesn't do that does it? Might want to omit it from this arglist style too. There shouldn't be a need to flush, provided the code in the child is nice and tight and won't accidentally do so there. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 21:00 ` Kevin Ryde @ 2003-10-31 21:18 ` Paul Jarc 2003-10-31 21:48 ` Kevin Ryde 0 siblings, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 21:18 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> wrote: > prj@po.cwru.edu (Paul Jarc) writes: >> My procedure uses flush-all-ports before the fork, > > The current "system" function doesn't do that does it? No. Maybe it should. > There shouldn't be a need to flush, provided the code in the child > is nice and tight and won't accidentally do so there. Suppose we write some data to a port, and then we lose all references to the port without having closed it. In this case, garbage collection will free the port, which means closing it, which means, flushing it. Is it possible to guarantee that the child will not trigger garbage collection? paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 21:18 ` Paul Jarc @ 2003-10-31 21:48 ` Kevin Ryde 2003-10-31 22:10 ` Paul Jarc 0 siblings, 1 reply; 34+ messages in thread From: Kevin Ryde @ 2003-10-31 21:48 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: > > Is it possible to guarantee that the child will not trigger garbage > collection? Probably not. A good reason to do it in C. (Though it could be argued that it ought to be possible to this sort of thing safely at the scheme level, somehow.) Incidentally, looking at glibc sysdeps/posix/system.c, it seems to ignore SIGINT and SIGQUIT in the parent while running the child. I'm not up with the standards or conventions on this, but for maximum compatibility I suppose a "system*" might like to do the same. (A spawn-only variant probably wouldn't want to.) _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 21:48 ` Kevin Ryde @ 2003-10-31 22:10 ` Paul Jarc 2003-10-31 22:26 ` Paul Jarc 2003-10-31 22:50 ` Kevin Ryde 0 siblings, 2 replies; 34+ messages in thread From: Paul Jarc @ 2003-10-31 22:10 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> wrote: > prj@po.cwru.edu (Paul Jarc) writes: >> Is it possible to guarantee that the child will not trigger garbage >> collection? > > Probably not. A good reason to do it in C. Even in C, avoiding garbage collection is probably impossible. At some level, the child has to allocate the argv array that will be passed to execve(). > (Though it could be argued that it ought to be possible to this sort > of thing safely at the scheme level, somehow.) I think my Scheme procedure is safe. > Incidentally, looking at glibc sysdeps/posix/system.c, it seems to > ignore SIGINT and SIGQUIT in the parent while running the child. I'm > not up with the standards or conventions on this, but for maximum > compatibility I suppose a "system*" might like to do the same. I believe that's geared toward applications running on a tty, with the assumption that if the user interrupts the child, the parent is supposed to keep running. This may or may not be what an application wants, so we should provide both varieties. Given system*/nowait as before, we can have (with whatever names): (define (system*/no-ignore-signals . args) (cdr (waitpid (apply system*/nowait args)))) (define (system*/ignore-signals . args) (let* ((pid (apply system*/nowait args)) (old-int (sigaction SIGINT SIG_IGN)) (old-quit (sigaction SIGQUIT SIG_IGN)) (status (cdr (waitpid (apply system*/nowait args))))) (sigaction SIGINT (car old-int) (cdr old-int)) (sigaction SIGQUIT (car old-quit) (cdr old-quit)) status)) paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 22:10 ` Paul Jarc @ 2003-10-31 22:26 ` Paul Jarc 2003-10-31 22:42 ` Kevin Ryde 2003-10-31 22:50 ` Kevin Ryde 1 sibling, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 22:26 UTC (permalink / raw) I wrote: > (define (system*/ignore-signals . args) > (let* ((pid (apply system*/nowait args)) > (old-int (sigaction SIGINT SIG_IGN)) > (old-quit (sigaction SIGQUIT SIG_IGN)) > (status (cdr (waitpid (apply system*/nowait args))))) > (sigaction SIGINT (car old-int) (cdr old-int)) > (sigaction SIGQUIT (car old-quit) (cdr old-quit)) > status)) Oops. That should, of course, be: (define (system*/ignore-signals . args) (let* ((pid (apply system*/nowait args)) (old-int (sigaction SIGINT SIG_IGN)) (old-quit (sigaction SIGQUIT SIG_IGN)) (status (cdr (waitpid pid)))) (sigaction SIGINT (car old-int) (cdr old-int)) (sigaction SIGQUIT (car old-quit) (cdr old-quit)) status)) paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 22:26 ` Paul Jarc @ 2003-10-31 22:42 ` Kevin Ryde 0 siblings, 0 replies; 34+ messages in thread From: Kevin Ryde @ 2003-10-31 22:42 UTC (permalink / raw) [-- Attachment #1: Type: text/plain, Size: 455 bytes --] prj@po.cwru.edu (Paul Jarc) writes: > > (let* ((pid (apply system*/nowait args)) > (old-int (sigaction SIGINT SIG_IGN)) > (old-quit (sigaction SIGQUIT SIG_IGN)) In glibc the ignores are put on before the fork (and undone again in the child). Presumably to avoid a gap where the child is running but the parent is not yet ignoring. Oh, and SIGCHLD is blocked until after waitpid. (Code below, for those who don't have it handy.) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: system.c --] [-- Type: text/x-csrc, Size: 4152 bytes --] /* Copyright (C) 1991-1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include <stddef.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <signal.h> #include <sys/types.h> #include <errno.h> #ifndef HAVE_GNU_LD #define __environ environ #endif #define SHELL_PATH "/bin/sh" /* Path of the shell. */ #define SHELL_NAME "sh" /* Name to give it. */ /* Execute LINE as a shell command, returning its status. */ int __libc_system (const char *line) { int status, save; pid_t pid; struct sigaction sa, intr, quit; #ifndef WAITPID_CANNOT_BLOCK_SIGCHLD sigset_t block, omask; #endif if (line == NULL) /* Check that we have a command processor available. It might not be available after a chroot(), for example. */ return __libc_system ("exit 0") == 0; sa.sa_handler = SIG_IGN; sa.sa_flags = 0; __sigemptyset (&sa.sa_mask); if (__sigaction (SIGINT, &sa, &intr) < 0) return -1; if (__sigaction (SIGQUIT, &sa, &quit) < 0) { save = errno; (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); __set_errno (save); return -1; } #ifndef WAITPID_CANNOT_BLOCK_SIGCHLD /* SCO 3.2v4 has a bug where `waitpid' will never return if SIGCHLD is blocked. This makes it impossible for `system' to be implemented in compliance with POSIX.2-1992. They have acknowledged that this is a bug but I have not seen nor heard of any forthcoming fix. */ __sigemptyset (&block); __sigaddset (&block, SIGCHLD); save = errno; if (__sigprocmask (SIG_BLOCK, &block, &omask) < 0) { if (errno == ENOSYS) __set_errno (save); else { save = errno; (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); __set_errno (save); return -1; } } # define UNBLOCK __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) #else # define UNBLOCK 0 #endif pid = __fork (); if (pid == (pid_t) 0) { /* Child side. */ const char *new_argv[4]; new_argv[0] = SHELL_NAME; new_argv[1] = "-c"; new_argv[2] = line; new_argv[3] = NULL; /* Restore the signals. */ (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); (void) UNBLOCK; /* Exec the shell. */ (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ); _exit (127); } else if (pid < (pid_t) 0) /* The fork failed. */ status = -1; else /* Parent side. */ { #ifdef NO_WAITPID pid_t child; do { child = __wait (&status); if (child <= -1 && errno != EINTR) { status = -1; break; } /* Note that pid cannot be <= -1 and therefore the loop continues when __wait returned with EINTR. */ } while (child != pid); #else int n; do n = __waitpid (pid, &status, 0); while (n == -1 && errno == EINTR); if (n != pid) status = -1; #endif } save = errno; if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) | UNBLOCK) != 0) { if (errno == ENOSYS) __set_errno (save); else return -1; } return status; } weak_alias (__libc_system, system) [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 22:10 ` Paul Jarc 2003-10-31 22:26 ` Paul Jarc @ 2003-10-31 22:50 ` Kevin Ryde 2003-10-31 22:59 ` Paul Jarc 1 sibling, 1 reply; 34+ messages in thread From: Kevin Ryde @ 2003-10-31 22:50 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: > > At some level, the child has to allocate the argv array that will be > passed to execve(). Could do that in the parent, where any gc is certain to be safe. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 22:50 ` Kevin Ryde @ 2003-10-31 22:59 ` Paul Jarc 2003-10-31 23:25 ` Kevin Ryde 0 siblings, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 22:59 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> wrote: > prj@po.cwru.edu (Paul Jarc) writes: >> At some level, the child has to allocate the argv array that will be >> passed to execve(). > > Could do that in the parent, where any gc is certain to be safe. True, but is it worth the effort? What's the benefit supposed to be? And how sure are we that nothing else could trigger garbage collection (signal handlers, maybe)? paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 22:59 ` Paul Jarc @ 2003-10-31 23:25 ` Kevin Ryde 2003-10-31 23:34 ` Paul Jarc 0 siblings, 1 reply; 34+ messages in thread From: Kevin Ryde @ 2003-10-31 23:25 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: > > True, but is it worth the effort? What's the benefit supposed to be? Only what you said about gc'ed port closing doing something the child has no business touching. > (signal handlers, maybe) An ever present danger no doubt. (They go via asyncs don't they? Maybe call-with-blocked-asyncs around the fork.) I guess some of these matters (if they're really problems) should be outlined in the docs for primitive-fork. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 23:25 ` Kevin Ryde @ 2003-10-31 23:34 ` Paul Jarc 2003-11-02 21:13 ` Kevin Ryde 0 siblings, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 23:34 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> wrote: > prj@po.cwru.edu (Paul Jarc) writes: >> True, but is it worth the effort? What's the benefit supposed to be? > > Only what you said about gc'ed port closing doing something the child > has no business touching. I claim that my Scheme version, which uses flush-all-ports before the fork, and (raise SIGKILL) to terminate the child, does not suffer from any problems of that sort. Can you find any problems that it is vulnerable to? If not, what problem are we trying to solve by rewriting it in C? paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 23:34 ` Paul Jarc @ 2003-11-02 21:13 ` Kevin Ryde 2003-11-10 19:25 ` Paul Jarc 0 siblings, 1 reply; 34+ messages in thread From: Kevin Ryde @ 2003-11-02 21:13 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: > > I claim that my Scheme version, which uses flush-all-ports before the > fork, Oops, I was a bit slow on the uptake. That flushes unreferenced ports as well, of course. You'll probably still want to block SIGCHLD though (when it exists), the same as the main system() does. I think that's to stop a slack application handler possibly stealing the exit status, but I'm not too well up on the subtleties of sigchld. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-11-02 21:13 ` Kevin Ryde @ 2003-11-10 19:25 ` Paul Jarc 2003-12-16 23:45 ` Paul Jarc 0 siblings, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-11-10 19:25 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> wrote: > You'll probably still want to block SIGCHLD though (when it exists), > the same as the main system() does. That will require a Scheme binding for sigprocmask(). I'll give it a go if no one beats me to it. > I think that's to stop a slack application handler possibly stealing > the exit status, Sounds reasonable. paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-11-10 19:25 ` Paul Jarc @ 2003-12-16 23:45 ` Paul Jarc 0 siblings, 0 replies; 34+ messages in thread From: Paul Jarc @ 2003-12-16 23:45 UTC (permalink / raw) BTW, I've implemented the pass-the-error-back-to-the-parent thing in my prjlibs package at <URL:http://multivac.cwru.edu./prjlibs/>. (See call/child/wait in run.scm.) It's done in Scheme, and doesn't mess with signals. (I would like to mess with SIGCHLD, at least, but I'll have to come up with a patch to add sigprocmask first.) paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 20:15 ` Kevin Ryde 2003-10-31 20:31 ` Paul Jarc @ 2003-10-31 22:49 ` Jonathan Bartlett 1 sibling, 0 replies; 34+ messages in thread From: Jonathan Bartlett @ 2003-10-31 22:49 UTC (permalink / raw) Cc: guile-devel > When exiting due to an exec failure, you generally don't want to run > atexit handlers or flush stdio buffers. Those things of course are > not done if the exec succeeds. This is true for many forks - you don't want the child cleaning up file handles that are in use by the parent. For example, closing connections to databases et al. Jon _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 5:51 ` Rob Browning 2003-10-31 17:05 ` Paul Jarc @ 2003-10-31 20:19 ` Kevin Ryde 2003-10-31 20:37 ` Paul Jarc 1 sibling, 1 reply; 34+ messages in thread From: Kevin Ryde @ 2003-10-31 20:19 UTC (permalink / raw) Rob Browning <rlb@defaultvalue.org> writes: > > SCM_SYSCALL (wait_result = waitpid (pid, &status, 0)); As a suggestion, I think a variation that just returned the child pid would be nice (or threw an execption for an exec failure). _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 20:19 ` Kevin Ryde @ 2003-10-31 20:37 ` Paul Jarc 2003-10-31 21:02 ` Rob Browning 0 siblings, 1 reply; 34+ messages in thread From: Paul Jarc @ 2003-10-31 20:37 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> wrote: > As a suggestion, I think a variation that just returned the child pid > would be nice (or threw an execption for an exec failure). (define (system*/nowait . args) (flush-all-ports) (let* ((p (pipe)) (pid (primitive-fork))) (if (zero? pid) (catch 'system-error (lambda () (close-port (car p)) (fcntl (cdr p) F_SETFD FD_CLOEXEC) (apply execlp (car args) args)) (lambda exception (write exception (cdr p)) (force-output (cdr p)) (raise SIGKILL))) (begin (close-port (cdr p)) (let ((exception (read (car p)))) (close-port (car p)) (if (not (eof-object? exception)) (apply throw exception) pid)))))) I'd still prefer the argv list as a single Scheme argument, though, since it saves an "apply" when the list is dynamically constructed. paul _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Support for (system '("echo" "foo" "bar")) 2003-10-31 20:37 ` Paul Jarc @ 2003-10-31 21:02 ` Rob Browning 0 siblings, 0 replies; 34+ messages in thread From: Rob Browning @ 2003-10-31 21:02 UTC (permalink / raw) prj@po.cwru.edu (Paul Jarc) writes: > I'd still prefer the argv list as a single Scheme argument, though, > since it saves an "apply" when the list is dynamically constructed. Might well be too ugly, but we *could* have it accept either format. -- Rob Browning rlb @defaultvalue.org and @debian.org; previously @cs.utexas.edu GPG starting 2002-11-03 = 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2003-12-16 23:45 UTC | newest] Thread overview: 34+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2003-10-28 21:15 Support for (system '("echo" "foo" "bar")) Rob Browning 2003-10-28 22:13 ` Paul Jarc 2003-10-29 7:58 ` tomas 2003-10-29 13:58 ` Greg Troxel 2003-10-29 14:04 ` Rob Browning 2003-10-29 16:15 ` Marius Vollmer 2003-10-29 18:13 ` Rob Browning 2003-10-29 22:32 ` Paul Jarc 2003-10-30 1:41 ` Alex Shinn 2003-10-30 10:31 ` tomas 2003-10-30 20:09 ` Kevin Ryde 2003-10-31 5:51 ` Rob Browning 2003-10-31 17:05 ` Paul Jarc 2003-10-31 17:47 ` Rob Browning 2003-10-31 17:59 ` Paul Jarc 2003-10-31 20:15 ` Kevin Ryde 2003-10-31 20:31 ` Paul Jarc 2003-10-31 21:00 ` Kevin Ryde 2003-10-31 21:18 ` Paul Jarc 2003-10-31 21:48 ` Kevin Ryde 2003-10-31 22:10 ` Paul Jarc 2003-10-31 22:26 ` Paul Jarc 2003-10-31 22:42 ` Kevin Ryde 2003-10-31 22:50 ` Kevin Ryde 2003-10-31 22:59 ` Paul Jarc 2003-10-31 23:25 ` Kevin Ryde 2003-10-31 23:34 ` Paul Jarc 2003-11-02 21:13 ` Kevin Ryde 2003-11-10 19:25 ` Paul Jarc 2003-12-16 23:45 ` Paul Jarc 2003-10-31 22:49 ` Jonathan Bartlett 2003-10-31 20:19 ` Kevin Ryde 2003-10-31 20:37 ` Paul Jarc 2003-10-31 21:02 ` Rob Browning
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).