diff --git a/core/io.rbs b/core/io.rbs index 0284fecde..879dd27db 100644 --- a/core/io.rbs +++ b/core/io.rbs @@ -1802,8 +1802,8 @@ class IO < Object # * [Open Options](rdoc-ref:IO@Open+Options). # * [Encoding options](rdoc-ref:encodings.rdoc@Encoding+Options). # - def reopen: (IO other_IO_or_path) -> IO - | (String other_IO_or_path, ?String mode_str) -> IO + def reopen: (IO other_IO_or_path, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: Strin) -> IO + | (String other_IO_or_path, ?string | int mode_str, ?external_encoding: String | Encoding | nil, ?internal_encoding: String | Encoding | nil, ?encoding: String | Encoding | nil, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?mode: Strin) -> IO # + # Basically a wrapper for Open3.popen3 that: + # + # * Creates a child process, by calling Open3.popen3 with the given arguments + # (except for certain entries in hash `options`; see below). + # * Returns as string `stdout_s` the standard output of the child process. + # * Returns as `status` a `Process::Status` object that represents the exit + # status of the child process. + # + # Returns the array `[stdout_s, status]`: + # + # stdout_s, status = Open3.capture2('echo "Foo"') + # # => ["Foo\n", #] + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # Unlike Process.spawn, this method waits for the child process to exit before + # returning, so the caller need not do so. + # + # If the first argument is a hash, it becomes leading argument `env` in the call + # to Open3.popen3; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in the + # call to Open3.popen3; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # The hash `options` is given; two options have local effect in method + # Open3.capture2: + # + # * If entry `options[:stdin_data]` exists, the entry is removed and its + # string value is sent to the command's standard input: + # + # Open3.capture2('tee', stdin_data: 'Foo') + # + # # => ["Foo", #] + # + # * If entry `options[:binmode]` exists, the entry is removed and the internal + # streams are set to binary mode. + # + # The single required argument is one of the following: + # + # * `command_line` if it is a string, and if it begins with a shell reserved + # word or special built-in, or if it contains one or more metacharacters. + # * `exe_path` otherwise. + # + # **Argument `command_line`** + # + # String argument `command_line` is a command line to be passed to a shell; it + # must begin with a shell reserved word, begin with a special built-in, or + # contain meta characters: + # + # Open3.capture2('if true; then echo "Foo"; fi') # Shell reserved word. + # # => ["Foo\n", #] + # Open3.capture2('echo') # Built-in. + # # => ["\n", #] + # Open3.capture2('date > date.tmp') # Contains meta character. + # # => ["", #] + # + # The command line may also contain arguments and options for the command: + # + # Open3.capture2('echo "Foo"') + # # => ["Foo\n", #] + # + # **Argument `exe_path`** + # + # Argument `exe_path` is one of the following: + # + # * The string path to an executable to be called. + # * A 2-element array containing the path to an executable and the string to + # be used as the name of the executing process. + # + # Example: + # + # Open3.capture2('/usr/bin/date') + # # => ["Fri Sep 29 01:00:39 PM CDT 2023\n", #] + # + # Ruby invokes the executable directly, with no shell and no shell expansion: + # + # Open3.capture2('doesnt_exist') # Raises Errno::ENOENT + # + # If one or more `args` is given, each is an argument or option to be passed to + # the executable: + # + # Open3.capture2('echo', 'C #') + # # => ["C #\n", #] + # Open3.capture2('echo', 'hello', 'world') + # # => ["hello world\n", #] + # + def self.capture2: (?Hash[String, String] env, *String cmds, ?Hash[untyped, untyped] options) -> [IO, Process::Status] + # + # Basically a wrapper for Open3.popen3 that: + # + # * Creates a child process, by calling Open3.popen3 with the given arguments + # (except for certain entries in hash `options`; see below). + # * Returns as strings `stdout_s` and `stderr_s` the standard output and + # standard error of the child process. + # * Returns as `status` a `Process::Status` object that represents the exit + # status of the child process. + # + # Returns the array `[stdout_s, stderr_s, status]`: + # + # stdout_s, stderr_s, status = Open3.capture3('echo "Foo"') + # # => ["Foo\n", "", #] + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # Unlike Process.spawn, this method waits for the child process to exit before + # returning, so the caller need not do so. + # + # If the first argument is a hash, it becomes leading argument `env` in the call + # to Open3.popen3; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in the + # call to Open3.popen3; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # The hash `options` is given; two options have local effect in method + # Open3.capture3: + # + # * If entry `options[:stdin_data]` exists, the entry is removed and its + # string value is sent to the command's standard input: + # + # Open3.capture3('tee', stdin_data: 'Foo') + # # => ["Foo", "", #] + # + # * If entry `options[:binmode]` exists, the entry is removed and the internal + # streams are set to binary mode. + # + # The single required argument is one of the following: + # + # * `command_line` if it is a string, and if it begins with a shell reserved + # word or special built-in, or if it contains one or more metacharacters. + # * `exe_path` otherwise. + # + # **Argument `command_line`** + # + # String argument `command_line` is a command line to be passed to a shell; it + # must begin with a shell reserved word, begin with a special built-in, or + # contain meta characters: + # + # Open3.capture3('if true; then echo "Foo"; fi') # Shell reserved word. + # # => ["Foo\n", "", #] + # Open3.capture3('echo') # Built-in. + # # => ["\n", "", #] + # Open3.capture3('date > date.tmp') # Contains meta character. + # # => ["", "", #] + # + # The command line may also contain arguments and options for the command: + # + # Open3.capture3('echo "Foo"') + # # => ["Foo\n", "", #] + # + # **Argument `exe_path`** + # + # Argument `exe_path` is one of the following: + # + # * The string path to an executable to be called. + # * A 2-element array containing the path to an executable and the string to + # be used as the name of the executing process. + # + # Example: + # + # Open3.capture3('/usr/bin/date') + # # => ["Thu Sep 28 05:03:51 PM CDT 2023\n", "", #] + # + # Ruby invokes the executable directly, with no shell and no shell expansion: + # + # Open3.capture3('doesnt_exist') # Raises Errno::ENOENT + # + # If one or more `args` is given, each is an argument or option to be passed to + # the executable: + # + # Open3.capture3('echo', 'C #') + # # => ["C #\n", "", #] + # Open3.capture3('echo', 'hello', 'world') + # # => ["hello world\n", "", #] + # + def self.capture3: (?Hash[String, String] env, *String cmds, ?Hash[untyped, untyped] options) -> [IO, IO, Process::Status] + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process for each of the given `cmds` by calling + # Process.spawn. + # * Pipes the `stdout` from each child to the `stdin` of the next child, or, + # for the last child, to the caller's `stdout`. + # * Waits for the child processes to exit. + # * Returns an array of Process::Status objects (one for each child). + # + # Example: + # + # wait_threads = Open3.pipeline('ls', 'grep R') + # # => [#, #] + # + # Output: + # + # Rakefile + # README.md + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # If the first argument is a hash, it becomes leading argument `env` in each + # call to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in each + # call to Process.spawn' see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # Each remaining argument in `cmds` is one of: + # + # * A `command_line`: a string that begins with a shell reserved word or + # special built-in, or contains one or more metacharacters. + # * An `exe_path`: the string path to an executable to be called. + # * An array containing a `command_line` or an `exe_path`, along with zero or + # more string arguments for the command. + # + # See [Argument command_line or + # exe_path](rdoc-ref:Process@Argument+command_line+or+exe_path). + # + def self.pipeline: (?Hash[String, String] env, *String cmds, ?Hash[untyped, untyped] options) -> Array[Process::Status] + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process for each of the given `cmds` by calling + # Process.spawn. + # * Pipes the `stdout` from each child to the `stdin` of the next child, or, + # for the last child, to the caller's `stdout`. + # + # The method does not wait for child processes to exit, so the caller must do + # so. + # + # With no block given, returns a 2-element array containing: + # + # * The `stdout` stream of the last child process. + # * An array of the wait threads for all of the child processes. + # + # Example: + # + # last_stdout, wait_threads = Open3.pipeline_r('ls', 'grep R') + # # => [#, [#, #]] + # puts last_stdout.read + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # + # Output: + # + # Rakefile + # README.md + # + # With a block given, calls the block with the `stdout` stream of the last child + # process, and an array of the wait processes: + # + # Open3.pipeline_r('ls', 'grep R') do |last_stdout, wait_threads| + # puts last_stdout.read + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # end + # + # Output: + # + # Rakefile + # README.md + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # If the first argument is a hash, it becomes leading argument `env` in each + # call to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in each + # call to Process.spawn; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # Each remaining argument in `cmds` is one of: + # + # * A `command_line`: a string that begins with a shell reserved word or + # special built-in, or contains one or more metacharacters. + # * An `exe_path`: the string path to an executable to be called. + # * An array containing a `command_line` or an `exe_path`, along with zero or + # more string arguments for the command. + # + # See [Argument command_line or + # exe_path](rdoc-ref:Process@Argument+command_line+or+exe_path). + # + def self.pipeline_r: (?Hash[String, String] env, *String cmds, ?Hash[untyped, untyped] options) -> [IO, Process::Waiter] + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process for each of the given `cmds` by calling + # Process.spawn. + # * Pipes the `stdout` from each child to the `stdin` of the next child, or, + # for the first child, from the caller's `stdin`, or, for the last child, to + # the caller's `stdout`. + # + # The method does not wait for child processes to exit, so the caller must do + # so. + # + # With no block given, returns a 3-element array containing: + # + # * The `stdin` stream of the first child process. + # * The `stdout` stream of the last child process. + # * An array of the wait threads for all of the child processes. + # + # Example: + # + # first_stdin, last_stdout, wait_threads = Open3.pipeline_rw('sort', 'cat -n') + # # => [#, #, [#, #]] + # first_stdin.puts("foo\nbar\nbaz") + # first_stdin.close # Send EOF to sort. + # puts last_stdout.read + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # + # Output: + # + # 1 bar + # 2 baz + # 3 foo + # + # With a block given, calls the block with the `stdin` stream of the first + # child, the `stdout` stream of the last child, and an array of the wait + # processes: + # + # Open3.pipeline_rw('sort', 'cat -n') do |first_stdin, last_stdout, wait_threads| + # first_stdin.puts "foo\nbar\nbaz" + # first_stdin.close # send EOF to sort. + # puts last_stdout.read + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # end + # + # Output: + # + # 1 bar + # 2 baz + # 3 foo + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # If the first argument is a hash, it becomes leading argument `env` in each + # call to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in each + # call to Process.spawn; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # Each remaining argument in `cmds` is one of: + # + # * A `command_line`: a string that begins with a shell reserved word or + # special built-in, or contains one or more metacharacters. + # * An `exe_path`: the string path to an executable to be called. + # * An array containing a `command_line` or an `exe_path`, along with zero or + # more string arguments for the command. + # + # See [Argument command_line or + # exe_path](rdoc-ref:Process@Argument+command_line+or+exe_path). + # + def self.pipeline_rw: (?Hash[String, String] env, *String cmds, ?Hash[untyped, untyped] options) -> [IO, IO, Process::Waiter] + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process for each of the given `cmds` by calling + # Process.spawn. + # * Does not wait for child processes to exit. + # + # With no block given, returns an array of the wait threads for all of the child + # processes. + # + # Example: + # + # wait_threads = Open3.pipeline_start('ls', 'grep R') + # # => [#, #] + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # + # Output: + # + # Rakefile + # README.md + # + # With a block given, calls the block with an array of the wait processes: + # + # Open3.pipeline_start('ls', 'grep R') do |wait_threads| + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # end + # + # Output: + # + # Rakefile + # README.md + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # If the first argument is a hash, it becomes leading argument `env` in each + # call to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in each + # call to Process.spawn; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # Each remaining argument in `cmds` is one of: + # + # * A `command_line`: a string that begins with a shell reserved word or + # special built-in, or contains one or more metacharacters. + # * An `exe_path`: the string path to an executable to be called. + # * An array containing a `command_line` or an `exe_path`, along with zero or + # more string arguments for the command. + # + # See [Argument command_line or + # exe_path](rdoc-ref:Process@Argument+command_line+or+exe_path). + # + def self.pipeline_start: (?Hash[String, String] env, *String cmds, ?Hash[untyped, untyped] options) -> Array[Process::Waiter] + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process for each of the given `cmds` by calling + # Process.spawn. + # * Pipes the `stdout` from each child to the `stdin` of the next child, or, + # for the first child, pipes the caller's `stdout` to the child's `stdin`. + # + # The method does not wait for child processes to exit, so the caller must do + # so. + # + # With no block given, returns a 2-element array containing: + # + # * The `stdin` stream of the first child process. + # * An array of the wait threads for all of the child processes. + # + # Example: + # + # first_stdin, wait_threads = Open3.pipeline_w('sort', 'cat -n') + # # => [#, [#, #]] + # first_stdin.puts("foo\nbar\nbaz") + # first_stdin.close # Send EOF to sort. + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # + # Output: + # + # 1 bar + # 2 baz + # 3 foo + # + # With a block given, calls the block with the `stdin` stream of the first child + # process, and an array of the wait processes: + # + # Open3.pipeline_w('sort', 'cat -n') do |first_stdin, wait_threads| + # first_stdin.puts("foo\nbar\nbaz") + # first_stdin.close # Send EOF to sort. + # wait_threads.each do |wait_thread| + # wait_thread.join + # end + # end + # + # Output: + # + # 1 bar + # 2 baz + # 3 foo + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # If the first argument is a hash, it becomes leading argument `env` in each + # call to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in each + # call to Process.spawn; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # Each remaining argument in `cmds` is one of: + # + # * A `command_line`: a string that begins with a shell reserved word or + # special built-in, or contains one or more metacharacters. + # * An `exe_path`: the string path to an executable to be called. + # * An array containing a `command_line` or an `exe_path`, along with zero or + # more string arguments for the command. + # + # See [Argument command_line or + # exe_path](rdoc-ref:Process@Argument+command_line+or+exe_path). + # + def self.pipeline_w: (?Hash[String, String] env, *String cmds, ?Hash[untyped, untyped] options) -> [IO, Process::Waiter] + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process, by calling Process.spawn with the given + # arguments. + # * Creates streams `stdin` and `stdout`, which are the standard input and + # standard output streams in the child process. + # * Creates thread `wait_thread` that waits for the child process to exit; the + # thread has method `pid`, which returns the process ID of the child + # process. + # + # With no block given, returns the array `[stdin, stdout, wait_thread]`. The + # caller should close each of the two returned streams. + # + # stdin, stdout, wait_thread = Open3.popen2('echo') + # # => [#, #, #] + # stdin.close + # stdout.close + # wait_thread.pid # => 2263572 + # wait_thread.value # => # + # + # With a block given, calls the block with the three variables (two streams and + # the wait thread) and returns the block's return value. The caller need not + # close the streams: + # + # Open3.popen2('echo') do |stdin, stdout, wait_thread| + # p stdin + # p stdout + # p wait_thread + # p wait_thread.pid + # p wait_thread.value + # end + # + # Output: + # + # # + # # + # # + # 2263636 + # # + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # Unlike Process.spawn, this method waits for the child process to exit before + # returning, so the caller need not do so. + # + # If the first argument is a hash, it becomes leading argument `env` in the call + # to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in the + # call to Process.spawn; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # The single required argument is one of the following: + # + # * `command_line` if it is a string, and if it begins with a shell reserved + # word or special built-in, or if it contains one or more metacharacters. + # * `exe_path` otherwise. + # + # **Argument `command_line`** + # + # String argument `command_line` is a command line to be passed to a shell; it + # must begin with a shell reserved word, begin with a special built-in, or + # contain meta characters: + # + # Open3.popen2('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. + # Open3.popen2('echo') {|*args| p args } # Built-in. + # Open3.popen2('date > date.tmp') {|*args| p args } # Contains meta character. + # + # Output (similar for each call above): + # + # # => [#, #, #] + # + # The command line may also contain arguments and options for the command: + # + # Open3.popen2('echo "Foo"') { |i, o, t| o.gets } + # "Foo\n" + # + # **Argument `exe_path`** + # + # Argument `exe_path` is one of the following: + # + # * The string path to an executable to be called. + # * A 2-element array containing the path to an executable and the string to + # be used as the name of the executing process. + # + # Example: + # + # Open3.popen2('/usr/bin/date') { |i, o, t| o.gets } + # # => "Thu Sep 28 09:41:06 AM CDT 2023\n" + # + # Ruby invokes the executable directly, with no shell and no shell expansion: + # + # Open3.popen2('doesnt_exist') { |i, o, t| o.gets } # Raises Errno::ENOENT + # + # If one or more `args` is given, each is an argument or option to be passed to + # the executable: + # + # Open3.popen2('echo', 'C #') { |i, o, t| o.gets } + # # => "C #\n" + # Open3.popen2('echo', 'hello', 'world') { |i, o, t| o.gets } + # # => "hello world\n" + # + # Related: + # + # * Open3.popen2e: Makes the standard input and the merge of the standard + # output and standard error streams of the child process available as + # separate streams. + # * Open3.popen3: Makes the standard input, standard output, and standard + # error streams of the child process available as separate streams. + # + def self.popen2: (?Hash[String, String] env, *String exe_path_or_cmd_with_args, ?Hash[untyped, untyped] options) -> [IO, IO, Process::Waiter] + | [U] (?Hash[String, String] env, *String exe_path_or_cmd_with_args, ?Hash[untyped, untyped] options) { (IO stdin, IO stdout, Process::Waiter wait_thread) -> U } -> U + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process, by calling Process.spawn with the given + # arguments. + # * Creates streams `stdin`, `stdout_and_stderr`, which are the standard input + # and the merge of the standard output and standard error streams in the + # child process. + # * Creates thread `wait_thread` that waits for the child process to exit; the + # thread has method `pid`, which returns the process ID of the child + # process. + # + # With no block given, returns the array `[stdin, stdout_and_stderr, + # wait_thread]`. The caller should close each of the two returned streams. + # + # stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo') + # # => [#, #, #] + # stdin.close + # stdout_and_stderr.close + # wait_thread.pid # => 2274600 + # wait_thread.value # => # + # + # With a block given, calls the block with the three variables (two streams and + # the wait thread) and returns the block's return value. The caller need not + # close the streams: + # + # Open3.popen2e('echo') do |stdin, stdout_and_stderr, wait_thread| + # p stdin + # p stdout_and_stderr + # p wait_thread + # p wait_thread.pid + # p wait_thread.value + # end + # + # Output: + # + # # + # # + # # + # 2274763 + # # + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # Unlike Process.spawn, this method waits for the child process to exit before + # returning, so the caller need not do so. + # + # If the first argument is a hash, it becomes leading argument `env` in the call + # to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in the + # call to Process.spawn; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # The single required argument is one of the following: + # + # * `command_line` if it is a string, and if it begins with a shell reserved + # word or special built-in, or if it contains one or more metacharacters. + # * `exe_path` otherwise. + # + # **Argument `command_line`** + # + # String argument `command_line` is a command line to be passed to a shell; it + # must begin with a shell reserved word, begin with a special built-in, or + # contain meta characters: + # + # Open3.popen2e('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. + # Open3.popen2e('echo') {|*args| p args } # Built-in. + # Open3.popen2e('date > date.tmp') {|*args| p args } # Contains meta character. + # + # Output (similar for each call above): + # + # # => [#, #, #] + # + # The command line may also contain arguments and options for the command: + # + # Open3.popen2e('echo "Foo"') { |i, o_and_e, t| o_and_e.gets } + # "Foo\n" + # + # **Argument `exe_path`** + # + # Argument `exe_path` is one of the following: + # + # * The string path to an executable to be called. + # * A 2-element array containing the path to an executable and the string to + # be used as the name of the executing process. + # + # Example: + # + # Open3.popen2e('/usr/bin/date') { |i, o_and_e, t| o_and_e.gets } + # # => "Thu Sep 28 01:58:45 PM CDT 2023\n" + # + # Ruby invokes the executable directly, with no shell and no shell expansion: + # + # Open3.popen2e('doesnt_exist') { |i, o_and_e, t| o_and_e.gets } # Raises Errno::ENOENT + # + # If one or more `args` is given, each is an argument or option to be passed to + # the executable: + # + # Open3.popen2e('echo', 'C #') { |i, o_and_e, t| o_and_e.gets } + # # => "C #\n" + # Open3.popen2e('echo', 'hello', 'world') { |i, o_and_e, t| o_and_e.gets } + # # => "hello world\n" + # + # Related: + # + # * Open3.popen2: Makes the standard input and standard output streams of the + # child process available as separate streams, with no access to the + # standard error stream. + # * Open3.popen3: Makes the standard input, standard output, and standard + # error streams of the child process available as separate streams. + # + def self.popen2e: (?Hash[String, String] env, *String exe_path_or_cmd_with_args, ?Hash[untyped, untyped] options) -> [IO, IO, Process::Waiter] + | [U] (?Hash[String, String] env, *String exe_path_or_cmd_with_args, ?Hash[untyped, untyped] options) { (IO stdin, IO stdout_and_stderr, Process::Waiter wait_thread) -> U } -> U + + # + # Basically a wrapper for [Process.spawn](rdoc-ref:Process.spawn) that: + # + # * Creates a child process, by calling Process.spawn with the given + # arguments. + # * Creates streams `stdin`, `stdout`, and `stderr`, which are the standard + # input, standard output, and standard error streams in the child process. + # * Creates thread `wait_thread` that waits for the child process to exit; the + # thread has method `pid`, which returns the process ID of the child + # process. + # + # With no block given, returns the array `[stdin, stdout, stderr, wait_thread]`. + # The caller should close each of the three returned streams. + # + # stdin, stdout, stderr, wait_thread = Open3.popen3('echo') + # # => [#, #, #, #] + # stdin.close + # stdout.close + # stderr.close + # wait_thread.pid # => 2210481 + # wait_thread.value # => # + # + # With a block given, calls the block with the four variables (three streams and + # the wait thread) and returns the block's return value. The caller need not + # close the streams: + # + # Open3.popen3('echo') do |stdin, stdout, stderr, wait_thread| + # p stdin + # p stdout + # p stderr + # p wait_thread + # p wait_thread.pid + # p wait_thread.value + # end + # + # Output: + # + # # + # # + # # + # # + # 2211047 + # # + # + # Like Process.spawn, this method has potential security vulnerabilities if + # called with untrusted input; see [Command + # Injection](rdoc-ref:command_injection.rdoc@Command+Injection). + # + # Unlike Process.spawn, this method waits for the child process to exit before + # returning, so the caller need not do so. + # + # If the first argument is a hash, it becomes leading argument `env` in the call + # to Process.spawn; see [Execution + # Environment](rdoc-ref:Process@Execution+Environment). + # + # If the last argument is a hash, it becomes trailing argument `options` in the + # call to Process.spawn; see [Execution + # Options](rdoc-ref:Process@Execution+Options). + # + # The single required argument is one of the following: + # + # * `command_line` if it is a string, and if it begins with a shell reserved + # word or special built-in, or if it contains one or more metacharacters. + # * `exe_path` otherwise. + # + # **Argument `command_line`** + # + # String argument `command_line` is a command line to be passed to a shell; it + # must begin with a shell reserved word, begin with a special built-in, or + # contain meta characters: + # + # Open3.popen3('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. + # Open3.popen3('echo') {|*args| p args } # Built-in. + # Open3.popen3('date > date.tmp') {|*args| p args } # Contains meta character. + # + # Output (similar for each call above): + # + # [#, #, #, #] + # + # The command line may also contain arguments and options for the command: + # + # Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets } + # "Foo\n" + # + # **Argument `exe_path`** + # + # Argument `exe_path` is one of the following: + # + # * The string path to an executable to be called. + # * A 2-element array containing the path to an executable and the string to + # be used as the name of the executing process. + # + # Example: + # + # Open3.popen3('/usr/bin/date') { |i, o, e, t| o.gets } + # # => "Wed Sep 27 02:56:44 PM CDT 2023\n" + # + # Ruby invokes the executable directly, with no shell and no shell expansion: + # + # Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets } # Raises Errno::ENOENT + # + # If one or more `args` is given, each is an argument or option to be passed to + # the executable: + # + # Open3.popen3('echo', 'C #') { |i, o, e, t| o.gets } + # # => "C #\n" + # Open3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets } + # # => "hello world\n" + # + # Take care to avoid deadlocks. Output streams `stdout` and `stderr` have + # fixed-size buffers, so reading extensively from one but not the other can + # cause a deadlock when the unread buffer fills. To avoid that, `stdout` and + # `stderr` should be read simultaneously (using threads or IO.select). + # + # Related: + # + # * Open3.popen2: Makes the standard input and standard output streams of the + # child process available as separate streams, with no access to the + # standard error stream. + # * Open3.popen2e: Makes the standard input and the merge of the standard + # output and standard error streams of the child process available as + # separate streams. + # + def self.popen3: (?Hash[String, String] env, *String exe_path_or_cmd_with_args, ?Hash[untyped, untyped] options) -> [IO, IO, IO, Process::Waiter] + | [U] (?Hash[String, String] env, *String exe_path_or_cmd_with_args, ?Hash[untyped, untyped] options) { (IO stdin, IO stdout, IO stderr, Process::Waiter wait_thread) -> U } -> U + + VERSION: ::String end