Code Monkey home page Code Monkey logo

external-program's Introduction

EXTERNAL-PROGRAM enables running programs outside the Lisp process. It is an attempt to make the RUN-PROGRAM functionality in implementations like SBCL and CCL as portable as possible without sacrificing much in the way of power.

Note: This library is available via Quicklisp.

Here are some of the differences:

  • splits START (async) and RUN (sync) into two separate functions, rather than using a single function with a WAIT parameter that changes the function's specification;
  • offers a REPLACE-ENVIRONMENT-P parameter that indicates whether provided env vars should build on or replace the current environment.

Read the API documention for details. It’s a bit spartan, but should explain a lot.

Not all functionality is available on all platforms. EXTERNAL-PROGRAM provides warnings and errors when these limitations are encountered. But I'll try my best to work around them.

There is currently at least some support for:

  • Allegro (blocking only)
  • Armed Bear (blocking only)
  • CLisp
  • Clozure CL (née OpenMCL)
  • CMUCL
  • ECL
  • LispWorks
  • SBCL

In addition to some implementations only providing blocking calls, some don’t use $PATH – the ones that don’t won’t find bareword commands, you’ll need to use a pathname.

external-program's People

Contributors

daewok avatar epipping avatar filonenko-mikhail avatar foretspaisibles avatar hraban avatar luismbo avatar renovate[bot] avatar rwiker avatar sellout avatar u-u-h avatar wzrdsappr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

external-program's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

None detected


  • Check this box to trigger a request for Renovate to run again on this repository

Support for pty

SBCL has a :pty keyword for run-program, which make it possible to talk to other REPL like program possible, for example, python, psql, sqlite, etc. Although it's not in CCL and ECL, but maybe possible implement in a similar way by calling c functions fork, execvp like SBCL does.
I think it's a useful feature. It's of course possible to use these interpreter's low level c library, but need a lot of effort, like library RCL, LTK). Talk to interpreter to directly is a less efficient but quick way. Is this task possible (run a external python, talk to it interactively in CL) in current external-program in current external-program? Thank you

Make tests work on Windows

Currently tests call things like cd and which, which don’t exist on Windows. Need to make them more portable.

Environment doesn't support SSH_AUTH_SOCK=/unix/path

There is presently no way to pass environment variables such as SSH_AUTH_SOCK=/tmp/ssh-BLAH/. They are upcased when symbols, if passed as |/tmp/ssh-BLAH/| the pipes remain, etc. Perhaps I'm missing something simple...

Fix for external-program:run

I was using run to start gnuplot, which returned an io stream, and not a numeric value. In the cond statement at the end of run, the (< result 0) test was signaling an error, since a stream is not a numeric value.

I had to add a clause (not (null result)) before the (< result 0) to circumvent this.

This duplicates the (t ...) clause, but I did not want to move it from its current spot.

notes after trying to use external-program

Hello.

I once tried to use external-program, and collected some notes about problems I saw.

  • sb-ext:run-program on Windows doesn't accept :environment nor :env keyword arguments.
    external-program always passes the :environment argument to sb-ext:run-program,
    therefore external-program:run always fails on SBCL Windows with an error about
    illegal keyword passed to sb-ext:run-program, event if we don't pass :environment to
    external-program:run

  • Quoting the program arguments against shell interpretation is
    inconsistent.

    For example on CCL (external-program:run "some-other-lisp.exe" '("--eval" "(+ 1 2)"))
    doesn't work because of spaces in the expression;
    ''("--eval" ""(+ 1 2)"") works.

    But on CLISP quoting is not necessary, and
    (external-program:run "some-lisp" '("--eval" "(+ 1 2)"))
    works fine.

    The issue is complicated by the fact that external-program docs do not
    specify how arguments are interpreted.

    I may be wrong, but I find more convenient the approach similar
    to Unix' execve, i.e. arguments are just strings which are not interpreted
    anyhow and work as if they just passed as the argv parameter of the called
    program function main (i..e the how it works on CLISP now).

  • On CLISP the method external-program:run
    incorrectly interprets the exit status
    returned by CLISP function ext:run-program.

    The rules of ext:run-program:
    case 1
    if :input or :output were T,
    than ext:run-program return value
    NIL means the program exited successfully
    with status 0. Othersise ext:run-program
    returns a positive integer.
    case 2
    if :stream was specified for both
    input and output, 3 streams are returned.

    The external-program:run method interprets
    the ext:run-program return value absolutely
    differently.

  • (minor) the API doc is not very clear what is the format
    of exit status returned by external-program:run.
    My assumption is that it should be in the same form
    as returned by external-program:process-status.

Note, none of these issues is real blocker for me; just reporting here for your information.

Windows compatibility

In SBCL implementation external-program is looking for /usr/bin/env which is nonexistent in Windows.

Add support for CCL's :error-if-exited

The issue is outlined here: http://trac.clozure.com/ccl/ticket/1015

A short summary: If you signal a dead process with e.g. sbcl, nothing happens. If you do it with ccl, you get a simple-error. Checking if the process is alive and killing it only then creates a race condition. Thus :error-if-exited was added, which defaults to t.

I do not know how other implementations (than SBCL and CCL) handle this matter.

Strange issue with macOS 10.15. and broken pipe

I am sorry for bothering you but I just don't know where to ask. I am using some foreign CL code to create an animation using external-program to pipe cairo surfaces into an ffmpeg process which was started using external-program:start.

While on macOS 10.13. everything is working on 10.15. I get the following error:

Couldn't write to #<SB-SYS:FD-STREAM for "descriptor 15" {1001A962D3}>:
  Broken pipe

I am using SBCL 1.5.9. on both machines, ffmpeg is installed properly via macports and the process is :RUNNING according to external-program:process-status. I assume, that there was some change in the inter process communication or security settings but wasn't able to debug this further. Is anyone using macOS here and can confirm the issue?

Any hint will be gratefully appreciated!

reformat-environment and make-shell-string do not fit together

(external-program::make-shell-string "ls" '(".") '(("PATH" . "")) nil)

yields

    0[11]: (EXTERNAL-PROGRAM::MAKE-SHELL-STRING "ls" (".") (("PATH" . ""))  NIL)
    1[11]: (EXTERNAL-PROGRAM::REFORMAT-ENVIRONMENT (("PATH" . "")))
    1[11]: returned ("PATH=''")
    0[11]: returned " #<Printer Error, obj=#x10000000af9: `\"PATH=''\"' is not of the expected type `LIST'>"

because REFORMAT-ENVIRONMENT flattens the list of conses.

RUN on ACL (and probably abcl) breaks on this; for lispworks the environment is never passed down, so it is not affected. Other backends do not use make-shell-string.

CMUCL: external-program:start Function with declared result type NIL returned:

cmu-20c_release-20c__20c_unicode_-linux-x86.
quicklisp 2012-07-03

  • (external-program:start "echo" '("hello"))

Function with declared result type NIL returned:
(PCL:FAST-METHOD EXTERNAL-PROGRAM:START (T T))
[Condition of type KERNEL:SIMPLE-CONTROL-ERROR]

Restarts:
0: [ABORT] Return to Top-Level.

Debug (type H for help)

("LAMBDA (.KEYARGS-START. .VALID-KEYS. G3150)" # #
"echo" ("hello") ...)
Source: (FUNCALL (THE FUNCTION #'(PCL:FAST-METHOD EXTERNAL-PROGRAM:START #))
(PCL::FAST-METHOD-CALL-PV-CELL #:G3150)
(PCL::FAST-METHOD-CALL-NEXT-METHOD-CALL #:G3150)
PCL::.ARG0.
...)

RUN on allegro does not handle stream input

On Allegro CL the RUN method does not obtain input from a stream
correctly. Just creating an echo stream does not work, one needs to
copy the data to the provided stream in the :input form of excl.osi:with-command-io.
Test:

(with-input-from-string (s (format nil "Print~%2 lines~%")) 
 (external-program:run "cat" '() :input s :output T :error T))

does not print anything.

Feature request: Add a function to wait for processes

I can already run a program asynchronously (yay!). But then how do I know when it's done? (without resorting to a loop in which I constantly call process-status)

There are mechanisms in place for this kind of task, like sb-ext:process-wait for sbcl. A look at the source of UIOP in https://github.com/fare/asdf/blob/master/uiop/run-program.lisp (where this logic is made available as part of the function %wait-process-result, but not a separate function) suggests that the following should work:

  #+clozure (ccl::external-process-wait process)
  #+(or cmu scl) (ext:process-wait process)
  #+sbcl (sb-ext:process-wait process)

Unexpected redefinitions

I have external-program installed via quicklisp. If I load it via ASDF, I get:

% sbcl --eval "(asdf:operate 'asdf:load-op :external-program)" --quit
This is SBCL 1.3.7.nixos, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
WARNING:
   redefining RUN (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>
                   #<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING:
   redefining START (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>
                     #<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING:
   redefining PROCESS-INPUT-STREAM (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING:
   redefining PROCESS-OUTPUT-STREAM (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING:
   redefining PROCESS-ERROR-STREAM (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING:
   redefining PROCESS-STATUS (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING:
   redefining PROCESS-ID (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
WARNING:
   redefining PROCESS-P (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>) in DEFMETHOD
% 

This does not happen for other packages (except for those that depend on external-program). Is something wrong with the build system perhaps?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.