Subject: [clisp-list] Running CLISP as a Subprocess of Tcl

From: Daniel Ozick <[email-masked]>
Date: Wed Jan 9 13:58:04 2002

Hello Everyone,

We have a small GUI built in Tcl/Tk under Windows-NT and would like to run
CLISP as a child process to perform some computation.  Currently, we use
this architecture to run a C++ executable (Win32 console app) as a child
process of Tcl.  The Tcl code looks something like this:

set interface_pipe [open "|program" r+]

Through 'interface_pipe', we can send input to 'program' stdin and get
output from 'program' stdout.  When we try this with CLISP 2.27, however,
the following error message appears:

*** - Win32 error 5 (ERROR_ACCESS_DENIED): Access is denied.

Other clues: if we invoke CLISP via Tcl with '--help', we get the correct
and expected results.  If we start CLISP via Tcl in its own command window
by prepending  'cmd /c', CLISP starts up correctly, but we have no access
to its standard I/O.  Running CLISP from a DOS prompt or BASH shell and
redirecting its stdin and stdout works fine.  And, as I've said, we've
successfully connected via pipe to other programs as subprocesses of Tcl.

So there's some interaction between how Tcl handles pipes and subprocesses
and what CLISP is trying to do when it starts up.

Can anyone help?  Any suggestions or ideas will be greatly appreciated.

Thank you,
Daniel Ozick

Daniel N. Ozick
Lead Software Engineer
iRobot Corporation
Twin City Office Center, Suite 6
22 McGrath Highway
Somerville, MA 02143

Voice:  (617) 629-0055 x285
Fax:    (617) 629-0126
E-mail: [email-masked]
Web:    http://www.irobot.com

---

From: Sam Steingold <[email-masked]>
Date: Wed Jan 9 15:47:03 2002

> * In message <[email-masked]>
> * On the subject of "[clisp-list] Running CLISP as a Subprocess of Tcl"
> * Sent on Wed, 09 Jan 2002 16:59:09 -0500
> * Honorable Daniel Ozick <[email-masked]> writes:
>
> output from 'program' stdout.

I am not a Tcl expert, so could you please give me a sample session?
E.g.,

set a [open "|clisp" r+]
puts $a "(1+ 10)"
puts $a "(bye)"
get_all_output <---- how do I do this? "gets $a b; echo $b" is ugly!

how do I check whether input is available?

> When we try this with CLISP 2.27, however, the following error message
> appears:
> 

CLISP cannot open the console - no wonder, Tcl has it!

> Can anyone help?  Any suggestions or ideas will be greatly appreciated.

try the appended patch.  it will break WITH-KEYBOARD-INPUT, but you are
not using it anyway, right?

-- 
Sam Steingold (http://www.podval.org/~sds)
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
You can have it good, soon or cheap.  Pick two...

Index: stream.d
===================================================================
RCS file: /cvsroot/clisp/clisp/src/stream.d,v
retrieving revision 1.246
diff -u -w -b -u -b -w -i -B -r1.246 stream.d
--- stream.d	2002/01/07 21:41:36	1.246
+++ stream.d	2002/01/09 23:44:35
@@ -15185,7 +15185,7 @@
   # Initialize the *KEYBOARD-INPUT* stream. This can fail in some cases,
   # therefore we do it after the standard streams are in place, so that
   # the user will get a reasonable error message.
-  #if defined(UNIX) || defined(RISCOS)
+  #if 1 # defined(UNIX) || defined(RISCOS)
   # Building the keyboard stream is a costly operation. Delay it
   # until we really need it.
   define_variable(S(keyboard_input),NIL);     # *KEYBOARD-INPUT*

---

From: Daniel Ozick <[email-masked]>
Date: Thu Jan 10 08:06:10 2002

Thank you, Sam Steingold!

>get_all_output <---- how do I do this? "gets $a b; echo $b" is ugly!

read $a

will return all the data from the channel up to end-of-file.

>how do I check whether input is available?

fblocked $a

will test whether the input has been exhausted on the channel.

eof $a

will test for end-of-file on the channel.

You can also set up file event handlers which fire when the channel is
readable or writeable.

>not using it anyway, right?

<<
Index: stream.d

Right, we are not using WITH-KEYBOARD-INPUT.  However, rebuilding CLISP is
beyond my current capabilities.  (I don't even have the full source.)  Is
there a simple way to apply the patch without doing a full build?  If not,
where do I start reading to learn how to do a build?  Depending on the
complexity of rebuilding and the tools necessary, I may decide to work
around the problem in some other way, since building CLISP is certainly a
major diversion from the task at hand.

Thanks again.

Daniel N. Ozick
Lead Software Engineer
iRobot Corporation

---

From: Sam Steingold <[email-masked]>
Date: Thu Jan 10 08:22:11 2002

> * In message <[email-masked]>
> * On the subject of "Re: [clisp-list] Running CLISP as a Subprocess of Tcl"
> * Sent on Thu, 10 Jan 2002 11:06:59 -0500
welcome!

> Right, we are not using WITH-KEYBOARD-INPUT.  However, rebuilding
> CLISP is beyond my current capabilities.  (I don't even have the full
> source.)  Is there a simple way to apply the patch without doing a
> full build?  If not, where do I start reading to learn how to do a
> build?  Depending on the complexity of rebuilding and the tools
> necessary, I may decide to work around the problem in some other way,
> since building CLISP is certainly a major diversion from the task at
> hand.

your options are:

 - use sockets: this way CLISP and Tcl will be able to run on different
   machines.  this is reliable and easy.  really.
   _much_ better than pipes!
   Note the security issues though: Tcl will have to authenticate
   itself to CLISP (or you have to restrict connections).
 
 - go to <http://clisp.cons.org> and get the CLISP source distribution.
   go to <http://sources.redhat.com/cygwin/> and get Cygwin, _or_
   install MSVC.  then it is quite straitforward to build CLISP.
   (MSVC: copy win32msvc/Makefile.msvc5 src/; cd src; nmake)
   (Cygwin: ./configure --build build)

My other CAR is a CDR.

---

From: Sam Steingold <[email-masked]>
Date: Thu Jan 10 08:50:09 2002

> *** - Win32 error 5 (ERROR_ACCESS_DENIED): Access is denied.

as I said, this is because of the console permissions.

note that CLISP runs just fine under Emacs (using inf-lisp.el), so this
is not "just a CLISP problem".

you might actually be using a wrong Tcl interface.

I conclude this from the fact that I cannot send input to CLISP (even
when I patch it and it starts fine) - it does not see what I send to it
with `puts'.

I think [open "|program" r+] creates a 1-directional pipe instead of a
bi-directional one.

-- 
Sam Steingold (http://www.podval.org/~sds)
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
If brute force does not work, you are not using enough.

---

From: Daniel Ozick <[email-masked]>
Date: Thu Jan 10 12:18:07 2002

>is not "just a CLISP problem".

We use CLISP under Emacs as well.

>I think [open "|program" r+] creates a 1-directional pipe instead of a

As I mentioned, we use exactly this Tcl interface with other programs, and
it works bidirectionally.  Here's something you can try to prove out the
pipe if you've got Cygwin tools (or equivalent).

% set a [open "|cat" r+]
file9d9e00
% puts $a "Hello"
% flush $a
% gets $a
Hello

Daniel N. Ozick
Lead Software Engineer
iRobot Corporation

---

From: Sam Steingold <[email-masked]>
Date: Thu Jan 10 12:43:04 2002

> * In message <[email-masked]>
> * Sent on Thu, 10 Jan 2002 15:15:19 -0500

good - so you can see that CLISP _can_ work under another program!

can Tcl avoid grabbing the console?

> % flush $a

aha! - this is was was missing!

% set c "d:/gnu/clisp/current/src/lisp.exe -B d:/gnu/clisp/current/src -q -M d:/gnu/clisp/current/src/lispinit.mem -norc"
d:/gnu/clisp/current/src/lisp.exe -B d:/gnu/clisp/current/src -q -M d:/gnu/clisp/current/src/lispinit.mem -norc
% set a [open "|$c" r+]
filecb9ec0
% puts $a "(1+ 10)"
% puts $a "(bye)"
% flush $a
% read $a

[1]> 
11
[2]> 

% 

so my patch does fix the problem.
I am not sure I want to put it in though...

-- 
Sam Steingold (http://www.podval.org/~sds)
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
We're too busy mopping the floor to turn off the faucet.

---

From: Sam Steingold <[email-masked]>
Date: Thu Jan 10 14:09:03 2002

> We use CLISP under Emacs as well.

Perl, which comes with Cygwin, also has no problems:

my $clisp="d:/gnu/clisp/current/src/lisp.exe -B d:/gnu/clisp/current/src -q -M d:/gnu/clisp/current/src/lispinit.mem -norc";
open(CLISP,"|$clisp");
print CLISP "(! 10)\n*KEYBOARD-INPUT*\n(bye)\n";
close(CLISP);

[1]>
3628800
[2]>
#<INPUT KEYBOARD-STREAM>

maybe you should report this as a Tcl bug?

-- 
Sam Steingold (http://www.podval.org/~sds)
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
Lisp suffers from being twenty or thirty years ahead of time.

---

From: Paolo Amoroso <[email-masked]>
Date: Fri Jan 11 02:40:02 2002

> CLISP as a child process to perform some computation.  Currently, we use

You may check the page about lisp2wish at CLiki:

  http://ww.telent.net/cliki/

Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://web.mclink.it/amoroso/ency/README
[http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/]