Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
#######
#
# E-scripts on Expect.
#
# Note 1: use the eev command (defined in eev.el) and the
# ee alias (in my .zshrc) to execute parts of this file.
# Executing this file as a whole makes no sense.
# An introduction to eev can be found here:
#
#   (find-eev-quick-intro)
#   http://angg.twu.net/eev-intros/find-eev-quick-intro.html
#
# Note 2: be VERY careful and make sure you understand what
# you're doing.
#
# Note 3: If you use a shell other than zsh things like |&
# and the for loops may not work.
#
# Note 4: I always run as root.
#
# Note 5: some parts are too old and don't work anymore. Some
# never worked.
#
# Note 6: the definitions for the find-xxxfile commands are on my
# .emacs.
#
# Note 7: if you see a strange command check my .zshrc -- it may
# be defined there as a function or an alias.
#
# Note 8: the sections without dates are always older than the
# sections with dates.
#
# This file is at <http://angg.twu.net/e/expect.e>
#           or at <http://angg.twu.net/e/expect.e.html>.
#        See also <http://angg.twu.net/emacs.html>,
#                 <http://angg.twu.net/.emacs[.html]>,
#                 <http://angg.twu.net/.zshrc[.html]>,
#                 <http://angg.twu.net/escripts.html>,
#             and <http://angg.twu.net/>.
#
#######





# «.expect.info»		(to "expect.info")
# «.represent-interact»		(to "represent-interact")
# «.expect.nist.gov»		(to "expect.nist.gov")
# «.cotse»			(to "cotse")
# «.debugger»			(to "debugger")
# «.switching_versions»		(to "switching_versions")
# «.modem_interact»		(to "modem_interact")
# «.splitting_output_0»		(to "splitting_output_0")
# «.splitting_output_1»		(to "splitting_output_1")
# «.splitting_input_0»		(to "splitting_input_0")
# «.splitting_input_1»		(to "splitting_input_1")
# «.mini-kibitz»		(to "mini-kibitz")
# «.interact-re-problem»	(to "interact-re-problem")
# «.mini-autoexpect»		(to "mini-autoexpect")
# «.expect_arrays»		(to "expect_arrays")
# «.dejagnu»			(to "dejagnu")
# «.regress.ps-listings»	(to "regress.ps-listings")
# «.modem»			(to "modem")
# «.curses»			(to "curses")
# «.expect_bugs_potato»		(to "expect_bugs_potato")
# «.inetd_logger0»		(to "inetd_logger0")

# «.stty»			(to "stty")
# «.shell-utils»		(to "shell-utils")

# «.input-from-fifo»		(to "input-from-fifo")
# «.passwords»			(to "passwords")
# «.autopasswd»			(to "autopasswd")
# «.noncanonical-mode»		(to "noncanonical-mode")
# «.getconf-pipe-buf»		(to "getconf-pipe-buf")



(find-fline "/usr/doc/expect5.24/FAQ.gz")
(find-fline "/usr/doc/expect5.24/examples/")





#####
#
# Installing the info/texinfo version of the Expect manpage
# 2001apr17
#
#####

# «expect.info»  (to ".expect.info")
# (find-es "texinfo")
# (find-angg "EXPECT/expect.texi")
#*
cd ~/EXPECT/
rm -v expect.info*
makeinfo expect.texi
gzip -9v expect.info*
laf expect.*

install-info --remove expect
echo $?
rm -v /usr/share/info/expect.info*

cd ~/EXPECT/
cp -v expect.info* /usr/share/info/
install-info							\
  --section Programming Programming				\
  --description='Expect 5.31.8.'				\
  /usr/share/info/expect.info.gz
echo $?

# (find-node "(dir)Top" "expect")
# (find-node "(expect)Top")

#*
cd ~/EXPECT/
anonftp angg.twu.net 'cd /home2/edrx/info/' 'mput expect.info*' 'quit'

#*




#####
#
# Representing an interaction with Expect
# 2001jul16
#
#####

# «represent-interact»  (to ".represent-interact")

We'll treat only the case where there's exactly one spawned process.
Atomic actions:

  P<------E         c    expect sends a char "c" to the process
  P------>E         c    the process sends a char to expect
          E<------U c    the user sends a char to expect
          E------>U c    expect sends a char to the user
      (n secs)           n seconds pass without any chars

There are several other kinds of actions, like sending or receiving
signals, or the process closing, but I don't want to discuss them now.
Also, the communication happens through terminals, and either side of
a terminal may change some of its settings; and, as each terminal can
do some buffering and char translation the "real" arrows would be

  P<--T             c
  P-->T		    c
      T<--E	    c
      T-->E	    c
          E<--T	    c
          E-->T	    c
              T<--U c
              T-->U c

I don't understand terminals very well, but I know that they have lots
of settings and are quite complex... there are some notes at the link
below.
# (find-es "modem" "modem_tty_bits")

String actions:

  P<------E         str    expect sends a string "str" to the process
  P------>E         str    the process sends a string to expect
          E<------U str    the user sends a string to expect
          E------>U str    expect sends a string to the user

Note that a string action can correspond to several different
sequences of character actions through terminals, but we don't care
which... for example, both

      T<--E         "a"
  P<--T             "a"
      T<--E         "b"
  P<--T             "b"

and

      T<--E         "a"
      T<--E         "b"
  P<--T             "a"
  P<--T             "b"

can be written as string actions as

  P<------E         "ab".

Also there are string actions with translation:

  P<------E         strp<-stre  expect sends stre and P receives strp
  P------>E         strp->stre  P sends strp and expects receives stre
          E<------U stre<-stru  the user sends stru and E receives stre
          E------>U stre->stru  expect sends stre and U receives stru

and communications between two agents in which we only care for one
side, typically because the other is just echoing, or answering in a
very standard & boring way:

  p<------E         \ stre1    	expect sends stre1 and
  p\----->E	    / stre2	receives stre2

          e<------U \ stru1     the user sends stru1 and
          e\----->U / stru2	receives stru2

  P------>e         \ strp1    	the process sends strp1 and
  P<-----/e	    / strp2	receives back strp2

I'm using lowercases in the name of one the agents of these types of
commutications to stress that its side of the communication has to be
inferred from the other, as its strings are not being shown
explicitly; and, of course, there are many possible ways to expand
these actions into "more atomic" actions. For example:

  p<------E         \ "ab"
  p\----->E	    / "cd"

can be

  P<------E         "ab"
  P------>E         "cd",

or

  P------>E         "c"
  P<------E         "ab"
  P------>E         "d",

or several others, maybe even with pauses and terminal translation.

Extending this idea we may have things like

  p<------e<------U \ stru1
  p\----->e------>U / stru2,

that is typical of when we're using the "interact" command,

  p<------E         \ stre
  p\----->e------>U / stru,

for a situation where expect sends a string (after a timeout, say) and
we are only interested in what the users gets as a consequence of
that.




#####
#
# Don Libes' site: expect.nist.gov
# 2001jul16
#
#####

# «expect.nist.gov»  (to ".expect.nist.gov")
# (find-shttpw3 "expect.nist.gov/")
# (find-shttpfile "expect.nist.gov/")




#####
#
# Expect texts at COTSE
# 2001jul16
#
#####

# «cotse»  (to ".cotse")
# (find-shttpw3 "members.cotse.com/dlf/man/expect/")
# (find-shttpfile "members.cotse.com/dlf/man/expect/")

psner http://members.cotse.com/dlf/man/expect/ -A htm,html,txt,css -nc -np
# Weird, netscape can't display these pages... 

w3m $FLH/snarf/http/members.cotse.com/dlf/man/expect/
w3m $FLH/snarf/http/members.cotse.com/dlf/man/expect/index.htm
w3m $FLH/snarf/http/members.cotse.com/dlf/man/expect/bulletproof1.htm





#####
#
# Using Expect's internal Tcl debugger
# 2000dec25
#
#####

# «debugger»  (to ".debugger")
# (find-fline "~/tmp/EXPECT/")
#*
cat > $EEG <<'---'

h
exit
---
eeg expect -D 1
#*

cd /tmp/
cat > debug-text.exp <<'---'
set b 1
proc p4 {x} {
  return [
    expr 5+[expr 1+$x]]
}
set z [
  expr 1+[expr 2+[p4 $b]]
]
proc p3 {} {
  set m 0
}
proc p2 {} {
  set c 4
  p3
  set d 5
}
proc p1 {} {
  set a 2
  p2
  set a 3
  set a 5
}
p1
set k 7
p1
---

cat > $EEG <<'---'
w
info exists b
n
w
info exists b
n
w
s
w
s
info locals
puts $x
info level
s
w
info exists b
u
w
info exists b
set b
puts $b
concat {}
# Bye...
exit
---

clear; eeg expect -D 1 debug-text.exp

#*





#####
#
# switching between the two expect versions in potato
# 2000oct01
#
#####

# «switching_versions»  (to ".switching_versions")
apti expect5.31-dev tk8.2-dev
# or
apti expect5.24-dev tk8.0-dev


# (find-status "expect5.31")
# (find-vldifile "expect5.31.list")
# (find-fline "/usr/doc/expect5.31/")

# (find-status "expect5.31-dev")
# (find-vldifile "expect5.31-dev.list")
# (find-fline "/usr/doc/expect5.31-dev/")

# apti expectk5.31
# (find-status "expectk5.31")
# (find-vldifile "expectk5.31.list")
# (find-fline "/usr/doc/expectk5.31/")

cd /tmp/
/usr/share/doc/expect5.31/examples/autoexpect tcsh

#*
cp -a /usr/share/doc/expect5.31/examples/autoexpect /tmp/autoex
# (find-fline "/tmp/autoex")
#*





#####
#
# stty (in expect and in shell-utils)
# 2001jan03
#
#####

# «stty»  (to ".stty")
# (find-man "1 stty")
# (to "expect5.31-src")
# (find-exptag "Exp_SttyCmd")
# (find-expfile "exp_tty.c" "if any unknown args")
# (find-es "modem" "modem_tty_bits")

# (find-node "(coreutils)stty invocation")

# «shell-utils»  (to ".shell-utils")
#*
pdsc $SDEBIAN/dists/potato/main/source/base/shellutils_2.0-7.dsc
cd /usr/src/shellutils-2.0/
find *		      | sort > .files
find * -name '*.[ch]' | sort > .files.ch
etags $(<.files.ch)

#*
cd /usr/src/shellutils-2.0/
debian/rules binary	|& tee odrb
# (find-shufile "odrb")

cd /usr/src/shellutils-2.0/builddir/src/
gcc -DLOCALEDIR=\"/usr/share/locale\" -DHAVE_CONFIG_H \
  -I.. -I../../src -I../../lib -I../intl \
  -E ../../src/stty.c > ../../src/stty.E

# (find-shufile "src/stty.E")
# (find-shutag "display_settings")
# (find-shutag "display_recoverable")
# (find-shufile "src/stty.E" "\ndisplay_recoverable")

# Weird: for the kernel NCCS=19, but from the outside NCCS=32...
# (find-k22file "include/asm-i386/termios.h")
# (find-k22file "include/asm-i386/termbits.h")
# (find-k22file "include/asm-i386/ioctls.h")
# (find-k22file "drivers/char/tty_ioctl.c" "NCCS")
# (find-fline "/usr/include/bits/termios.h")
# (find-fline "/usr/include/termios.h")

#*
cd /usr/src/shellutils-2.0/
cd tests/stty/
VERBOSE=yes basic-1
VERBOSE=yes row-col-1

#*
# (find-shufile "")
# (find-shufile "tests/stty/")
# (find-shunode "stty invocation")
# (find-shufile "src/stty.c")
stty -a
stty -g
stty -g | awk -F : '{print NF}'

# The next step is to learn how to simulate that using stty from Expect...
# (find-es "modem" "modem_tty_bits")

#*




#####
#
# splitting output
# 2001jan13
#
#####

# «splitting_output_0»  (to ".splitting_output_0")
# (find-fline "~/EXPECT/MAN/TXT/spawn")
# (find-fline "~/EXPECT/MAN/TXT/interact")
#*
expect -c '
  spawn -open [open /tmp/o w]
  puts $spawn_id
'
#*
expect -c '
  spawn -open [set out_file [open /tmp/o w]]
  set out_spid $spawn_id
  spawn cat
  interact -output "$spawn_id $out_spid" timeout 5 return
  close $out_file
  puts "\n==> [exec tr "\004\012\015" DJM < /tmp/o]\n"
'
#*
# «splitting_output_1»  (to ".splitting_output_1")
# (find-expcommand "spawn" "user_spawn_id")
# (find-expcommand "spawn" "error_spawn_id")
# (find-expcommand "spawn" "tty_spawn_id")
# (find-expcommand "spawn"    "-open")
# (find-expcommand "interact" "-input and -output")
# (find-angg ".zshrc" "save-input")
echo "line1\nline2\n\004" > $EEG
eeg expect -c '
  set idu $user_spawn_id
  spawn -open [set fid1 [open /tmp/out1 w]]; set id1 $spawn_id
  spawn -open [set fid2 [open /tmp/out2 w]]; set id2 $spawn_id
  spawn cat
  set idp $spawn_id
  interact {
    -input $idu -output $idp -output $id1
    -input $idp -output $idu -output $id2
    timeout 5 return
  }
  close $fid1
  close $fid2
  puts ""
  puts "==> [exec tr "\004\012\015" DJM < /tmp/out1]"
  puts "==> [exec tr "\004\012\015" DJM < /tmp/out2]"
'
#*





#####
#
# splitting input
# 2001jan13
#
#####

# «splitting_input_0»  (to ".splitting_input_0")
# (find-node "(libc)Pipes and FIFOs")
# (find-node "(fileutils)mkfifo invocation")
# I want to let an "interact" take input from a fifo, as if the fifo
# was a kibitzed keyboard; the problem is that a fifo closes when the
# writing process closes...
#*
rm -v  /tmp/fifo
mkfifo /tmp/fifo
(sleep 1; echo Hello > /tmp/fifo; sleep 1) &
cat < /tmp/fifo
#*
rm -v  /tmp/fifo
mkfifo /tmp/fifo
(sleep 2; echo Hello > /tmp/fifo; sleep 4) &
expect -c '
  spawn cat /tmp/fifo
  interact {
    timeout 5 {send_user "Timed out\n"; return}
       -o eof {send_user "Got an eof\n"; return}
  }
  puts "Interact ended"
'
#*
# Setting spawn_id inside a proc does not change its global value
# (unless we declare it as global, of course):
expect -c '
  spawn cat; set catpid $spawn_id
  proc s {} {global lspid; spawn ls; set lspid $spawn_id}
  s
  puts "$catpid $lspid $spawn_id"
'


#*
# «splitting_input_1»  (to ".splitting_input_1")
# (to "splitting_output_1")
rm -v  /tmp/fifo
mkfifo /tmp/fifo
( sleep 1; echo -ne 'Hello\r'  > /tmp/fifo
  sleep 1; echo -ne 'Again!\r' > /tmp/fifo
  sleep 3
) &
expect -c '
  proc openfifo {} {spawn -noecho cat /tmp/fifo; return $spawn_id}
  set idu $user_spawn_id
  spawn cat
  set idp $spawn_id
  while 1 {
    set idf [openfifo]
    interact {
      -input $idp eof break  -output $idu
      -input $idu eof break  -output $idp
      -input $idf eof return -output $idp
      timeout 2 break
    }
  }
'
#*




# (find-node "(screen)Screen Command" "`C-a c'")
# (find-node "(screen)Split" "`C-a S'")
# (find-node "(screen)Focus" "`C-a Tab'")



^ac



#####
#
# a problem with interact -re
# 2000jan17
#
#####

# «interact-re-problem»  (to ".interact-re-problem")
# (find-expmanfile "expect")
# (find-expmanfile "interact")
# (find-expfile "exp_inter.c")
# (find-exptag "Exp_InteractObjCmd")
# (find-expfile "exp_inter.c" "exp_one_arg_braced")
# (find-exptag "exp_one_arg_braced")
# (find-exptag "exp_eval_with_one_arg")
# Ahaa - we need a \n before the first non-blank...
#*
# echo '\a\r\f%^\n\a' > /tmp/o
echo '...%^...' > /tmp/o
expect -c '
  proc gotit {} {send_user !!!}
  spawn cat /tmp/o; interact   -o     %      gotit
  spawn cat /tmp/o; interact   -o -re %      gotit
  spawn cat /tmp/o; interact   -o -re {[%^]} gotit
  spawn cat /tmp/o; interact { -o     %      gotit }
  spawn cat /tmp/o; interact { -o     {%}    gotit }
  spawn cat /tmp/o; interact { -o -re %      gotit }
  spawn cat /tmp/o; interact -nobrace -o     %      gotit
  spawn cat /tmp/o; interact -nobrace -o     {%}    gotit
  spawn cat /tmp/o; interact -nobrace -o -re %      gotit
'
#*
# (find-es "perl" "eval_in_regsub")

echo -ne '\b\e\f\n\r\t\v' > /tmp/o
expect -c 'proc gotit {} {send_user !!!}
  spawn cat /tmp/o; interact -o -re {[\r\n]} gotit
'

echo -ne 'foo\nbar\n' > /tmp/o
expect -c 'proc gotit {} {send_user !!!}
  spawn cat /tmp/o; interact -o -re {[\r\n]} gotit
'

echo -ne 'foo\n%%> bar\n%%> ' > /tmp/o
expect -c 'proc gotit {} {send_user !!!}
  spawn cat /tmp/o; interact -o -nobuffer -re {[\r\n]%+> } gotit
  spawn cat /tmp/o; interact {
    -o  -nobuffer -re {[\r\n]%+> } gotit
  }
  set prompt {[\r\n]%+> }
  spawn cat /tmp/o; interact {
    -o  -nobuffer -re $prompt gotit
  }
' | tee ~/o | tr \\r \\n

# (find-file-literally "~/o")
# (find-enode "Coding Systems")
# (find-enode "Visiting")
#*


# The problem is more subtle



set prompt {[\r\n]%+> }
set prompt "\[\r\n\]%+> "
set prompt "\n%+> "
set prompt {..%+> }
set prompt {..\%+> }
# (progn (find-fline "/tmp/o") (wrap 0))
# (progn (find-file-literally "/tmp/o") (wrap 0))
# (find-angg "EXPECT/eeg")
# (find-fline "~/EXPECT/eeg2")
# (find-expfile "exp_inter.c" "spawn id %s sent")
# (find-expfile "exp_log.c" "static char *\nexpPrintifyReal(s)")
# (find-expmanfile "exp_internal")










#####
#
# mini-kibitz
# 2000jan13
#
#####

# «mini-kibitz»  (to ".mini-kibitz")
# (find-status "expect5.24")
# (find-vldifile "expect5.24.list")
# (find-fline "/usr/doc/expect5.24/")

cp -v /usr/share/doc/expect5.24/examples/kibitz ~/tmp/kibitz

# (find-fline "~/tmp/kibitz")
# (find-fline "~/EXPECT/MAN/TXT/")
# (find-fline "~/EXPECT/MAN/TXT/spawn")





#####
#
# A minimal "autoexpect"
# 2001jan21
#
#####

# «mini-autoexpect»  (to ".mini-autoexpect")
# (code-c-d "expex" "/usr/doc/expect5.31/examples/")
# (find-expexfile "autoexpect")
# (find-expexfile "autoexpect" "eval interact")
# (find-expexfile "autoexpect" "proc input")
# (find-expexfile "autoexpect" "proc output")
# (find-expexfile "autoexpect" "proc expand")
#*
cat > $EEG <<'---'
1 + 2
e(1)
l(3)/l(2)
quit
---

cat > /tmp/ae.exp <<'---'
  set buf {}
  set mode none
  set pairs {}
  proc newmode {newmode newbuf} { global buf mode pairs
    if {$mode!="none"} { lappend pairs $mode $buf }
    set mode $newmode
    set buf $newbuf
  }
  proc gotstr {from str} { global buf mode pairs
    if {$from==$mode} {
      append buf $str
    } else {
      newmode $from $str
    }
  }
  interact {
       -nobuffer -re .+ { gotstr i $interact_out(0,string) }
    -o -nobuffer -re .+ { gotstr o $interact_out(0,string) }
  }
---

~/bin/eeg \
  expect -c '
    source $env(HOME)/TCL/inc.tcl ;# (find-angg "TCL/inc.tcl")
    spawn bc -l
    source /tmp/ae.exp
    writefile /tmp/io $pairs
  '

# (find-fline "/tmp/io")
#*




#####
#
# inspecting expect's arrays
# 2000oct02
#
#####

# «expect_arrays»  (to ".expect_arrays")
# (find-fline "/usr/lib/tcl8.0/parray.tcl")

#*
expect -c '
proc puts {channel str} { send_user $str\n }
proc buf {} { global interact_out; return $interact_out(0,string) }
spawn tcsh
interact {
     -re . { send_user "key\n";  parray interact_out }
  -o -re . { send_user "prog\n"; parray interact_out }
       eof { exit }
}
'
#*





#####
#
# Expect variables
#
#####

# (eeman "expect" "expect_out")
# (eeman "expect" 651)
# (eeman "expect" "any_spawn_id")
# (eeman "expect" "interact_out")
# (eeman "expect" "send_slow")
# (eeman "expect" "send_human")
# (eeman "expect" 1624)




######
#
# kibitz
#
######

# (find-vldifile "expect5.24.list")
# (find-fline "/usr/doc/expect5.24/examples/")
cd /usr/doc/expect5.24/examples/
man2t kibitz.1

man2t /usr/doc/expect5.24/examples/kibitz.1

gzip -c9 < /usr/doc/expect5.24/examples/kibitz.1 > /usr/man/man1/kibitz.1.gz
ln -sf /usr/doc/expect5.24/examples/kibitz /usr/bin/kibitz

# (find-fline "/usr/doc/xterm/")

cd /usr/doc/expect5.24/examples/
kibitz alex

/usr/doc/expect5.24/examples/kibitz alex

# (find-fline "/usr/doc/expect5.24/examples/kibitz")

echo 'exec echo Helloooo! > /dev/tty5' | tclsh -

pdsc /debian/dists/slink/main/source/utils/bsdmainutils_4.4.0.1.dsc
# (find-fline "/usr/src/bsdmainutils-4.4.0.1/")
# (find-fline "/usr/src/bsdmainutils-4.4.0.1/write.c")
# (find-fline "/usr/src/bsdmainutils-4.4.0.1/mesg.c")

tty
# (eeman "1 tty")
# (eeman "4 tty")

man -a console
man -a chvt
man -a deallocvt

usr/bin/mesg                                            base/sysvinit




######
#
# kibitz
#
######

cd ~/EXPECT/
grep -v '^[ 	]*#' mykibitz > mykibitz0

# (find-fline "~/EXPECT/mykibitz")
# (find-fline "~/EXPECT/mykibitz0")
# (eeman "expect" 1614)
# (find-fline "~/.zshrc" "kibitz")




######
#
# On doing my own kibitz
#
######

# (eeman "expect" 736)
# (find-fline "~/EXPECT/mykibitz")


puts $argv
if {$argv=="server"} {
}


puts "I'm the server."
exec rm -fv /tmp/toserver
catch [exec mkfifo /tmp/toserver]

puts "pipefd:     [set pipefd [open /tmp/toserver {RDONLY NONBLOCK}]]"
puts "spawn pipe: [spawn -open $pipefd]"
puts "pipesid:    [set pipesid $spawn_id]"
puts ""
puts "shellpid: [set shellpid [spawn $env(SHELL)]]"
puts "shellsid: [set shellsid $spawn_id]"

set timeout -1
expect { -i $pipesid -re .+ { puts hello!} }
puts fuck

set spawn_id $shellsid
expect {
  -re .+ {
    send_user -raw $expect_out(buffer)
    exp_continue
  }
  -i $user_spawn_id -re .+ {
    send $expect_out(buffer)
    exp_continue
  }
}

puts "Server happy! Bye."



    -i $pipesid -re .+ {
      send $expect_out(buffer)
      exp_continue
    }



expect	{
	timeout {send "abc \177d"; continue -expect}
	-re .+ {send_user -raw $expect_out(buffer); continue -expect}
	-i $user_spawn_id -re .+ {send $expect_out(buffer); continue -expect}
}


# interact:
# (eeman "expect" 972)

# (find-expfile "")
# (find-expfile "exp_inter.c")
# (find-expfile "exp_inter.c" "Exp_InteractCmd")

# (find-fline "$S/http/expect.nist.gov/scripts/")
# (find-fline "$S/http/expect.nist.gov/scripts/noidle")

    -re ".*" { puts "pipe input!" }



puts [set z [spawn zsh]]
puts $spawn_id
set spawn_id $z
interact "~~" { puts "tildes!" }





  interact {
    -output $shid
    "~~" { puts "tildes!" }
    -input $inid
    -re ".*" {
      puts "oba!"
    }
  }


else {
  puts [set fout [open /tmp/toserver {WRONLY NONBLOCK}]]
  puts [set fout [open /tmp/fromserver {WRONLY NONBLOCK}]]
  puts "Client happy! Bye."
}



  catch [exec mkfifo /tmp/fromserver]
  puts [exec rm -fv /tmp/fromserver]
  puts [exec ls -laF /tmp]

  # Esse fica bloqueado até o cliente abrir a conexão:
  # puts [set fout [open /tmp/fromserver {WRONLY}]]


set idfs [open /tmp/fromserver r]

puts "$idsh $idfs $idts"





#####
#
# expect using tcl/tk 7.6
#
#####

pdsc /debian/dists/slink/main/source/interpreters/expect_5.28.1-1.dsc

# (find-expfile "exp_main_exp.c")
# (find-expfile "exp_main_sub.c")
# (find-expfile "exp_main_tk.c")
# (find-expfile "Makefile.in" "expectk: ")

cd /usr/src/expect-5.28.1/
debian/rules binary	|& tee odrb

# (find-expfile "odrb")
# (find-expfile "exp_command.c" 1216)
# (find-expfile "exp_command.c" 3181)
# (find-expfile "exp_command.E" "setpgrp(0,0)")

# C-c C-p  c-backward-conditional
# C-c C-n  c-forward-conditional

lynx http://www.distributedobjects.com/portfolio/archives/patterns/discussion/msg03277.html


gcc -D_REENTRANT -E \
  -I. \
  -I/usr/include/tcl8.0-int/generic \
  -I/usr/include/tk8.0-int/generic \
  -I/usr/X11R6/include \
  -DEXP_VERSION=\"5.28.1\" \
  -DSCRIPTDIR=\"/usr/lib/expect5.28\" \
  -DEXECSCRIPTDIR=\"/usr/lib/expect5.28\" \
  -DTCL_DEBUGGER \
  -DDFLT_STTY="\"sane\"" exp_command.c	> exp_command.E

# (find-expfile "debian/rules")
# (find-expfile "odrb")
# (find-expfile "configure.in")
# (find-expfile "configure")
# (find-expfile "Dbgconfig.in")
# (find-expfile "Dbgconfigure")

Pgrep 'm/ckage: (expect5.24|tcl|tk[48])/'


apti tcl7.6-dev tk4.2-dev
# The following packages will be REMOVED:
#   expect5.24-dev tk8.0-dev tcl8.0-dev
# The following NEW packages will be installed:
#   tk4.2-dev tcl7.6-dev




######
#
# Tuba on Tuba
#
######

# (find-fline "/usr/lib/tcl8.0/")
# (find-fline "/usr/lib/tk8.0/")
# (find-vldifile "tk8.0.list")

# (find-tubafile "")
# (find-tubafile "tuba" ".tubarc")
# (find-tubafile "tuba" "proc main ")
# (find-tubafile "tuba_lib.tcl")





#####
#
# dejagnu
# 2001jan20
#
#####

# «dejagnu»  (to ".dejagnu")
# (find-es "gdb" "gdb-source")

# (find-status "dejagnu")
# (find-vldifile "dejagnu.list")
# (find-fline "/usr/doc/dejagnu/")
# (find-node "(dejagnu)Top")
# (find-node "(dejagnu)Running Tests")
# (find-node "(dejagnu)Invoking runtest")

# (find-fline "/usr/bin/runtest")
# (eeman "1 runtest")
# (find-fline "/usr/share/dejagnu/")

#*
# (find-node "(dejagnu)Sample Test")
cd /tmp/
cat > gdb.echo.exp <<'---'
  # send a string to the GDB stdin:
  send "echo Hello world!\n"

  # inspect the GDB stdout for the correct reply,
  # and determine whether the test passes or fails:
  expect {
    -re "Hello world.*$prompt $"    { pass "Echo test" }
    -re "$prompt $"                 { fail "Echo test" }
    timeout                         { fail "(timeout) Echo test" }
    }
---

runtest --tool_exec gdb gdb.echo.exp

#*








Uma coisa que eu não tou entendendo. O expect sempre deixa todos os
processinhos rodando, ou ele pode suspendê-los, como o shell? Aliás, o
sigsusp é não-trapável? Qdz, um processo percebe quando é suspendido?
Ele percebe quando é "dessuspendido", né? Ele precisa disso pra
redesenhar a tela, como o emacs.

Se os processos não são suspendidos então não tem sentido falar em job
control, a não ser que o job control só determine o que vai parar na
tela e que processo recebe o que o usuário tecla.

O expect sabe mandar signals para os filhinhos? Como?

Uma ferramenta que poderia deixar bem mais claro como é que o expect
funciona: como eu acho que o cerne do expect é um enorme "select",
algo que mostrasse tudo que entra e que sai nesse select.


# (find-vldifile "tcl8.0-dev.list")
# (find-fline "/usr/doc/tcl8.0-dev/")

# (eeman "3tcl tclvars")
set tcl_traceCompile 2

for i in $(grep /usr/man/man /var/lib/dpkg/info/tcl8.0-dev.list); do
  echo $i; zcat $i | grep auto_path
done


any_spawn_id
error_spawn_id
tty_spawn_id
user_spawn_id

exp_exec_library
exp_library
expect_library
spawn_id
spawn_out
timeout







#####
#
# expect variables
#
#####

puts [info vars]

puts [spawn cat]
foreach var {
  any_spawn_id
  error_spawn_id
  tty_spawn_id
  user_spawn_id
  exp_exec_library
  exp_library
  expect_library
  spawn_id
  timeout
} {
  catch {
    puts "$var: [set $var]"
  }
}
puts "spawn_out(): [array get spawn_out]"






diald
exmh
dejagnu





######
#
# http://expect.nist.gov/scripts/
#
######

# (find-fline "$S/http/expect.nist.gov/scripts/")
# (find-fline "~/EXPECT/dialer")




######
#
# http://expect.nist.gov/doc/
#
######

# (find-fline "$S/http/expect.nist.gov/doc/")
# (find-fline "$S/http/expect.nist.gov/doc/regress-talk.ps" "csh")

cd $S/http/expect.nist.gov/doc/
pstotext regress.ps > /tmp/regress.txt
pstotext -landscape regress-talk.ps > /tmp/regress-talk.txt
pstotext scripts.ps > /tmp/scripts.txt
# (find-fline "/tmp/")




#####
#
# http://expect.nist.gov/doc/regress.ps: listings
#
#####

# «regress.ps-listings»  (to ".regress.ps-listings")

set password [lindex $argv 2]
spawn passwd [lindex $argv 1]
expect "password:"
send "$password\r"
expect "password:"
send "$password\r"
expect eof

# Listing 1: Non-interactive passwd script. First argument is
# username. Second argument is new password.

################

expect_after {
  eof {exit [expr 10+$question]}
  timeout {exit [expr 20+$question]}
}
set question 0
proc test {args} {
  uplevel {incr question}
  eval [concat expect $args]
}
spawn passwd [lindex $argv 1]
test {
  "No such user" {exit 1}
  "New password:"
}
send "[lindex $argv 2]\r"
test {
  "Password too long" {exit 2}
  "Password too short" {exit 3}
  "Retype new password:"
}
send "[lindex $argv 3]\r"
test {
  "Mismatch - password unchanged" {exit 4}
  "^\r\n$"
}
test {
  "*" {exit 5}
  eof
}

# Listing 2: Non-interactive passwd script with various tests for
# behavior at boundary conditions.

################

passwd.exp bogus - - 1
passwd.exp fred abledabl abledabl 0
passwd.exp fred abcdefghijklm - 3
passwd.exp fred abc - 2
passwd.exp fred foobar bar 4
passwd.exp fred ^C - 11

# Listing 3: Example data file for testing passwd.

################

spawn csh		;# this is a comment
expect "$prompt"	;# assume prompt is set already
send "sleep 10\r"	;# run sleep command for 10 secs
exec sleep 1		;# give time to let sleep begin
send "\cZ"		;# suspend it
exec sleep 10		;# wait for 10 seconds
send "fg\r"		;# let sleep resume
set timeout 5		;# timeout expect after 5 secs
expect "*$prompt" {print "control-Z stopped sleep's clock\n"}
timeout {print "control-Z didn't stop sleep's clock\n"}

# Listing 4: Test whether sleep counts time while suspended.

################

spawn csh
expect $prompt
for {set i 0} {1} {incr i} {
  send "a"
  expect {
    "\cG" break
    timeout break
    "a"
  }
}
print "driver accepted $i chars\n"

# Listing 5: Determine longest input line acceptable to terminal
# driver while in canonical mode.

################

spawn ...
initialize
for {} {1} {} {
  punish ;# punishing procedure defined elsewhere
  interact X ;# pass control to user
}

# Listing 6: Run application through a set of punishing interactions,
# then let user interact. Repeat indefinitely.

################

spawn csh; set csh1 spawn_id
spawn csh; set csh2 spawn_id
send -i $csh1 "send tty\r"
expect -i $csh1 -re "(/.*)\r"
send -i $csh2 "send write $env(USER) $expect(1,string)\r"
expect -i $csh1 -re "Message from .*"

# Listing 7: Beginning of a script to start two processes that
# interact with each other -- in this case, via write.

################

set csh [spawn csh]
set cshnew [spawn csh.new]
while {-1!=[gets stdin input]} {
  send -i $csh $input
  send -i $cshnew $input
  expect -i $csh -re ".+\r\n"
  set output $expect_out(buffer)
  expect -i $csh $output
  if ![string match output $expect_out(buffer)] {
    send_user "detected discrepancy on input $input\n"
    send_user "original csh output $output\n"
    send_user "new csh output $expect_out(buffer)\n"
    interact
  }
}

# Listing 8: Run two shells simultaneously from the same input,
# stopping when there is a difference in their output.

################






#####
#
# modem
#
#####

# «modem»  (to ".modem")
(defun eex-bounded () (interactive)
  (ee-strbounded 'eex "\n%*\n" "\n%*\n"))
(global-set-key [f3] 'eex-bounded)

# (find-fline "~/EXPECT/")
# (find-fline "~/EXPECT/dialer")
# (find-fline "~/EXPECT/dialer" "-open")

# (find-node "(sh-utils)stty invocation")

%*
proc Exec {args} {
  puts $args
  puts -nonewline [eval exec $args]
}
set port /dev/ttyS2
Exec stty 115200 raw -echo < $port > $port
Exec rm -fv /var/lock/LCK..ttyS2 /var/lock/LCK.004.066
spawn -noecho -open [open $port {RDWR NONBLOCK}]
interact {
  "~~" return
  -o "Strike a key when ready . . .\r\n" {send "\n"}
}
%*


%*
proc Exec {args} {
  puts $args
  puts -nonewline [eval exec $args]
}
set port /dev/ttyS2
Exec stty 115200 raw -echo < $port > $port
Exec rm -fv /var/lock/LCK..ttyS2 /var/lock/LCK.004.066
spawn -noecho -open [open $port {RDWR NONBLOCK}]
puts yeah
send {at$}
expect "OK"
%*



expect_before "Strike a key when ready . . .\r\n" {send "\n"; exp_continue}
send "at$"
puts yeah
expect "OK" {puts -nonewline OK}
puts yeah
%*



(defun eexm-bounded () (interactive)
  (ee-strbounded 'write-ee "\n%*\n" "\n%*\n"
		 "#!/usr/bin/expect
proc Exec {args} { puts $args; puts -nonewline [eval exec $args] }
set port /dev/modem
exec stty 115200 raw -echo < $port > $port
spawn -noecho -open [open $port {RDWR NONBLOCK}]
set strike \"Strike a key when ready . . .\\r\\n\"
\n" "\n" "$EET" "0777"))
(global-set-key [f3] 'eexm-bounded)


%*
interact {
  "~~" return
  -o $strike {send "\n"}
}
%*

%*
proc expok {} {
  global strike
  expect {
    $strike { send "\n"; exp_continue }
    OK {}
  }
}
send "at$\r"
expok
%*


%*
set timeout 1
proc expok {} {
  global strike
  expect {
    $strike { send "\n"; exp_continue }
    OK { send {} }
  }
}
foreach command $argv {
  send "$command\r"
  expok
}
sleep 0.05
%*

eet 'at$' 'at&$' 'atd$' 'ats$'

# (find-fline "~/EXPECT/modem")


%*
set strike "Strike a key when ready . . .\r\n"
proc expok {} {
  global strike
  interact {
    -o $strike { send "\r" }
    OK { send_user OK; return }
  }
}
send "at$\r"
expok
%*




strace -q -f -o ~/s $EET

close on exec
"/etc/nsswitch.conf"





#####
#
# Simplifying the curses codes
#
#####

# «curses»  (to ".curses")
# (find-fline "/usr/doc/ncurses-base/")
# (find-fline "/usr/doc/ncurses-bin/")
# (find-fline "/usr/doc/ncurses-term/")
# (find-vldifile "ncurses-base.list")
# (find-vldifile "ncurses-bin.list")
# (find-vldifile "ncurses-term.list")


# See: Exploring Expect, p. 450;
# (eeman "5 terminfo")
# (eeman "5 termcap")
# (eeman "captoinfo")
# (eeman "console_codes")
# (find-fline "/etc/terminfo/l/linux")

pdsc /big/slinks2/dists/slink/main/source/libs/ncurses_4.2-3.dsc
# (code-c-d "ncurses" "/usr/src/ncurses-4.2/")
# (find-ncursesfile "misc/terminfo.src")
# (find-ncursesfile "misc/terminfo.src" "linux|linux console")
# (find-ncursesfile "misc/terminfo.src" "klone+sgr")
# (find-ncursesfile "misc/terminfo.src" "ecma+color")




# Esse bloquinho não funciona, mas o que vem depois funciona.
set env(TERM) "ezork"
set env(TERMCAP) {ezork:
  clr:^L:
  do:^J:
  cr:^M:
  csr:\E[%i%p1%d;%p2%dr:
  cm:\E[%d;%dH:
}
exec captoinfo
exit



# Esse aqui tá ok, mas ele não faz o que eu queria.
set file [open /tmp/ezork.src w]
puts $file {ezork|Test for groking Zork output,
  ind=\n,
  cr=\r,
  clear=\f,
  cup=\E[%p1%d;%p2%dH,
  csr=,
}
#  cup=\E[%p1%d;%p2%dH,
#  csr=\E[%p1%d;%p2%dr,
close $file
set env(TERMINFO) /tmp
exec tic /tmp/ezork.src
set env(TERM) ezork



# Esse bloco é o que funciona mais, mas o scroll dele é meio bobo.

if {0} {
  # (find-ncursesfile "misc/terminfo.src" "linux|linux console")
  # (find-ncursesfile "misc/terminfo.src" "klone+sgr")
  # (find-ncursesfile "misc/terminfo.src" "ecma+color")
  set file [open /tmp/ezork.src w]
  puts $file {ezork|Test for groking Zork output,
    ind=^J,
    cr=^M,
    nel=^M^J,
    cols#80, lines#50,
    ndscr,
    cup=\E[%i%p1%d;%p2%dH,
    csr=\E[%i%p1%d;%p2%dr,
    clear=\E[H\E[J,
    dl=\E[%p1%dM,
  }
  #  cup=\E[%p1%d;%p2%dH,
  #  csr=\E[%p1%d;%p2%dr,
  close $file
  set env(TERMINFO) /tmp
  exec tic /tmp/ezork.src
  set env(TERM) ezork
}




#####
#
# expect bugs in potato
# 2000apr15
#
#####

# «expect_bugs_potato»  (to ".expect_bugs_potato")
#*
expect -c '
  # stty raw
  stty -icanon
  while 1 {
    set usecs [lindex [time {expect -re .}] 0]
    set msecs [expr $usecs/1000.0]
    send_user "$msecs "
  }
'
#*

# 2001jan20: hm, it turns out that there is no bug here; I just
# learned enough about ttys to why a "stty -icanon"/"stty raw" is
# needed. But stty raw is often too aggressive.

# (find-fline "/var/lib/dpkg/status" "Package: expect5.24\n")
# (find-fline "/var/lib/dpkg/status" "Package: expect5.31\n")

# (find-vldifile "" "expect")

# (find-vldifile "expect5.24.postinst")
# (find-vldifile "expect5.24.prerm")
# (find-vldifile "expect5.31.list")
# (find-vldifile "expect5.31.md5sums")
# (find-vldifile "expect5.31.postinst")
# (find-vldifile "expect5.31.prerm")
# (find-vldifile "expect5.31.shlibs")

# (find-fline "/usr/doc/expect5.31/FAQ.gz")
# (find-fline "/usr/doc/expect5.31/FAQ.gz" "fake daemon")
# (find-fline "/usr/doc/expect5.31/NEWS.gz" "new-regexp-features")

psne http://www.scriptics.com/support/howto/regexp81.html
http://dev.scriptics.com/doc/howto/regexp81.html

# (find-fline "/var/lib/dpkg/status" "Package: exim")
# (find-fline "$SDEBIAN/ls-lR.i")
Pgrepp m/icq/





#####
#
# making a texinfo file from the manpage
# 2001apr15
#
#####

# «expect.texi»  (to ".expect.texi")
# (find-fline "~/EXPECT/expect.man.txt")
#*
cd ~/EXPECT/
zcat /usr/share/man/man1/expect.1.gz \
  | man2t2 \
  | col -bx \
  > expect.man.txt
#*








#####
#
# bug-hunting on inetd services: logging stdin, stdout and stderr
# 2000apr15
#
#####

# «inetd_logger0»  (to ".inetd_logger0")

# Below are some frustrated attempts to write loggers for inetd
# programs in expect.

# see the expect book, p.245 and 251--.

# expect:
# (eeman "expect" 491)
# interact:
# (eeman "expect" 491)

# user_spawn_id
# error_spawn_id
# tty_spawn_id

expect -c '
  expect {
    -i $user_spawn_id
    -re . {
      send $expect_out(buffer)
      exp_continue
    }
    -i $error_spawn_id
    -re . {
      send $expect_out(buffer)
      exp_continue
    }
  }
'

expect -c '
  spawn tclsh
  expect -i $user_spawn_id -re . {
    send $expect_out(buffer)
    send_user $expect_out(buffer)
    exp_continue
  }
'

zcat /usr/share/man/man1/expect.1.gz

# (find-expmanfile "")
# (find-expmanfile "interact")


expect -c '
  spawn tclsh
  interact {
    -re (.)  {
      send $interact_out(0,string)
    }
    -i $user_spawn_id
    -re (.) {
      send_user $interact_out(0,string)
    }
    -i $error_spawn_id
    -re (.) {
      send_error $interact_out(0,string)
    }
  }
  send_user "done.\n"
'


expect -c '
  spawn tclsh
  interact {
    -re (.) {
      send $interact_out(0,string)
      send_user $interact_out(0,string)
    }
  }
  send_user "done.\n"
'




#####
#
# expect5.31-dev
#
#####

# (find-available "expect5.31-dev")
# (find-status "expect5.31-dev")
# (find-vldifile "expect5.31-dev.list")
# (find-fline "/usr/doc/expect5.31-dev/")

# (find-fline "/usr/include/tcl8.3/expect.h")
# (find-fline "/usr/include/tcl8.3/expect_tcl.h")
# (find-fline "/usr/include/tcl8.3/expect_comm.h")
# (find-fline "/usr/include/tcl8.3/tcldbg.h")
# (eeman "3 libexpect5.31")


A mental model for expect (tentative):

Let's suppose that no new processes will be spawned and no processes
will close in the time frame we're interested in; then Expect is
communicating with n processes, P1..Pn, plus a special process, P0,
which is the user. We'll ignore the distinction between each
stdout/stderr pair, and between the three "std"s and the tty for P0;
so Expect can send characters to any one of P0..Pn through a single
channel, that we will call E->Pk. Also, Expect receives chars via
channels that we will call Pk->E.

We'll suppose that every time that Expect sends characters to any of
the Pks the kernel call is ran immediately; so there is no need for
output buffers. As for receiving characters, Expect waits for them
using a "select" call, and when it is notified that there are
characters waiting it reads these characters immediately and do all
the state transitions it needs; only after getting back to a stable
state it will do another "select" call. Expect never asks which of the
Pk->E channels have characters; it just enters its "call select" mode
from time to time. So we can suppose that input comes from one channel
at a time; the "select" call receives either characters from exactly
one of the channels, or a notification that a certain number of
seconds have passed (1, say) and the processes have sent nothing.

Each of the Pk->E channels has a buffer with its unprocessed
characters. Every time we receive new characters we run a certain
pattern matching routine on all these buffers of unprocessed
characters. The pattern matchers are not optimized to suspend while we
wait for new input to avoid reparsing things; every time we receive
new characters -- and then we append them to some of the input buffers
-- the buffers are reparsed anew. The order in which the characters
have piled on the several input buffers is immaterial.

The top of each of the buffers is a "temporary EOF", or "TEOF". Trying
to matching a patterns and discovering that it would have to extend
past the TEOF is not exactly a failure; the match is just incomplete.
This distinction in important sometimes because it is a common
operation to discover which characters do not match a pattern and
flush them out. As far as I know there are no commands to replace the
characters in a buffer by another arbitrary sequence of characters.

The action at any given state is determined by trying to match the
contents of the buffers agains certain patterns, and discovering
"which pattern matches first". As the patterns are given by regexps I
believe that we must use a sort of a stack machine (the stacks are for
backtracking) with a separate stacks for each input buffer, and with
some weird rules of backtracking (i.e., with some unusual rules to
compose the individual pattern-matching automata) to let us test one
buffer for a pattern, then another for another pattern, then, say,
another pattern on the first buffer, and so on.

To make it simpler to test which pattern matches first we will suppose
that each "select" call returns exactlt one char, or a timeout; no
blocks of characters. It should possible to devise optimization
strategies to allow receiving blocks of characters at once (without
changing the result) but it would be crazy to discuss that now.




Is the "pi-calculus" the calculus designed to allow reasoning with
confluent reductions on programs that interact via many channels, like
Expect?




#####
#
# exec and spawn do NOT concatenate their arguments
# 2004sep06
#
#####

# (find-man "3tcl exec")
# (find-expcommand "spawn")
#*
printf "{%s} {%s}\n"  foo bar
printf "{%s} {%s}\n" "foo bar"
expect -c '
  puts [exec printf "{%s} {%s}"  foo bar ]
  puts [exec printf "{%s} {%s}" "foo bar"]
  spawn printf "{%s} {%s}\n"  foo bar ; interact
  spawn printf "{%s} {%s}\n" "foo bar"; interact
'
#*




#####
#
# getting extra input from a fifo
# 2004sep06
#
#####

# «input-from-fifo»  (to ".input-from-fifo")
# (find-angg "EXPECT/readfifo")
# (find-man "1 mkfifo")
# (find-node "(coreutils)mkfifo invocation")
#*
rm -Rv /tmp/myfifos/
mkdir  /tmp/myfifos/
cd     /tmp/myfifos/
mkfifo fifo1
(sleep 2; echo "echo foo" > fifo1; sleep 2; echo "echo bar" > fifo1) &
cat < fifo1
cat < fifo1

#*
# (find-expcommand "interact")
rm -Rv /tmp/myfifos/
mkdir  /tmp/myfifos/
cd     /tmp/myfifos/
mkfifo fifo1
(sleep 2; echo "echo foo" > fifo1; sleep 2; echo "echo bar" > fifo1) &

expect -c '
  # spawn cat fifo1
  # spawn sh -c "while true; do cat fifo1; done"
  spawn sh -c {while [ -r fifo1 ]; do cat fifo1; done}
  set readfifo_spawn_id $spawn_id
  spawn bash
  interact {
    -input        $user_spawn_id
      -output          $spawn_id
      eof              {send_user "keyboard closed\n"; return}
    -input    $readfifo_spawn_id
      -output          $spawn_id
      eof              {send_user "readfifo closed\n"; exp_continue}
    -input             $spawn_id
      -output     $user_spawn_id
      eof              {send_user "sh closed\n"; return}
  }
'
#*





#####
#
# answering ssh/rsh password requests
# 2004sep30
#
#####

# «passwords»  (to ".passwords")
# (find-angg ".zshrc" "autopasswd")
# (find-angg "EXPECT/Sucuri")
# (find-angg "EXPECT/Twu")
# (find-expcommand "log_user")
#*
# I got the -echo/echo hint from Exploring Expect, p.199.
# (find-expcommand "stty" "stty -echo")
# (find-man "1 stty")
# (find-node "(coreutils)stty invocation")
# (find-node "(libc)Low-Level Terminal Interface")

cat > /tmp/passwdprompt <<'%%%'
#!/bin/sh
echo Hello.
# echo -n "edrx@sucuri.mat.puc-rio.br's password: "
echo -n "edrx@angg.twu.net's password: "
  stty -echo
read PASSWD
  stty echo
  echo
echo you typed: $PASSWD
%%%
chmod 755 /tmp/passwdprompt
#*
/tmp/passwdprompt

#*
# (find-expcommand "interact")
# (find-expcommand "interact" "-o flag")
# (find-expcommand "interact" "-nobuffer flag")

expect =(<<'%%%'
  spawn /tmp/passwdprompt
  set SUCURI sucuri.mat.puc-rio.br
  set TWU    angg.twu.net
  interact {
    -o -nobuffer "edrx@${SUCURI}'s password: " { sleep 0.5; send "1234\n" }
       -nobuffer "edrx@${TWU}'s password: "    { sleep 0.5; send "2345\n" }
  }
%%%)

#*




#####
#
# autopasswd (my script conflict with expect's)
# 2019mar14
#
#####

# «autopasswd» (to ".autopasswd")
# (find-angg ".zshrc" "autopasswd")
# (find-angg "EXPECT/autopasswd")
# (find-zsh "apt-file search autopasswd")
# (find-status   "expect")
# (find-vldifile "expect.list")
# (find-udfile   "expect/")
# (find-vldifile "expect.list" "/usr/bin/expect_autopasswd")
# (find-vldifile "expect.list" "/usr/bin/autopasswd")




#####
#
# receiving characters as they are typed
# 2004oct08
#
#####

# «noncanonical-mode»  (to ".noncanonical-mode")
# (find-node "(libc)Canonical or Not")
# (find-node "(libc)Noncanonical Input")
# (find-node "(libc)Local Modes")
# (find-node "(coreutils)Input")
# (find-node "(coreutils)Local")
# (find-htetfile "BackspaceDelete.gz" "one-liner")
#*
eegcc <<<'
  void main() { int c; while(c = getchar()) printf("%d 0x%02X\n", c, c); }
'
stty -icanon min 1
eec
stty sane

#*




#####
#
# logging the input and output of an interactive program
# 2004dec18
#
#####

# (find-man "1 script")
#*
expect -c '
  spawn -open [set infile  [open /tmp/i w]]; set infile_spawn_id  $spawn_id
  spawn -open [set outfile [open /tmp/o w]]; set outfile_spawn_id $spawn_id
  spawn bash;                                set prog_spawn_id    $spawn_id
  interact {
    -input $user_spawn_id -output "$prog_spawn_id $infile_spawn_id" 
    -input $prog_spawn_id -output "$user_spawn_id $outfile_spawn_id" 
  }
  close $outfile
  exit 0
'
# (find-fline "/tmp/o")
# (find-sh "cat /tmp/i; echo; echo '===='; cat /tmp/o")

#*
# (find-pspage "$S/http/expect.nist.gov/doc/kibitz.ps")
# On page 3 of http://expect.nist.gov/doc/kibitz.ps Don Libes uses
# another idiom for connecting two processes:
#   while 1 {
#     expect {
#       -i $process1 -re .+ { send -i $process2 $expect_out(buffer) }
#       -i $process2 -re .+ { send -i $process1 $expect_out(buffer) }
#     }
#   }
# but that was written before he had "interact".






#*
cat > /tmp/foo.tcl <<'%%%'
  proc li {str} { sleep 1; send_user -- "$str\n" }
  li {print(1+2)}
  li {-- comment}
  li {os.exit()}
  sleep 1
%%%
expect /tmp/foo.tcl

#*
# This doesn't work. Why?
expect -c '
  spawn expect /tmp/foo.tcl; set id1 $spawn_id
  spawn lua50;               set id2 $spawn_id
  interact {
    -input $id1 -output $id2 -output $user_spawn_id
    -input $id2 -output $id1 -output $user_spawn_id
  }
'
#*
# Logging input (this script works)
expect -c '
  spawn -open [set outfile [open /tmp/i w]]; set outfile_id $spawn_id
  spawn bash
  interact -output "$spawn_id $outfile_id"
  close $outfile
  exit 0
'
# (find-fline "/tmp/i")

#*
expect =(<<'%%%'
  puts $argv
%%%) foo "bar plic ploc" moo


# (find-udfile "expect/examples/kibitz")





#####
#
# A thread on emacs-devel about getconf, LINE_MAX, and PIPE_BUF
# 2021sep08
#
#####

# «getconf-pipe-buf»  (to ".getconf-pipe-buf")
# https://lists.gnu.org/archive/html/emacs-devel/2021-09/threads.html#00193
# https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg00453.html getconf LINE_MAX
# https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg00478.html getconf PIPE_BUF
# https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg00483.html neither has PIPE_BUF
# https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg00681.html Barton patch
# (find-man "1 getconf")
# (find-sh "getconf -a")
# (find-sh "getconf -a | sort")











# (find-available "empty-expect")
# http://empty.sourceforge.net/
# https://packages.debian.org/stretch/empty-expect

https://stackoverflow.com/questions/32910661/pretend-to-be-a-tty-in-bash-for-any-command/32981392#32981392
https://stackoverflow.com/questions/1401002/how-to-trick-an-application-into-thinking-its-stdout-is-a-terminal-not-a-pipe
https://blog.robertelder.org/don-libes-expect-unix-automation-tool/

https://news.ycombinator.com/item?id=31146862 The TTY Demystified (2008) (linusakesson.net) - Links to previous discussions




#  Local Variables:
#  coding:               utf-8-unix
#  End: