Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
#!/bin/sh
# the next line restarts using expect \
exec expect "$0" -- "$@"
# (find-man "tclsh" "#!")

#                 _                            _ 
#   ___  ___  ___| |__   __ _ _ __  _ __   ___| |
#  / _ \/ _ \/ __| '_ \ / _` | '_ \| '_ \ / _ \ |
# |  __/  __/ (__| | | | (_| | | | | | | |  __/ |
#  \___|\___|\___|_| |_|\__,_|_| |_|_| |_|\___|_|
#                                                
# eechannel: run an interactive program accepting input from a "channel".
#
# This is a "temporarily ugly" rewrite of a script that had very nice
# headers, and that can still be found at:
#   <http://angg.twu.net/eev-current/eegchannel>
#   <http://angg.twu.net/eev-current/eegchannel.html>
#
# The present version has far less quirks (I hope), and its
# documentation and tests are at:
#   (find-eev "eev-intro.el" "find-channels-intro")
#                            (find-channels-intro)
#                            (find-channels-intro "Downloading and testing")
#
# Please bear with its current ugliness for a while! Cheers! =)
# Edrx, 2013feb11


# Copyright (C) 2004,2007,2012 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:    2013feb11
# Keywords:   e-scripts, processes
#
# Latest version: <http://angg.twu.net/bin/eechannel>
#       htmlized: <http://angg.twu.net/bin/eechannel.html>

# eechannel: run an interactive program accepting input from a "channel".
# eechannel 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:
#
#   eechannel [-v] <channelname> <prog> [<args>]
#
# For example:
#
#   eechannel A bash
#
# will invoke "bash" and run it interactively, with no keyboard or
# output translation; but eechannel 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 eechannel "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 pidfile {} { global channel; return [EEVTMPDIR]/eech.${channel}.pid }
proc strfile {} { global channel; return [EEVTMPDIR]/eech.${channel}.str }

proc rmlastnewline {str} { regexp "^(.*)\n\$" $str -> str; return $str }

set verbose 0
if {[lindex $argv 0] == "-v"} {  # if the first arg is "-v" then
  set verbose 1;                 # set verbose to 1 and
  set argv [lrange $argv 1 end]; # discard that first argument
}

# (find-man "3tcl if")
# (find-books "__comp/__comp.el" "ousterhout")
# (find-tcltktext "")



set channel     [lindex $argv 0];      # first argument:  channel
set progandargs [lrange $argv 1 end];  # other arguments: target prog and args
if {[llength $argv] < 2} {
  puts "Usage: eechannel \[-v\] <channelname> <prog> \[<args>\]"
  exit
}

proc runtimeinfo {} {
  global channel progandargs
  return "Expect binary:  [info nameofexecutable]
Expect script:  [file normalize [info script]]
Expect pid:     [pid]
Channel name:   $channel
Target program: $progandargs
Target pwd:     [pwd]/
\$EEVTMPDIR:     [getenv EEVTMPDIR]
Temp dir:       [EEVTMPDIR]/
Pid file:       [pidfile]
Command file:   [strfile]
Signal:         SIGUSR1
Send cmd with:  echo '<cmd>'   > [strfile]
Send sig with:  kill -USR1 \$(cat [pidfile])"
}
if {$verbose} {
  puts [runtimeinfo]
}




# set argv [lrange $argv 1 end];	# discard first argument


# (find-sh0 "eechannel")
# (find-sh  "eechannel -v")
# (find-sh0 "eechannel -v")
# (find-sh  "eechannel -v A")
# (find-sh  "eechannel -v A prog arg1 arg2")

# exit

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

# puts ([lrange $argv 1 end])
# eval spawn -noecho $argv
eval spawn -noecho [lrange $argv 1 end]
# eval spawn [lrange $argv 1 end]
# stty raw;	        # A relic. Why this? For \n -> \r translation?
interact



#  Local Variables:jjj
#  mode:		 tcl
#  coding:               raw-text-unix
#  ee-anchor-format:     "proc %s"
#  End: