Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid off dependency on Signal in Win32 Process::Status #8537

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions src/compiler/crystal/command.cr
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,11 @@ class Crystal::Command
begin
elapsed = Time.measure do
Process.run(output_filename, args: run_args, input: Process::Redirect::Inherit, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit) do |process|
# Ignore the signal so we don't exit the running process
# (the running process can still handle this signal)
::Signal::INT.ignore # do
{% unless flag?(:win32) %}
# Ignore the signal so we don't exit the running process
# (the running process can still handle this signal)
::Signal::INT.ignore # do
{% end %}
end
end
{$?, elapsed}
Expand All @@ -238,17 +240,18 @@ class Crystal::Command
if status.normal_exit?
exit error_on_exit ? 1 : status.exit_code
else
case status.exit_signal
when ::Signal::KILL
STDERR.puts "Program was killed"
when ::Signal::SEGV
STDERR.puts "Program exited because of a segmentation fault (11)"
when ::Signal::INT
# OK, bubbled from the sub-program
else
STDERR.puts "Program received and didn't handle signal #{status.exit_signal} (#{status.exit_signal.value})"
end

{% unless flag?(:win32) %}
case status.exit_signal
when ::Signal::KILL
STDERR.puts "Program was killed"
when ::Signal::SEGV
STDERR.puts "Program exited because of a segmentation fault (11)"
when ::Signal::INT
# OK, bubbled from the sub-program
else
STDERR.puts "Program received and didn't handle signal #{status.exit_signal} (#{status.exit_signal.value})"
end
{% end %}
exit 1
end
end
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/crystal/compiler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,10 @@ module Crystal
status = yield command, args

unless status.success?
msg = status.normal_exit? ? "code: #{status.exit_code}" : "signal: #{status.exit_signal} (#{status.exit_signal.value})"
msg = "code: #{status.exit_code}"
{% unless flag?(:win32) %}
msg = "signal: #{status.exit_signal} (#{status.exit_signal.value})" unless status.normal_exit?
{% end %}
code = status.normal_exit? ? status.exit_code : 1
error "execution of command failed with #{msg}: `#{command}`", exit_code: code
end
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/crystal/tools/playground/server.cr
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,10 @@ module Crystal::Playground
spawn do
status = process.wait
@logger.info "Code execution ended (session=#{@session_key}, tag=#{tag}, filename=#{output_filename})."
exit_status = status.normal_exit? ? status.exit_code : status.exit_signal.value
exit_status = status.exit_code
{% unless flag?(:win32) %}
exit_status = status.exit_signal.value unless status.normal_exit?
{% end %}

send_with_json_builder do |json|
json.field "type", "exit"
Expand Down
36 changes: 25 additions & 11 deletions src/process/status.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,40 @@ class Process::Status

# Returns `true` if the process was terminated by a signal.
def signal_exit?
# define __WIFSIGNALED(status) (((signed char) (((status) & 0x7f) + 1) >> 1) > 0)
((LibC::SChar.new(@exit_status & 0x7f) + 1) >> 1) > 0
{% unless flag?(:win32) %}
# define __WIFSIGNALED(status) (((signed char) (((status) & 0x7f) + 1) >> 1) > 0)
((LibC::SChar.new(@exit_status & 0x7f) + 1) >> 1) > 0
{% else %}
false
{% end %}
end

# Returns `true` if the process terminated normally.
def normal_exit?
# define __WIFEXITED(status) (__WTERMSIG(status) == 0)
signal_code == 0
{% unless flag?(:win32) %}
# define __WIFEXITED(status) (__WTERMSIG(status) == 0)
signal_code == 0
{% else %}
true
{% end %}
end

# If `signal_exit?` is `true`, returns the *Signal* the process
# received and didn't handle. Will raise if `signal_exit?` is `false`.
def exit_signal
Signal.from_value(signal_code)
end
{% unless flag?(:win32) %}
# If `signal_exit?` is `true`, returns the *Signal* the process
# received and didn't handle. Will raise if `signal_exit?` is `false`.
def exit_signal
Signal.from_value(signal_code)
end
{% end %}

# If `normal_exit?` is `true`, returns the exit code of the process.
def exit_code
# define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
(@exit_status & 0xff00) >> 8
{% unless flag?(:win32) %}
# define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
(@exit_status & 0xff00) >> 8
{% else %}
@exit_status
{% end %}
end

# Returns `true` if the process exited normally with an exit code of `0`.
Expand Down