summaryrefslogtreecommitdiff
path: root/sample/pty/shl.rb
blob: 980748e8f587ba739c5e79c5e44bdda2403b9dbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# frozen_string_literal: true
#
#  old-fashioned 'shl' like program
#  by A. Ito
#
#  commands:
#     c        creates new shell
#     C-z      suspends shell
#     p        lists all shell
#     0,1,...  choose shell
#     q        quit

require 'pty'
require 'io/console'

$shells = []

$r_pty = nil
$w_pty = nil

def writer
  STDIN.raw!
  begin
    while true
      c = STDIN.getc
      if c == ?\C-z then
        $reader.raise('Suspend')
        return 'Suspend'
      end
      $w_pty.print c.chr
      $w_pty.flush
    end
  rescue
    $reader.raise('Exit')
    return 'Exit'
  ensure
    STDIN.cooked!
  end
end

$reader = Thread.new {
  while true
    begin
      Thread.stop unless $r_pty
      c = $r_pty.getc
      if c.nil? then
        Thread.main.raise('Exit')
        Thread.stop
      end
      print c.chr
      STDOUT.flush
    rescue
      Thread.stop
    end
  end
}

# $reader.raise(nil)


while true
  print ">> "
  STDOUT.flush
  n = nil
  case gets
  when /^c/i
    $shells << PTY.spawn("/bin/csh")
    n = -1
  when /^p/i
    $shells.each_with_index do |s, i|
      if s
        print i,"\n"
      end
    end
  when /^([0-9]+)/
    n = $1.to_i
    if $shells[n].nil?
      print "\##{i} doesn't exist\n"
      n = nil
    end
  when /^q/i
    exit
  end
  if n
    $r_pty, $w_pty, pid = $shells[n]
    $reader.run
    if writer == 'Exit' then
      Process.wait(pid)
      $shells[n] = nil
      $shells.pop until $shells.empty? or $shells[-1]
    end
  end
end