Prev: anomalies in capitalization in String functions
Next: A couple of questions on lisp compiler/optimization art
From: Teemu Likonen on 2 Mar 2010 13:23 I'm studying streams and CLISP's EXT:RUN-PROGRAM. As an exercise I wrote a function which runs an external program and returns its output as a list of strings. Each output line gets its own string in the list. The function works but I want to make sure I'm doing it correctly. Here it is: (defun my-command (command &optional arguments) (let ((stream (ext:run-program command :arguments arguments :output :stream :wait t))) (unwind-protect (loop for line = (read-line stream nil) while line collect line) (when (streamp stream) (close stream))))) A stupid example: (my-command "/usr/bin/printf" '("Line %d\\n" "1" "2" "3")) => ("Line 1" "Line 2" "Line 3") My questions: What happens if stream is not closed? Is UNWIND-PROTECT a good way handle closing a stream?
From: vanekl on 2 Mar 2010 14:30 On Mar 2, 1:23 pm, Teemu Likonen <tliko...(a)iki.fi> wrote: > I'm studying streams and CLISP's EXT:RUN-PROGRAM. As an exercise I wrote > a function which runs an external program and returns its output as a > list of strings. Each output line gets its own string in the list. The > function works but I want to make sure I'm doing it correctly. Here it > is: > > (defun my-command (command &optional arguments) > (let ((stream (ext:run-program command :arguments arguments > :output :stream :wait t))) > (unwind-protect > (loop for line = (read-line stream nil) > while line > collect line) > (when (streamp stream) > (close stream))))) > > A stupid example: > > (my-command "/usr/bin/printf" '("Line %d\\n" "1" "2" "3")) > => ("Line 1" "Line 2" "Line 3") > > My questions: What happens if stream is not closed? Is UNWIND-PROTECT a > good way handle closing a stream? 1. 'with-open-stream' should take care of closing the stream for you. 2. Something similar to this was discussed just two or three days ago in this group. You may want to reference that thread ('RUN-PROGRAM' is in title). 3. You could you 'ps' and 'lsof' to see for yourself what happens if the stream is prematurely aborted (if anything). On debian/sbcl: # install admin programs sudo apt-get install procps sudo apt-get install lsof # list open files lsof -p `pgrep sbcl` # list your printf process (if it's still open) ps -ef | grep printf
From: Pascal J. Bourguignon on 2 Mar 2010 16:06 Teemu Likonen <tlikonen(a)iki.fi> writes: > I'm studying streams and CLISP's EXT:RUN-PROGRAM. As an exercise I wrote > a function which runs an external program and returns its output as a > list of strings. Each output line gets its own string in the list. The > function works but I want to make sure I'm doing it correctly. Here it > is: > > > (defun my-command (command &optional arguments) > (let ((stream (ext:run-program command :arguments arguments > :output :stream :wait t))) > (unwind-protect > (loop for line = (read-line stream nil) > while line > collect line) > (when (streamp stream) > (close stream))))) > > A stupid example: > > (my-command "/usr/bin/printf" '("Line %d\\n" "1" "2" "3")) > => ("Line 1" "Line 2" "Line 3") > > > My questions: What happens if stream is not closed? Is UNWIND-PROTECT a > good way handle closing a stream? Subject to verification, ISTR that :wait t will make clisp wait for the process to exit before returning from run-program. Therefore if the process outputs more than a buffer worth, it will deadlock. When you want to process the output of a process, you should fork it without waiting on it. So I would write it as: (defun run-command (command &optional arguments) (with-open-stream (pipe (ext:run-program command :arguments arguments :output :stream :wait nil)) (loop :for line = (read-line pipe nil nil) :while line :collect line))) However it looks like :wait is ignored when you specify :input or :output streams. -- __Pascal Bourguignon__ http://www.informatimago.com
From: Teemu Likonen on 3 Mar 2010 01:54
* 2010-03-02 11:30 (-0800), vanekl wrote: > 1. 'with-open-stream' should take care of closing the stream for you. Ah, thanks. There seem to be many WITH-EVERYTHING-IMPLEMENTED-ALREADY macros in Common Lisp. |