From: Mikko Heikelä
Subject: IPC with pipes
Date: 
Message-ID: <rFbsa.179$D3.167@read3.inet.fi>
Hello,

Is there a way to spawn an arbitrary program and talk to it's standard 
input from a common lisp program? I am using CMUCL on linux. The 
solution doesn't have to be portable initially. To give a better idea of 
what I'm trying to do, below is perl code that I'd like to mimic.

#!/usr/bin/perl

use IO::Handle;

$program = "/usr/bin/gnuplot";
$pid = open(CHILD_INPUT, "|-");

# The above both forks and connects the pipe CHILD_INPUT to
# the childrens stdio.

$SIG{ALRM} = sub { die "whoops, $program pipe broke" };

CHILD_INPUT->autoflush(1);

if ($pid) {  # parent

     print CHILD_INPUT "plot x\n";
     sleep 3;
     print CHILD_INPUT "quit\n";
     close(CHILD_INPUT) || warn "kid exited $?";
}
else {     # child
     exec($program)
	|| die "can't exec program: $!";
     # NOTREACHED
}

I have tried to do the thing using CMUCL's unix package. Using it I can 
create a pipe and fork a child process. The problem is that I can't find 
a way to make the pipe to be the child processes standard input that 
would last across a call to execve.

Thanks in advance

   Mikko

From: Alexey Dejneka
Subject: Re: IPC with pipes
Date: 
Message-ID: <m34r4ek2v3.fsf@comail.ru>
Mikko Heikel� <············@mappi.helsinki.fi> writes:

> Hello,
> 
> Is there a way to spawn an arbitrary program and talk to it's standard
> input from a common lisp program? I am using CMUCL on linux. The
> solution doesn't have to be portable initially.

(let* ((gp (run-program "/usr/bin/gnuplot" nil
                        :input :stream
                        :wait nil))
         (input (process-input gp)))
    (format input "plot x~%")
    (finish-output input)
    (sleep 3)
    (format input "quit~%")
    (finish-output input)
    (process-wait gp))

-- 
Regards,
Alexey Dejneka

"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer
From: Tim Daly, Jr.
Subject: Re: IPC with pipes
Date: 
Message-ID: <8765oum5fd.fsf@tenkan.org>
Mikko Heikel� <············@mappi.helsinki.fi> writes:

> Hello,
> 
> Is there a way to spawn an arbitrary program and talk to it's standard
> input from a common lisp program? I am using CMUCL on linux. The
> solution doesn't have to be portable initially. To give a better idea
> of what I'm trying to do, below is perl code that I'd like to mimic.
<perl code>
> I have tried to do the thing using CMUCL's unix package. Using it I
> can create a pipe and fork a child process. The problem is that I
> can't find a way to make the pipe to be the child processes standard
> input that would last across a call to execve.
> 
> Thanks in advance
> 
>    Mikko
> 

If I understand correctly, you just want to be able to print to the
process' stdin, and read from its stdout?  This is what I do, in
CMUCL :


;see cat run
(let ((process (ext:run-program "cat" nil
				:wait nil
				:input :stream
				:output :stream
				:error t)))
  ;print foo at it
  (format (process-input process) "foo~%")
  ;flush the stream's buffer
  (finish-output (process-input process))
  ;read what cat had to say
  (princ (read-line (process-output process)))
  ;drown cat
  (ext:process-close process))


                => foo

HTH,
-Tim

-- 
From: Raymond Wiker
Subject: Re: IPC with pipes
Date: 
Message-ID: <86ptn1yeaq.fsf@raw.grenland.fast.no>
···@tenkan.org (Tim Daly, Jr.) writes:

> Mikko Heikel� <············@mappi.helsinki.fi> writes:
> 
> > Hello,
> > 
> > Is there a way to spawn an arbitrary program and talk to it's standard
> > input from a common lisp program? I am using CMUCL on linux. The
> > solution doesn't have to be portable initially. To give a better idea
> > of what I'm trying to do, below is perl code that I'd like to mimic.
> <perl code>
> > I have tried to do the thing using CMUCL's unix package. Using it I
> > can create a pipe and fork a child process. The problem is that I
> > can't find a way to make the pipe to be the child processes standard
> > input that would last across a call to execve.
> > 
> > Thanks in advance
> > 
> >    Mikko
> > 
> 
> If I understand correctly, you just want to be able to print to the
> process' stdin, and read from its stdout?  This is what I do, in
> CMUCL :
> 
> 
> ;see cat run
> (let ((process (ext:run-program "cat" nil
> 				:wait nil
> 				:input :stream
> 				:output :stream
> 				:error t)))
>   ;print foo at it
>   (format (process-input process) "foo~%")
>   ;flush the stream's buffer
>   (finish-output (process-input process))
>   ;read what cat had to say
>   (princ (read-line (process-output process)))
>   ;drown cat
>   (ext:process-close process))
> 
> 
>                 => foo

        You may have to add a loop around this - otherwise, the output
buffers of the called program will fill up, and it will wait for these
to empty before processing more input.

        You can verify this by sending, say, 40960 characters to cat
instead of just 4 :-)

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/