ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ???????????????????????????????????? ???????????????????????????????????? ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ÿØÿà JFIF    ÿÛ „  ( %!1!%)+//.383,7(-.+  -%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ  ¥2" ÿÄ     ÿÄ J    ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ   ÿÄ *  !1AQa‘"2q3±ð#b¡ÿÚ   ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú "SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁT­ÃÛ5 ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßw­pŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e ríV ?> ......................................... ............................................................................. ???????????????????????????????????? ???????????????????????????????????? U:RDoc::AnyMethod[iI" popen3:ETI"Open3#popen3;TF: privateo:RDoc::Markup::Document: @parts[:o:RDoc::Markup::Paragraph; [I"Basically a wrapper for ;TI"-{Process.spawn}[rdoc-ref:Process.spawn] ;TI" that:;To:RDoc::Markup::BlankLineo:RDoc::Markup::List: @type: BULLET: @items[o:RDoc::Markup::ListItem: @label0; [o; ; [I"PCreates a child process, by calling Process.spawn with the given arguments.;To;;0; [o; ; [I"6Creates streams +stdin+, +stdout+, and +stderr+, ;TI"Owhich are the standard input, standard output, and standard error streams ;TI"in the child process.;To;;0; [o; ; [I"LCreates thread +wait_thread+ that waits for the child process to exit; ;TI"?the thread has method +pid+, which returns the process ID ;TI"of the child process.;T@o; ; [I",With no block given, returns the array ;TI"4[stdin, stdout, stderr, wait_thread]. ;TI"@The caller should close each of the three returned streams.;T@o:RDoc::Markup::Verbatim; [ I"?stdin, stdout, stderr, wait_thread = Open3.popen3('echo') ;TI"\# => [#, #, #, #] ;TI"stdin.close ;TI"stdout.close ;TI"stderr.close ;TI"$wait_thread.pid # => 2210481 ;TI"Cwait_thread.value # => # ;T: @format0o; ; [ I"AWith a block given, calls the block with the four variables ;TI")(three streams and the wait thread) ;TI"+and returns the block's return value. ;TI"+The caller need not close the streams:;T@o;; [ I"BOpen3.popen3('echo') do |stdin, stdout, stderr, wait_thread| ;TI" p stdin ;TI" p stdout ;TI" p stderr ;TI" p wait_thread ;TI" p wait_thread.pid ;TI" p wait_thread.value ;TI" end ;T;0o; ; [I" Output:;T@o;; [ I"# ;TI"# ;TI"# ;TI"1# ;TI" 2211047 ;TI",# ;T;0o; ; [I"LLike Process.spawn, this method has potential security vulnerabilities ;TI"%if called with untrusted input; ;TI"Psee {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].;T@o; ; [I"KUnlike Process.spawn, this method waits for the child process to exit ;TI"4before returning, so the caller need not do so.;T@o; ; [I"HIf the first argument is a hash, it becomes leading argument +env+ ;TI"#in the call to Process.spawn; ;TI"Isee {Execution Environment}[rdoc-ref:Process@Execution+Environment].;T@o; ; [I"LIf the last argument is a hash, it becomes trailing argument +options+ ;TI"#in the call to Process.spawn; ;TI"Asee {Execution Options}[rdoc-ref:Process@Execution+Options].;T@o; ; [I":The single required argument is one of the following:;T@o; ; ;;[o;;0; [o; ; [I"'+command_line+ if it is a string, ;TI"Fand if it begins with a shell reserved word or special built-in, ;TI"2or if it contains one or more metacharacters.;To;;0; [o; ; [I"+exe_path+ otherwise.;T@o; ; [I"#Argument +command_line+;T@o; ; [I"P\String argument +command_line+ is a command line to be passed to a shell; ;TI"Nit must begin with a shell reserved word, begin with a special built-in, ;TI" or contain meta characters:;T@o;; [I"[Open3.popen3('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. ;TI"POpen3.popen3('echo') {|*args| p args } # Built-in. ;TI"_Open3.popen3('date > date.tmp') {|*args| p args } # Contains meta character. ;T;0o; ; [I"*Output (similar for each call above):;T@o;; [I"b[#, #, #, #] ;T;0o; ; [I"MThe command line may also contain arguments and options for the command:;T@o;; [I"8Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets } ;TI" "Foo\n" ;T;0o; ; [I"Argument +exe_path+;T@o; ; [I"1Argument +exe_path+ is one of the following:;T@o; ; ;;[o;;0; [o; ; [I"3The string path to an executable to be called.;To;;0; [o; ; [I" "Wed Sep 27 02:56:44 PM CDT 2023\n" ;T;0o; ; [I"PRuby invokes the executable directly, with no shell and no shell expansion:;T@o;; [I"QOpen3.popen3('doesnt_exist') { |i, o, e, t| o.gets } # Raises Errno::ENOENT ;T;0o; ; [I"CIf one or more +args+ is given, each is an argument or option ;TI"$to be passed to the executable:;T@o;; [ I"9Open3.popen3('echo', 'C #') { |i, o, e, t| o.gets } ;TI"# => "C #\n" ;TI"DOpen3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets } ;TI"# => "hello world\n" ;T;0o; ; [ I"#Take care to avoid deadlocks. ;TI"COutput streams +stdout+ and +stderr+ have fixed-size buffers, ;TI"Lso reading extensively from one but not the other can cause a deadlock ;TI"#when the unread buffer fills. ;TI"HTo avoid that, +stdout+ and +stderr+ should be read simultaneously ;TI""(using threads or IO.select).;T@o; ; [I" Related:;T@o; ; ;;[o;;0; [o; ; [I"HOpen3.popen2: Makes the standard input and standard output streams ;TI"9of the child process available as separate streams, ;TI"1with no access to the standard error stream.;To;;0; [o; ; [I";Open3.popen2e: Makes the standard input and the merge ;TI"7of the standard output and standard error streams ;TI"8of the child process available as separate streams.;T: @fileI"lib/open3.rb;T:0@omit_headings_from_table_of_contents_below0I"Open3.popen3([env, ] command_line, options = {}) -> [stdin, stdout, stderr, wait_thread] Open3.popen3([env, ] exe_path, *args, options = {}) -> [stdin, stdout, stderr, wait_thread] Open3.popen3([env, ] command_line, options = {}) {|stdin, stdout, stderr, wait_thread| ... } -> object Open3.popen3([env, ] exe_path, *args, options = {}) {|stdin, stdout, stderr, wait_thread| ... } -> object ;T0[I"(*cmd, &block);T@FI" Open3;TcRDoc::NormalModule00