yap-shell 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +9 -24
- data/Gemfile +1 -5
- data/LICENSE.txt +17 -18
- data/README.md +28 -14
- data/Rakefile +4 -1
- data/bin/yap +1 -3
- data/lib/.gitkeep +0 -0
- data/yap-shell.gemspec +12 -11
- metadata +19 -184
- data/.rspec +0 -2
- data/.travis.yml +0 -11
- data/DESIGN.md +0 -87
- data/Gemfile.travis +0 -8
- data/Gemfile.travis.lock +0 -104
- data/WISHLIST.md +0 -54
- data/bin/yap-dev +0 -45
- data/lib/tasks/gem.rake +0 -62
- data/lib/yap.rb +0 -52
- data/lib/yap/addon.rb +0 -24
- data/lib/yap/addon/base.rb +0 -52
- data/lib/yap/addon/export_as.rb +0 -12
- data/lib/yap/addon/loader.rb +0 -84
- data/lib/yap/addon/path.rb +0 -56
- data/lib/yap/addon/rc_file.rb +0 -21
- data/lib/yap/addon/reference.rb +0 -22
- data/lib/yap/cli.rb +0 -4
- data/lib/yap/cli/commands.rb +0 -6
- data/lib/yap/cli/commands/addon.rb +0 -14
- data/lib/yap/cli/commands/addon/disable.rb +0 -35
- data/lib/yap/cli/commands/addon/enable.rb +0 -35
- data/lib/yap/cli/commands/addon/list.rb +0 -37
- data/lib/yap/cli/commands/addon/search.rb +0 -99
- data/lib/yap/cli/commands/generate.rb +0 -13
- data/lib/yap/cli/commands/generate/addon.rb +0 -258
- data/lib/yap/cli/commands/generate/addonrb.template +0 -22
- data/lib/yap/cli/commands/generate/gemspec.template +0 -25
- data/lib/yap/cli/commands/generate/license.template +0 -21
- data/lib/yap/cli/commands/generate/rakefile.template +0 -6
- data/lib/yap/cli/commands/generate/readme.template +0 -40
- data/lib/yap/cli/options.rb +0 -162
- data/lib/yap/cli/options/addon.rb +0 -64
- data/lib/yap/cli/options/addon/disable.rb +0 -62
- data/lib/yap/cli/options/addon/enable.rb +0 -63
- data/lib/yap/cli/options/addon/list.rb +0 -65
- data/lib/yap/cli/options/addon/search.rb +0 -76
- data/lib/yap/cli/options/generate.rb +0 -59
- data/lib/yap/cli/options/generate/addon.rb +0 -63
- data/lib/yap/configuration.rb +0 -74
- data/lib/yap/gem_helper.rb +0 -195
- data/lib/yap/gem_tasks.rb +0 -6
- data/lib/yap/shell.rb +0 -116
- data/lib/yap/shell/aliases.rb +0 -58
- data/lib/yap/shell/builtins.rb +0 -18
- data/lib/yap/shell/builtins/alias.rb +0 -42
- data/lib/yap/shell/builtins/cd.rb +0 -57
- data/lib/yap/shell/builtins/env.rb +0 -11
- data/lib/yap/shell/commands.rb +0 -163
- data/lib/yap/shell/evaluation.rb +0 -439
- data/lib/yap/shell/evaluation/shell_expansions.rb +0 -99
- data/lib/yap/shell/event_emitter.rb +0 -18
- data/lib/yap/shell/execution.rb +0 -16
- data/lib/yap/shell/execution/builtin_command_execution.rb +0 -20
- data/lib/yap/shell/execution/command_execution.rb +0 -30
- data/lib/yap/shell/execution/context.rb +0 -128
- data/lib/yap/shell/execution/file_system_command_execution.rb +0 -137
- data/lib/yap/shell/execution/result.rb +0 -18
- data/lib/yap/shell/execution/ruby_command_execution.rb +0 -80
- data/lib/yap/shell/execution/shell_command_execution.rb +0 -30
- data/lib/yap/shell/prompt.rb +0 -21
- data/lib/yap/shell/repl.rb +0 -237
- data/lib/yap/shell/version.rb +0 -5
- data/lib/yap/world.rb +0 -286
- data/rcfiles/yaprc +0 -390
- data/scripts/4 +0 -8
- data/scripts/bg-vim +0 -4
- data/scripts/fail +0 -3
- data/scripts/letters +0 -8
- data/scripts/lots-of-output +0 -6
- data/scripts/pass +0 -3
- data/scripts/simulate-long-running +0 -4
- data/scripts/write-to-stderr.rb +0 -3
- data/scripts/write-to-stdout.rb +0 -3
- data/spec/features/addons/generating_an_addon_spec.rb +0 -55
- data/spec/features/addons/using_an_addon_spec.rb +0 -182
- data/spec/features/aliases_spec.rb +0 -78
- data/spec/features/environment_variables_spec.rb +0 -69
- data/spec/features/filesystem_commands_spec.rb +0 -61
- data/spec/features/first_time_spec.rb +0 -45
- data/spec/features/grouping_spec.rb +0 -81
- data/spec/features/line_editing_spec.rb +0 -174
- data/spec/features/range_spec.rb +0 -35
- data/spec/features/redirection_spec.rb +0 -234
- data/spec/features/repetition_spec.rb +0 -118
- data/spec/features/shell_expansions_spec.rb +0 -127
- data/spec/spec_helper.rb +0 -172
- data/spec/support/matchers/have_not_printed.rb +0 -30
- data/spec/support/matchers/have_printed.rb +0 -68
- data/spec/support/very_soon.rb +0 -9
- data/spec/support/yap_spec_dsl.rb +0 -258
- data/test.rb +0 -206
- data/update-rawline.sh +0 -6
@@ -1,99 +0,0 @@
|
|
1
|
-
module Yap::Shell
|
2
|
-
class Evaluation
|
3
|
-
class ShellExpansions
|
4
|
-
attr_reader :aliases, :world
|
5
|
-
|
6
|
-
def initialize(world:, aliases: Aliases.instance)
|
7
|
-
@world = world
|
8
|
-
@aliases = aliases
|
9
|
-
end
|
10
|
-
|
11
|
-
def expand_aliases_in(input)
|
12
|
-
Treefell['shell'].puts "shell-expansions expand aliases in: #{input.inspect}"
|
13
|
-
head, *tail = input.split(/\s/, 2).first
|
14
|
-
expanded = if aliases.has_key?(head)
|
15
|
-
new_head=aliases.fetch_alias(head)
|
16
|
-
[new_head].concat(tail).join(" ")
|
17
|
-
else
|
18
|
-
input
|
19
|
-
end
|
20
|
-
expanded
|
21
|
-
end
|
22
|
-
|
23
|
-
def expand_words_in(input, escape_directory_expansions: true)
|
24
|
-
Treefell['shell'].puts "shell-expansions expand words in: #{input.inspect}"
|
25
|
-
expanded = [input].flatten.inject([]) do |results,str|
|
26
|
-
results << process_expansions(
|
27
|
-
word_expand(str),
|
28
|
-
escape_directory_expansions: escape_directory_expansions
|
29
|
-
)
|
30
|
-
end.flatten
|
31
|
-
expanded
|
32
|
-
end
|
33
|
-
|
34
|
-
def expand_variables_in(input)
|
35
|
-
Treefell['shell'].puts "shell-expansions expand variables in: #{input.inspect}"
|
36
|
-
env_expand(input)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def env_expand(str)
|
42
|
-
# match "$a", "$a $b", "$a$b", "$cat$dog $foo"
|
43
|
-
str.gsub(/\$([^\$\s]+)/) do |match,*args|
|
44
|
-
var_name = match[1..-1]
|
45
|
-
if var_name == '?'
|
46
|
-
(world.last_result ? world.last_result.status_code.to_s : '0').tap do |expanded|
|
47
|
-
Treefell['shell'].puts "shell-expansions expanding env var #{match} to #{expanded}"
|
48
|
-
end
|
49
|
-
elsif world.env.has_key?(var_name)
|
50
|
-
world.env.fetch(var_name).tap do |expanded|
|
51
|
-
Treefell['shell'].puts "shell-expansions expanding env var #{match} to #{expanded}"
|
52
|
-
end
|
53
|
-
else
|
54
|
-
match
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def word_expand(str)
|
60
|
-
content = str.scan(/\{([^\}]+)\}/).flatten.first
|
61
|
-
if content
|
62
|
-
expansions = content.split(",", -1)
|
63
|
-
|
64
|
-
# Break compatibility with Bash/Zsh. They do not expand words
|
65
|
-
# when there is only one word supplied (e.g. "a_{word}"), but this
|
66
|
-
# is counter-intuitive to me. It should behave the same regardless
|
67
|
-
# of the number of words provided to expand.
|
68
|
-
expanded = expansions.map { |expansion| str.sub(/\{([^\}]+)\}/, expansion) }.tap do |expanded|
|
69
|
-
Treefell['shell'].puts "shell-expansions expanding words in #{str} to #{expanded}"
|
70
|
-
end
|
71
|
-
else
|
72
|
-
[str]
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def process_expansions(expansions, escape_directory_expansions: true)
|
77
|
-
expansions.map do |s|
|
78
|
-
# Basic bash-style tilde expansion
|
79
|
-
s.gsub!(/\A~(.*)/, world.env["HOME"] + '\1')
|
80
|
-
|
81
|
-
# Basic bash-style variable expansion
|
82
|
-
s = env_expand(s)
|
83
|
-
|
84
|
-
# Basic bash-style path-name expansion
|
85
|
-
expansions = Dir[s]
|
86
|
-
if expansions.any?
|
87
|
-
if escape_directory_expansions
|
88
|
-
expansions.map(&:shellescape)
|
89
|
-
else
|
90
|
-
expansions
|
91
|
-
end
|
92
|
-
else
|
93
|
-
s
|
94
|
-
end
|
95
|
-
end.flatten
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Yap::Shell
|
2
|
-
module EventEmitter
|
3
|
-
def _callbacks
|
4
|
-
@_callbacks ||= Hash.new { |h, k| h[k] = [] }
|
5
|
-
end
|
6
|
-
|
7
|
-
def on(type, *args, &blk)
|
8
|
-
_callbacks[type] << blk
|
9
|
-
self
|
10
|
-
end
|
11
|
-
|
12
|
-
def emit(type, *args)
|
13
|
-
_callbacks[type].each do |blk|
|
14
|
-
blk.call(*args)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/lib/yap/shell/execution.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Yap::Shell
|
2
|
-
module Execution
|
3
|
-
require "yap/shell/execution/context"
|
4
|
-
require "yap/shell/execution/command_execution"
|
5
|
-
require "yap/shell/execution/builtin_command_execution"
|
6
|
-
require "yap/shell/execution/file_system_command_execution"
|
7
|
-
require "yap/shell/execution/ruby_command_execution"
|
8
|
-
require "yap/shell/execution/shell_command_execution"
|
9
|
-
require "yap/shell/execution/result"
|
10
|
-
|
11
|
-
Context.register BuiltinCommandExecution, command_type: :BuiltinCommand
|
12
|
-
Context.register FileSystemCommandExecution, command_type: :FileSystemCommand
|
13
|
-
Context.register ShellCommandExecution, command_type: :ShellCommand
|
14
|
-
Context.register RubyCommandExecution, command_type: :RubyCommand
|
15
|
-
end
|
16
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Yap::Shell::Execution
|
2
|
-
require 'yap/shell/execution/result'
|
3
|
-
|
4
|
-
class BuiltinCommandExecution < CommandExecution
|
5
|
-
on_execute do |command:, n:, of:, wait:|
|
6
|
-
Treefell['shell'].puts "builtin command executing: #{command}"
|
7
|
-
status_code = command.execute(stdin:@stdin, stdout:@stdout, stderr:@stderr)
|
8
|
-
if status_code == :resume
|
9
|
-
Treefell['shell'].puts "builtin command execution resumed: #{command}"
|
10
|
-
ResumeExecution.new(status_code:0, directory:Dir.pwd, n:n, of:of)
|
11
|
-
else
|
12
|
-
@stdout.close if @stdout != $stdout && !@stdout.closed?
|
13
|
-
@stderr.close if @stderr != $stderr && !@stderr.closed?
|
14
|
-
Result.new(status_code:status_code, directory:Dir.pwd, n:n, of:of).tap do |result|
|
15
|
-
Treefell['shell'].puts "builtin command execution done with result=#{result.inspect}"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Yap::Shell::Execution
|
2
|
-
class CommandExecution
|
3
|
-
attr_reader :stdin, :stdout, :stderr, :world
|
4
|
-
|
5
|
-
def self.on_execute(&blk)
|
6
|
-
if block_given?
|
7
|
-
@on_execute_blk = blk
|
8
|
-
else
|
9
|
-
@on_execute_blk
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(stdin:, stdout:, stderr:, world:)
|
14
|
-
@stdin, @stdout, @stderr = stdin, stdout, stderr
|
15
|
-
@world = world
|
16
|
-
end
|
17
|
-
|
18
|
-
def execute(command:, n:, of:, wait:true)
|
19
|
-
if self.class.on_execute
|
20
|
-
self.instance_exec(command:command, n:n, of:of, wait:wait, &self.class.on_execute)
|
21
|
-
else
|
22
|
-
raise NotImplementedError, "on_execute block hasn't been implemented!"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def suspended?
|
27
|
-
@suspended
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
|
3
|
-
module Yap::Shell::Execution
|
4
|
-
class Context
|
5
|
-
def self.on(event=nil, &blk)
|
6
|
-
@on_callbacks ||= Hash.new{ |h,k| h[k] = [] }
|
7
|
-
if event
|
8
|
-
@on_callbacks[event.to_sym].push blk
|
9
|
-
end
|
10
|
-
@on_callbacks
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.fire(event, context, *args)
|
14
|
-
on[event.to_sym].each do |block|
|
15
|
-
block.call(context, *args)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.register(context, command_type:)
|
20
|
-
raise "context cannot be nil" if context.nil?
|
21
|
-
@registrations ||= {}
|
22
|
-
@registrations[command_type] = context
|
23
|
-
true
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.execution_context_for(command)
|
27
|
-
@registrations[command.type] || raise("No execution context found for given #{command.type} command: #{command.inspect}")
|
28
|
-
end
|
29
|
-
|
30
|
-
def initialize(stdin:, stdout:, stderr:)
|
31
|
-
@stdin, @stdout, @stderr = stdin, stdout, stderr
|
32
|
-
@command_queue = []
|
33
|
-
@suspended_execution_contexts = []
|
34
|
-
end
|
35
|
-
|
36
|
-
def add_command_to_run(command, stdin:, stdout:, stderr:, wait:)
|
37
|
-
@command_queue << [command, stdin, stdout, stderr, wait]
|
38
|
-
end
|
39
|
-
|
40
|
-
def clear_commands
|
41
|
-
@command_queue.clear
|
42
|
-
end
|
43
|
-
|
44
|
-
def execute(world:)
|
45
|
-
results = []
|
46
|
-
@command_queue.each_with_index do |(command, stdin, stdout, stderr, wait), reversed_i|
|
47
|
-
of = @command_queue.length
|
48
|
-
i = reversed_i + 1
|
49
|
-
stdin = @stdin if stdin == :stdin
|
50
|
-
stdout = @stdout if stdout == :stdout
|
51
|
-
stderr = @stderr if stderr == :stderr
|
52
|
-
|
53
|
-
execution_context_factory = self.class.execution_context_for(command)
|
54
|
-
if execution_context_factory
|
55
|
-
execution_context = execution_context_factory.new(
|
56
|
-
stdin: stdin,
|
57
|
-
stdout: stdout,
|
58
|
-
stderr: stderr,
|
59
|
-
world: world
|
60
|
-
)
|
61
|
-
|
62
|
-
@saved_tty_attrs = Termios.tcgetattr(STDIN) if STDIN.isatty
|
63
|
-
|
64
|
-
Treefell['shell'].puts "firing :before_execute for #{command}"
|
65
|
-
self.class.fire :before_execute, world, command: command
|
66
|
-
|
67
|
-
begin
|
68
|
-
result = execution_context.execute(command:command, n:i, of:of, wait:wait)
|
69
|
-
rescue Exception => ex
|
70
|
-
raise(ex) if ex.is_a?(SystemExit)
|
71
|
-
|
72
|
-
Treefell['shell'].puts "rescued unexpected error=#{ex} with message=#{ex.message.inspect}"
|
73
|
-
puts <<-ERROR.gsub(/^\s*\|/, '')
|
74
|
-
|******************************
|
75
|
-
|\e[31mWhoops! An unexpected error has occurred\e[0m
|
76
|
-
|******************************
|
77
|
-
|
|
78
|
-
|The error was:
|
79
|
-
| #{ex.message}
|
80
|
-
|
|
81
|
-
|Backtrace:
|
82
|
-
|#{ex.backtrace.join("\n")}
|
83
|
-
|
|
84
|
-
|Report this to yap-shell on github:
|
85
|
-
| https://github.com/zdennis/yap-shell/issues/new?title=#{URI.escape(ex.message)}
|
86
|
-
|
|
87
|
-
ERROR
|
88
|
-
end
|
89
|
-
|
90
|
-
Treefell['shell'].puts "firing :after_execute for #{command}"
|
91
|
-
self.class.fire :after_execute, world, command: command, result: result
|
92
|
-
|
93
|
-
results << process_execution_result(execution_context:execution_context, result:result)
|
94
|
-
Termios.tcsetattr(STDIN, Termios::TCSANOW, @saved_tty_attrs) if STDIN.isatty
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
clear_commands
|
99
|
-
|
100
|
-
results.last
|
101
|
-
end
|
102
|
-
|
103
|
-
private
|
104
|
-
|
105
|
-
def process_execution_result(execution_context:, result:)
|
106
|
-
case result
|
107
|
-
when SuspendExecution
|
108
|
-
Treefell['shell'].puts "suspending execution context"
|
109
|
-
@suspended_execution_contexts.push execution_context
|
110
|
-
return result
|
111
|
-
|
112
|
-
when ResumeExecution
|
113
|
-
Treefell['shell'].puts "resuming suspended execution context"
|
114
|
-
execution_context = @suspended_execution_contexts.pop
|
115
|
-
if execution_context
|
116
|
-
nresult = execution_context.resume
|
117
|
-
Treefell['shell'].puts "resuming suspended execution context success"
|
118
|
-
return process_execution_result execution_context: execution_context, result: nresult
|
119
|
-
else
|
120
|
-
Treefell['shell'].puts "error: cannot resume execution when there is nothing suspended"
|
121
|
-
@stderr.puts "fg: No such job"
|
122
|
-
end
|
123
|
-
else
|
124
|
-
return result
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
@@ -1,137 +0,0 @@
|
|
1
|
-
require 'termios'
|
2
|
-
|
3
|
-
module Yap::Shell::Execution
|
4
|
-
require 'yap/shell/execution/result'
|
5
|
-
|
6
|
-
class FileSystemCommandExecution < CommandExecution
|
7
|
-
on_execute do |command:, n:, of:, wait:, resume_blk:nil|
|
8
|
-
stdin, stdout, stderr, world = @stdin, @stdout, @stderr, @world
|
9
|
-
result = nil
|
10
|
-
if resume_blk
|
11
|
-
pid = resume_blk.call
|
12
|
-
else
|
13
|
-
r,w = nil, nil
|
14
|
-
if command.heredoc
|
15
|
-
r,w = IO.pipe
|
16
|
-
stdin = r
|
17
|
-
end
|
18
|
-
|
19
|
-
pid = fork do
|
20
|
-
# reset signals in case any were ignored
|
21
|
-
Signal.trap("SIGINT", "DEFAULT")
|
22
|
-
Signal.trap("SIGQUIT", "DEFAULT")
|
23
|
-
Signal.trap("SIGTSTP", "DEFAULT")
|
24
|
-
Signal.trap("SIGTTIN", "DEFAULT")
|
25
|
-
Signal.trap("SIGTTOU", "DEFAULT")
|
26
|
-
|
27
|
-
# Set the process group of the forked to child to that of the
|
28
|
-
Process.setpgrp
|
29
|
-
|
30
|
-
$stdin.reopen stdin
|
31
|
-
$stdout.reopen stdout
|
32
|
-
$stderr.reopen stderr
|
33
|
-
|
34
|
-
begin
|
35
|
-
before = ENV.to_h.dup
|
36
|
-
ENV.replace(@world.env)
|
37
|
-
Treefell['shell'].puts <<-MSG.gsub(/^\s*\|/, '')
|
38
|
-
|forked child process
|
39
|
-
| pid=#{Process.pid} #{command.to_executable_str}
|
40
|
-
| stdin=#{stdin.inspect}
|
41
|
-
| stdout=#{stdout.inspect}
|
42
|
-
| stderr=#{stderr.inspect}
|
43
|
-
| $stdin=#{$stdin.inspect}
|
44
|
-
| $stdout=#{$stdout.inspect}
|
45
|
-
| $stderr=#{$stderr.inspect}
|
46
|
-
MSG
|
47
|
-
Kernel.exec command.to_executable_str
|
48
|
-
ensure
|
49
|
-
ENV.replace(before)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
Treefell['shell'].puts "forked child process pid=#{pid} to execute #{command}"
|
53
|
-
|
54
|
-
# Put the child process into a process group of its own
|
55
|
-
Process.setpgid pid, pid
|
56
|
-
|
57
|
-
if command.heredoc
|
58
|
-
Treefell['shell'].puts "command has heredoc, wriing to stdin"
|
59
|
-
w.write command.heredoc
|
60
|
-
w.close
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Set terminal's process group to that of the child process
|
65
|
-
Termios.tcsetpgrp STDIN, pid if STDIN.isatty
|
66
|
-
pid, status = Process.wait2(pid, Process::WUNTRACED) if wait
|
67
|
-
|
68
|
-
# If we're not printing to the terminal then close in/out/err. This
|
69
|
-
# is so the next command in the pipeline can complete and don't hang waiting for
|
70
|
-
# stdin after the command that's writing to its stdin has completed.
|
71
|
-
if stdout != $stdout && stdout.is_a?(IO) && !stdout.closed? then
|
72
|
-
Treefell['shell'].puts "closing stdout for child process with pid=#{pid}"
|
73
|
-
stdout.close
|
74
|
-
end
|
75
|
-
if stderr != $stderr && stderr.is_a?(IO) && !stderr.closed? then
|
76
|
-
Treefell['shell'].puts "closing stderr for child process with pid=#{pid}"
|
77
|
-
stderr.close
|
78
|
-
end
|
79
|
-
# if stdin != $stdin && !stdin.closed? then stdin.close end
|
80
|
-
|
81
|
-
|
82
|
-
# if the pid that just stopped was the process group owner then
|
83
|
-
# give it back to the us so we can become the foreground process
|
84
|
-
# in the terminal
|
85
|
-
if STDIN.isatty
|
86
|
-
if pid == Termios.tcgetpgrp(STDIN)
|
87
|
-
Treefell['shell'].puts <<-DEBUG.gsub(/^\s*\|/, '')
|
88
|
-
|restoring process group for STDIN to yap process with pid=#{Process.pid}
|
89
|
-
DEBUG
|
90
|
-
Process.setpgid Process.pid, Process.pid
|
91
|
-
Termios.tcsetpgrp STDIN, Process.pid
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# if the reason we stopped is from being suspended
|
96
|
-
sigtstp = Signal.list["TSTP"]
|
97
|
-
if status && status.stopsig == sigtstp
|
98
|
-
Treefell['shell'].puts "process pid=#{pid} suspended by signal=#{status.stopsig.inspect}"
|
99
|
-
Treefell['shell'].puts "$?: #{$?.inspect}"
|
100
|
-
suspended(command:command, n:n, of:of, pid: pid)
|
101
|
-
result = Yap::Shell::Execution::SuspendExecution.new(status_code:nil, directory:Dir.pwd, n:n, of:of)
|
102
|
-
else
|
103
|
-
caused_by_signal = status ? (status.termsig || status.stopsig) : nil
|
104
|
-
Treefell['shell'].puts "process pid=#{pid} stopped by signal=#{caused_by_signal.inspect}"
|
105
|
-
Treefell['shell'].puts "$?: #{$?.inspect}"
|
106
|
-
# if a signal killed or stopped the process (such as SIGINT or SIGTSTP) $? is nil.
|
107
|
-
exitstatus = $? ? $?.exitstatus : nil
|
108
|
-
result = Yap::Shell::Execution::Result.new(status_code:exitstatus, directory:Dir.pwd, n:n, of:of)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def resume
|
113
|
-
args = @suspended
|
114
|
-
@suspended = nil
|
115
|
-
pid = args[:pid]
|
116
|
-
sigcont = Signal.list["CONT"]
|
117
|
-
|
118
|
-
Treefell['shell'].puts "resuming suspended process pid=#{pid} by sending it signal=#{sigcont}"
|
119
|
-
resume_blk = lambda do
|
120
|
-
Process.kill sigcont, pid
|
121
|
-
pid
|
122
|
-
end
|
123
|
-
|
124
|
-
self.instance_exec command:args[:command], n:args[:n], of:args[:of], resume_blk:resume_blk, wait:true, &self.class.on_execute
|
125
|
-
end
|
126
|
-
|
127
|
-
def suspended(command:, n:, of:, pid:)
|
128
|
-
Treefell['shell'].puts "process pid=#{pid} suspended"
|
129
|
-
@suspended = {
|
130
|
-
command: command,
|
131
|
-
n: n,
|
132
|
-
of: of,
|
133
|
-
pid: pid
|
134
|
-
}
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|