Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion src/crystal/system/process.cr
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct Crystal::System::Process
# def self.spawn(command_args : Args, env : Env?, clear_env : Bool, input : Stdio, output : Stdio, error : Stdio, chdir : Path | String?) : ProcessInformation

# Replaces the current process with a new one.
# def self.replace(command_args : Args, env : Env?, clear_env : Bool, input : Stdio, output : Stdio, error : Stdio, chdir : Path | String?) : NoReturn
# def self.replace(command : String, command_args : Args, env : Env?, clear_env : Bool, input : Stdio, output : Stdio, error : Stdio, chdir : Path | String?) : NoReturn

# Converts a command and array of arguments to the system-specific representation.
# def self.prepare_args(command : String, args : Enumerable(String)?, shell : Bool) : Args
Expand Down
28 changes: 14 additions & 14 deletions src/crystal/system/unix/process.cr
Original file line number Diff line number Diff line change
Expand Up @@ -307,25 +307,27 @@ struct Crystal::System::Process
pid
end

def self.prepare_args(command : String, args : Enumerable(String)?, shell : Bool) : Array(String)
def self.prepare_args(command : String, args : Enumerable(String)?, shell : Bool) : {String, UInt8**}
if shell
command = %(#{command} "${@}") unless command.includes?(' ')
shell_args = ["/bin/sh", "-c", command, "sh"]
argv_ary = ["/bin/sh", "-c", command, "sh"]

if args
unless command.includes?(%("${@}"))
raise ArgumentError.new(%(Can't specify arguments in both command and args without including "${@}" into your command))
end

shell_args.concat(args)
end

shell_args
pathname = "/bin/sh"
else
command_args = [command]
command_args.concat(args) if args
command_args
argv_ary = [command]
pathname = command
end

argv_ary.concat(args) if args

argv = argv_ary.map(&.check_no_null_byte.to_unsafe)
{pathname, argv.to_unsafe}
end

private def self.try_replace(command_args, env, clear_env, input, output, error, chdir)
Expand All @@ -344,16 +346,14 @@ struct Crystal::System::Process

::Dir.cd(chdir) if chdir

command = command_args[0]
argv = command_args.map &.check_no_null_byte.to_unsafe
argv << Pointer(UInt8).null
pathname, argv = command_args

lock_write { LibC.execvp(command, argv) }
lock_write { LibC.execvp(pathname, argv) }
end

def self.replace(command_args, env, clear_env, input, output, error, chdir)
def self.replace(command, command_args, env, clear_env, input, output, error, chdir)
try_replace(command_args, env, clear_env, input, output, error, chdir)
raise_exception_from_errno(command_args[0])
raise_exception_from_errno(command)
end

private def self.raise_exception_from_errno(command, errno = Errno.value)
Expand Down
2 changes: 1 addition & 1 deletion src/crystal/system/wasi/process.cr
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ struct Crystal::System::Process
raise NotImplementedError.new("Process.prepare_args")
end

def self.replace(command_args, env, clear_env, input, output, error, chdir)
def self.replace(command, command_args, env, clear_env, input, output, error, chdir)
raise NotImplementedError.new("Process.replace")
end

Expand Down
6 changes: 3 additions & 3 deletions src/crystal/system/win32/process.cr
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ struct Crystal::System::Process
end
end

private def self.try_replace(command_args, env, clear_env, input, output, error, chdir)
private def self.try_replace(command, command_args, env, clear_env, input, output, error, chdir)
old_input_fd = reopen_io(input, ORIGINAL_STDIN)
old_output_fd = reopen_io(output, ORIGINAL_STDOUT)
old_error_fd = reopen_io(error, ORIGINAL_STDERR)
Expand Down Expand Up @@ -378,8 +378,8 @@ struct Crystal::System::Process
errno
end

def self.replace(command_args, env, clear_env, input, output, error, chdir) : NoReturn
errno = try_replace(command_args, env, clear_env, input, output, error, chdir)
def self.replace(command, command_args, env, clear_env, input, output, error, chdir) : NoReturn
errno = try_replace(command, command_args, env, clear_env, input, output, error, chdir)
raise_exception_from_errno(command_args.is_a?(String) ? command_args : command_args[0], errno)
end

Expand Down
2 changes: 1 addition & 1 deletion src/process.cr
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class Process
output = exec_stdio_to_fd(output, for: STDOUT)
error = exec_stdio_to_fd(error, for: STDERR)

Crystal::System::Process.replace(command_args, env, clear_env, input, output, error, chdir)
Crystal::System::Process.replace(command, command_args, env, clear_env, input, output, error, chdir)
end

private def self.exec_stdio_to_fd(stdio : ExecStdio, for dst_io : IO::FileDescriptor) : IO::FileDescriptor
Expand Down