[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: mkfifo
- To: clisp-list@ma2s2.mathematik.uni-karlsruhe.de
- Subject: Re: mkfifo
- From: Bjoern Hoefling <hoefling@dfki.uni-kl.de>
- Date: Thu, 14 Oct 1993 16:46:59 +0100
- Cc: hoefling@dfki.uni-kl.de
Tomohiro Shibata wrote:
> There has been some discuttion on the mailing list on how to make
> bidirectional communication between clisp and other programs using Unix.
> below is one solutoin provided by Mr. Haible.
>> (shell "mkfifo /tmp/wish-in")
>> (shell "mkfifo /tmp/wish-out")
>> (setq *lisp-to-wish-stream*
>> (make-two-way-stream (open "/tmp/wish-out" :direction :input)
>> (open "/tmp/wish-in" :direction :output)
>> ) )
>> (shell "wish < /tmp/wish-in > /tmp/wish-out")
>> (delete-file "/tmp/wish-in")
>> (delete-file "/tmp/wish-out")
>
> As for my check, it doesn't work as they are seen above.
> when (open pipename-out :direction :input) is entered, prompt never comes.
> But (open pipename-in :direction :output) is entered, I can get
> #<FILE-HANDLE-STREAM #"out">.
> I think only it can work in case of `:direction :io '. And I tried:
>> (shell "command < pipename-in > pipename-out") ,
> but I couln't succeed. Has Mr. Hoefling already succeeded to connect
> with WISH?
> Any suggestion and information are welcome.
As I am directly adressed, here my response. In my masters thesis I am using
clisp under linux and UNIX (Sun). The graphical user interface for my program
is written in tcl/tk by another student and he has tried to explain his solution
for the problem for you. His solution is rather special and is realized mostly
in tcl and not in clisp, but it could be done in a similar way in C with another
UNIX-process.
Here is his solution:
________________________________________________________________________________
My solution works completely the other way round:
I don't call wish from within lisp, but start the lisp interpreter from
within the wish. I think this is more useful because normally i want to evaluate
lisp functions in response to tk events.
I need the "addinput patch" which is available at harbor.ecn.purdue.edu.
The following code works with tcl7.0/tk3.3 and a widget shell with the appropriate patch applied.
# the proc ChildProcess forks a new process from exec file cmd
# and sets it's stdio to inPipe/outPipe
proc ChildProcess {cmd inPipe outPipe } {
if {[set childPid [fork]] == 0} {
# overwrite stdin with inPipe
dup $inPipe stdin
# close the inPipe at the lisp side
close $inPipe
# do the same with stdout/stderr
dup $outPipe stdout
dup $outPipe stderr
close $outPipe
# disconnect process from terminal (useful for signal handling)
id process group set
# run cmd (lisp,shell, or whatever)
execl $cmd
# will never make it here...
}
return $childPid
}
# create fifo (named pipe)
# set your path to the mknod binary here!
proc mkfifo name {
# set mknod /bin/mknod # linux
set mknod /usr/etc/mknod # sun
catch { exec $mknod $name p } msg
if { "$msg" != "" } { puts stderr $msg }
}
# send lisp command to lisp interp.
proc to-lisp {cmd} {
global tclOutPipe
puts $tclOutPipe $cmd
flush $tclOutPipe
}
# signal handler
proc quitCmd { } {
global tclOutPipe tclInPipe tclDataInPipe
catch {
to-lisp "(quit)"
removeinput $tclInPipe
removeinput $tclDataInPipe
close $tclOutPipe
close $tclInPipe
close $tclDataInPipe
unlink [format "/tmp/wishin-%d" [pid] ]
}
destroy .
}
# handlers for receiving input from one of the pipes
# the catch is needed for suns where i get some strange error message
proc process-toplevel {event fileid} {
catch {
if { [gets $fileid line] < 0 } {
quitCmd
} else {
echo toplevel: $line
}
}
}
proc process-data {event fileid} {
catch {
if { [lgets $fileid line] < 0 } {
quitCmd
} else {
echo data: $line
}
} msg
if { "$msg" != "" } { puts stderr $msg }
}
# main program:
# first i create two pipes for communication to/from lisp *terminal-io*.
pipe lispInPipe tclOutPipe
pipe tclInPipe lispOutPipe
# next i create a named pipe for data communication lisp -> wish (i want to read lisp data
# from within tcl)
set pipename [format "/tmp/wishin-%d" [pid] ]
mkfifo $pipename
# the named pipe MUST be opened non-blocking, because otherwise it will hang
# until the other side is opened (see unix manual)
set tclDataInPipe [open $pipename {RDONLY NONBLOCK} ]
# sorry, but i don't know if this is really necessary - at least it doesn't cause harm ....
fcntl $tclInPipe NONBLOCK 1
fcntl $tclDataInPipe NONBLOCK 0
# install addinput handlers
addinput -read $tclInPipe "process-toplevel %E %F"
addinput -read $tclDataInPipe "process-data %E %F"
# fork off clisp
ChildProcess clisp $lispInPipe $lispOutPipe
# set signal handler so that clisp gets terminated when you kill wish
signal trap { SIGTERM SIGQUIT SIGINT } quitCmd
________________________________________________________________________________
I hope this answer helps at least those who use the combination wish/clisp.
*********************************************************************
Bjoern HOEFLING, DFKI, Postfach 2080, W-67608 Kaiserslautern, Germany
hoefling@dfki.uni-kl.de Phone: +49-631-205-3487 Fax: -3210
*********************************************************************