Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
#!/bin/sh # the next line restarts using expect \ exec expect "$0" -- "$@" # (find-man "tclsh" "#!") ## eegchannel: run an interactive program accepting input from a "channel". # Copyright (C) 2004,2007 Free Software Foundation, Inc. # # This file is part of GNU eev. # # GNU eev is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU eev is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Emacs; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # # Author: Eduardo Ochs <eduardoochs@gmail.com> # Maintainer: Eduardo Ochs <eduardoochs@gmail.com> # Version: 2007jan14 # Keywords: e-scripts, processes # # Latest version: <http://angg.twu.net/eev-current/eegchannel> # htmlized: <http://angg.twu.net/eev-current/eegchannel.html> # See also: <http://angg.twu.net/eev-current/README.html> # and: <http://angg.twu.net/eev-current/eeg4.html> # eegchannel: run an interactive program accepting input from a "channel". # eegchannel is a version of eeg/eeg4 in which the sending of a command to # the spawned process is triggered by a SIGUSR1, not by a M-L. # Usage: # # eegchannel <channelname> <prog> [<arg1> [<arg2> ...]] # # For example: # # eegchannel A bash # # will invoke "bash" and run it interactively, with no keyboard or # output translation; but eegchannel will create a file eeg.A.pid and # will use it and a file called eeg.A.str to establish a # (unidirectional) extra communication channel from the outside world # to the spawned process ("bash" in this case). If we do # # echo 'echo $[1+2]' > $EEVTMPDIR/eeg.A.str # kill -USR1 $(cat $EEVTMPDIR/eeg.A.pid) # # we are storing a line of input ("echo $[1+2]\n") in eeg.A.str and # then saying to eegchannel "send that to the process you're # controlling". From the point of view of the controlled process, # thanks to Expect's usual magic, things will be exactly as if the # user typed interactively "echo $[1+2]" and then a "return". # # For a high-level example of how this can be used see: # (find-eevfile "doc/shot-f9.png") # (find-eev "eev-dev.el" "eechannel-do-this-line") # # (find-eev "eeg4" "misc") # (find-eev "eeg4" "arguments") # (find-eev "eeg4" "dospawn") proc readfile {fname} { set ch [open $fname r]; set str [read $ch]; close $ch; return $str } proc writefile {fname str} { set ch [open $fname w]; puts -nonewline $ch $str; close $ch } proc getenv {key {defaultvalue {}}} { global env; expr {[info exist env($key)]?$env($key):$defaultvalue} } proc EEVTMPDIR {} { getenv EEVTMPDIR [getenv HOME]/eev-current/tmp } proc rmlastnewline {str} { regexp "^(.*)\n\$" $str -> str; return $str } proc pidfile {} { global channel; return [EEVTMPDIR]/eeg.${channel}.pid } proc strfile {} { global channel; return [EEVTMPDIR]/eeg.${channel}.str } set channel [lindex $argv 0]; # first argument set argv [lrange $argv 1 end]; # discard first argument writefile [pidfile] "[pid]\n" trap {send -- [readfile [strfile]]} USR1 # Transmit resizings. From <http://www.hadron.org/~hatch/goodies/rrr>. trap { stty rows [stty rows] columns [stty columns] < $spawn_out(slave,name) } WINCH eval spawn -noecho $argv stty raw; # A relic. Why this? For \n -> \r translation? interact # Local Variables: # mode: tcl # End: