Refactoring to support pseudoterminal mode

This commit is contained in:
Patrick Lühne 2020-05-25 16:28:59 +02:00
parent d6da017a76
commit a42417aed3
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
2 changed files with 56 additions and 39 deletions

View File

@ -89,7 +89,7 @@ end
log "info", "connected to control socket" log "info", "connected to control socket"
encoded_script_path = Base64.encode64(script_path).delete("\n") encoded_script_path = Base64.encode64(script_path).delete("\n")
$control_socket.puts "new v1 #{encoded_script_path}" $control_socket.puts "new v1 named-pipes #{encoded_script_path}"
pipes = {"stdin" => nil, "stdout" => nil, "stderr" => nil} pipes = {"stdin" => nil, "stdout" => nil, "stderr" => nil}

View File

@ -3,7 +3,7 @@
require "base64" require "base64"
require "socket" require "socket"
require "/data/github/current/config/environment" #require "/data/github/current/config/environment"
class ClientError < StandardError class ClientError < StandardError
def initialize(message) def initialize(message)
@ -85,6 +85,38 @@ def read_command(control_socket)
return command, arguments return command, arguments
end end
def set_up_named_pipes(control_socket, connection_id)
stdin = open_pipe(connection_id, "stdin")
control_socket.puts "stdin #{stdin}"
stdin = File::open(stdin, "r")
stdin.sync = true
stdout = open_pipe(connection_id, "stdout")
control_socket.puts "stdout #{stdout}"
stdout = File::open(stdout, "w")
stdout.sync = true
stderr = open_pipe(connection_id, "stderr")
control_socket.puts "stderr #{stderr}"
stderr = File::open(stderr, "w")
stderr.sync = true
$stderr.puts " set up named pipes"
control_socket.puts "ready"
response = control_socket.readline.strip
if response != "ready"
raise ClientError.new "invalid command"
Kernel.exit!
end
$stdin.reopen(stdin)
$stdout.reopen(stdout)
$stderr.reopen(stderr)
end
while true while true
control_socket = control_server.accept control_socket = control_server.accept
$stderr.puts "- new connection" $stderr.puts "- new connection"
@ -96,14 +128,24 @@ while true
raise ClientError.new "unexpected command" raise ClientError.new "unexpected command"
end end
if arguments.length != 2 if arguments.length != 3
raise ClientError.new "malformed command" raise ClientError.new "malformed command"
end end
if arguments[0] != "v1" protocol_version = arguments[0]
raise ClientError.new "unsupported protocol version"
if protocol_version != "v1"
raise ClientError.new "unsupported protocol version (#{protocol_version})"
end end
mode = arguments[1]
if not ["named-pipes", "pseudoterminal"].include?(mode)
raise ClientError.new "unknown mode (#{mode})"
end
script_path = Base64.decode64(arguments[2])
connection_id += 1 connection_id += 1
child_process = fork { child_process = fork {
@ -113,46 +155,21 @@ while true
exit_code = "unknown" exit_code = "unknown"
if mode == "named-pipes"
set_up_named_pipes(control_socket, connection_id)
else
raise ClientError.new "not yet implemented"
end
original_stderr.puts " executing script " + script_path
begin begin
stdin = open_pipe(connection_id, "stdin")
control_socket.puts "stdin #{stdin}"
stdin = File::open(stdin, "r")
# TODO: reconsider
stdin.sync = true
stdout = open_pipe(connection_id, "stdout")
control_socket.puts "stdout #{stdout}"
stdout = File::open(stdout, "w")
stdout.sync = true
stderr = open_pipe(connection_id, "stderr")
control_socket.puts "stderr #{stderr}"
stderr = File::open(stderr, "w")
stderr.sync = true
$stderr.puts " set up pipes"
control_socket.puts "ready"
response = control_socket.readline.strip
if response != "ready"
raise ClientError.new "invalid command"
Kernel.exit!
end
script_path = Base64.decode64(arguments[1])
$stderr.puts " executing script " + script_path
$stdin.reopen(stdin)
$stdout.reopen(stdout)
$stderr.reopen(stderr)
begin begin
load script_path, true load script_path, true
rescue SystemExit => error rescue SystemExit => error
original_stderr.puts " exit code: #{error.status}" original_stderr.puts " exit code: #{error.status}"
exit_code = error.status exit_code = error.status
rescue => error rescue StandardError => error
$stdin = original_stdin $stdin = original_stdin
$stdout = original_stdout $stdout = original_stdout
$stderr = original_stderr $stderr = original_stderr