summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurdetteLamar <burdettelamar@yahoo.com>2023-09-28 14:23:10 -0500
committergit <svn-admin@ruby-lang.org>2023-09-28 20:15:58 +0000
commitef13a49a7f4ed755584484f32aac5885b5aa1a0c (patch)
tree8626199c73888faffabe9d4a9f4fea2d643a7365
parent3ec6be1a4b94eed7b16601617c7f8b5eb10793b5 (diff)
[ruby/open3] [DOC] RDoc for Open3
https://github.com/ruby/open3/commit/457cae3a51
-rw-r--r--lib/open3.rb155
1 files changed, 129 insertions, 26 deletions
diff --git a/lib/open3.rb b/lib/open3.rb
index c24c4cd44e..63f0a90fa9 100644
--- a/lib/open3.rb
+++ b/lib/open3.rb
@@ -111,7 +111,7 @@ module Open3
# Open3.popen3('echo') {|*args| p args } # Built-in.
# Open3.popen3('date > date.tmp') {|*args| p args } # Contains meta character.
#
- # Output (for each call above):
+ # Output (similar for each call above):
#
# [#<IO:(closed)>, #<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f58d52f28c8 dead>]
#
@@ -152,7 +152,15 @@ module Open3
# To avoid that, +stdout+ and +stderr+ should be read simultaneously
# (using threads or IO.select).
#
- # Related: Open3.popen2, Open3.popen2e.
+ # 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 popen3(*cmd, &block)
if Hash === cmd.last
opts = cmd.pop.dup
@@ -249,7 +257,7 @@ module Open3
# Open3.popen2('echo') {|*args| p args } # Built-in.
# Open3.popen2('date > date.tmp') {|*args| p args } # Contains meta character.
#
- # Output (for each call above):
+ # Output (similar for each call above):
#
# # => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577dfe410 dead>]
#
@@ -284,7 +292,15 @@ module Open3
# # => "hello world\n"
#
#
- # Related: Open3.popen3, Open3.popen2e.
+ # 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 popen2(*cmd, &block)
if Hash === cmd.last
opts = cmd.pop.dup
@@ -303,36 +319,123 @@ module Open3
end
module_function :popen2
- # Open3.popen2e is similar to Open3.popen3 except that it merges
- # the standard output stream and the standard error stream.
+ # :call-seq:
+ # Open3.popen2e([env, ] command_line, options = {}) -> [stdin, stdout_and_stderr, wait_thread]
+ # Open3.popen2e([env, ] exe_path, *args, options = {}) -> [stdin, stdout_and_stderr, wait_thread]
+ # Open3.popen2e([env, ] command_line, options = {}) {|stdin, stdout_and_stderr, wait_thread| ... } -> object
+ # Open3.popen2e([env, ] exe_path, *args, options = {}) {|stdin, stdout_and_stderr, wait_thread| ... } -> object
#
- # Block form:
+ # Basically a wrapper for Process.spawn that:
#
- # Open3.popen2e([env,] cmd... [, opts]) {|stdin, stdout_and_stderr, wait_thr|
- # pid = wait_thr.pid # pid of the started process.
- # ...
- # exit_status = wait_thr.value # Process::Status object returned.
- # }
+ # - 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.
#
- # Non-block form:
+ # With no block given, returns the array
+ # <tt>[stdin, stdout_and_stderr, wait_thread]</tt>.
+ # The caller should close each of the two returned streams.
#
- # stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts])
- # ...
- # stdin.close # stdin and stdout_and_stderr should be closed explicitly in this form.
+ # stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo')
+ # # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f7577da4398 run>]
+ # stdin.close
# stdout_and_stderr.close
+ # wait_thread.pid # => 2274600
+ # wait_thread.value # => #<Process::Status: pid 2274600 exit 0>
+ #
+ # 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:
#
- # See Process.spawn for the optional hash arguments _env_ and _opts_.
+ # 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:
+ #
+ # #<IO:fd 6>
+ # #<IO:fd 7>
+ # #<Process::Waiter:0x00007f75777578c8 sleep>
+ # 2274763
+ # #<Process::Status: pid 2274763 exit 0>
+ #
+ # Like Process.spawn, this method has potential security vulnerabilities
+ # if called with untrusted input;
+ # see {Command Injection}[rdoc-ref:command_injection.rdoc].
+ #
+ # Unlike Process.spawn, this method waits for the child process to exit
+ # before returning, so the caller need not do so.
+ #
+ # Argument +options+ is a hash of options for the new process;
+ # 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.
+ #
+ # <b>Argument +command_line+</b>
+ #
+ # \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):
+ #
+ # # => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577d8a1f0 dead>]
+ #
+ # 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"
+ #
+ # <b>Argument +exe_path+</b>
+ #
+ # 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:
- # # check gcc warnings
- # source = "foo.c"
- # Open3.popen2e("gcc", "-Wall", source) {|i,oe,t|
- # oe.each {|line|
- # if /warning/ =~ line
- # ...
- # end
- # }
- # }
+ #
+ # 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 popen2e(*cmd, &block)
if Hash === cmd.last