extending uiop/run-program

Faré fahree at gmail.com
Sun Jul 31 19:56:48 UTC 2016


Dear Elias,

this kind of functionality is welcome in UIOP. However, the
responsibility is yours to ensure that it will work on every
implementation on every platform. Please make reasonably sure it works
before you submit the patch. You may contact various vendors for a
test license as appropriate.

Note that there are several run-program style libraries around. If
you're going to do this, I suggest you look at each and every of these
libraries (notably executor and external-program) and make sure you
have at least feature-parity and implementation-parity with them. Also
make sure that you explicitly raise an error on unsupported
implementations, at the start of every function that doesn't support
them.

Also, if you are going to support these interface, you can graduate
them out of % namespace (but keep the % name around for backward
compatibility for a year or two).

Would you be interested in becoming official maintainer for UIOP?

—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
The trouble with opportunity is that it always comes disguised as hard work.
               — Herbert V. Prochnow


On Sun, Jul 31, 2016 at 1:57 PM, Elias Pipping <pipping.elias at icloud.com> wrote:
> Dear list,
>
> I’ve recently made the switch from external-program to uiop/run-program::%run-program for asynchronous process execution after I read that its interface should remain essentially stable. I’ve also had to use uiop/run-program::%wait-process-result although I’m not sure if its interface in turn as subject to the same close-to-guarantee. So far the two are serving me well and I’m not looking back.
>
> I ended up writing two functions that I needed because uiop/run-program does not currently provide such functionality while external-program did.
>
> I’m sometimes interested in testing whether a process is running; I use the following function for that:
>
> (defun process-running-p (process-info)
>  (let ((process (getf process-info :process)))
>    #+clozure (eq :running (ccl:external-process-status process))
>    #+cmu (eq :running (ext:process-status process))
>    #+ecl (eq :running (ext:external-process-status process))
>    #+mkcl (eq :running (mk-ext:process-status process))
>    #+sbcl (eq :running (sb-ext:process-status process))
>    #-(or clozure cmu ecl mkcl sbcl)
>    (error "Cannot determine if a process is running.")))
>
> Maybe something like this could be incorporated into UIOP as well? (or a function that returns the process status, or a function that checks that a process is alive, etc.)
>
> Sometimes, I also want to terminate a process before it finishes. To that end, I use the following:
>
> (alexandria:define-constant +kill-signal+ 9 :test #'=)
> (alexandria:define-constant +term-signal+ 15 :test #'=)
>
> (defun terminate-process (process-info &key force)
>  (let ((process (getf process-info :process))
>        (sig (if force +kill-signal+ +term-signal+)))
>    #+allegro (progn ; FIXME: untested
>                #+os-unix (excl.osi:kill process sig)
>                #+os-windows (uiop/run-program::%run-program
>                              (format nil "taskkill /f /pid ~a" process)
>                              :wait t)
>                #-(or os-unix os-windows) (error "Cannot terminate a process.")
>                (sys:reap-os-subprocess :pid process))
>    #+clozure (ccl:signal-external-process process sig :error-if-exited nil)
>    #+cmu (ext:process-kill process sig)
>    #+sbcl (sb-ext:process-kill process sig)
>    #+scl (ext:process-kill process sig) ; FIXME: untested
>    #+mkcl (mk-ext:terminate-process process :force force)
>    #-(or allegro clozure cmu mkcl sbcl) (error "Cannot terminate a process.")))
>
> This is a special case of a more general signalling facility that many lisps have but which from my understanding can only work on unix. mkcl does not provide such a facility but it does provide a terminate-process function that works on windows, too. The Allegro CL documentation states that one should run (format nil "taskkill /f /pid ~a" process) on such platforms, which could also be done with other lisps, assuming that the PID is known or can be extracted from the process. Maybe a function of this type could be incorporated into UIOP as well?
>
>
> Elias Pipping



More information about the asdf-devel mailing list