childprocess 0.5.9 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.document +6 -6
  3. data/.gitignore +25 -25
  4. data/.rspec +1 -1
  5. data/.travis.yml +20 -18
  6. data/CHANGELOG.md +8 -0
  7. data/Gemfile +11 -4
  8. data/LICENSE +20 -20
  9. data/README.md +178 -178
  10. data/Rakefile +61 -61
  11. data/childprocess.gemspec +30 -29
  12. data/lib/childprocess.rb +184 -177
  13. data/lib/childprocess/abstract_io.rb +36 -36
  14. data/lib/childprocess/abstract_process.rb +187 -187
  15. data/lib/childprocess/errors.rb +26 -26
  16. data/lib/childprocess/jruby.rb +56 -56
  17. data/lib/childprocess/jruby/io.rb +16 -16
  18. data/lib/childprocess/jruby/process.rb +159 -159
  19. data/lib/childprocess/jruby/pump.rb +52 -52
  20. data/lib/childprocess/tools/generator.rb +145 -145
  21. data/lib/childprocess/unix.rb +9 -9
  22. data/lib/childprocess/unix/fork_exec_process.rb +70 -70
  23. data/lib/childprocess/unix/io.rb +21 -21
  24. data/lib/childprocess/unix/lib.rb +186 -186
  25. data/lib/childprocess/unix/platform/i386-linux.rb +12 -12
  26. data/lib/childprocess/unix/platform/i386-solaris.rb +11 -11
  27. data/lib/childprocess/unix/platform/x86_64-linux.rb +12 -12
  28. data/lib/childprocess/unix/platform/x86_64-macosx.rb +11 -11
  29. data/lib/childprocess/unix/posix_spawn_process.rb +134 -134
  30. data/lib/childprocess/unix/process.rb +89 -89
  31. data/lib/childprocess/version.rb +3 -3
  32. data/lib/childprocess/windows.rb +33 -33
  33. data/lib/childprocess/windows/handle.rb +91 -91
  34. data/lib/childprocess/windows/io.rb +25 -25
  35. data/lib/childprocess/windows/lib.rb +415 -415
  36. data/lib/childprocess/windows/process.rb +129 -129
  37. data/lib/childprocess/windows/process_builder.rb +174 -174
  38. data/lib/childprocess/windows/structs.rb +148 -148
  39. data/spec/abstract_io_spec.rb +12 -12
  40. data/spec/childprocess_spec.rb +291 -256
  41. data/spec/io_spec.rb +228 -228
  42. data/spec/jruby_spec.rb +24 -24
  43. data/spec/pid_behavior.rb +12 -12
  44. data/spec/spec_helper.rb +253 -253
  45. data/spec/unix_spec.rb +57 -57
  46. data/spec/windows_spec.rb +23 -23
  47. metadata +47 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a01a1e0a06d2a6a7f18c576a48d11aa4bd78437
4
- data.tar.gz: 4ad6d15fa3e38aa45d244533a617abb87af294d0
3
+ metadata.gz: ddee2715001c0588975716a640ae4318074657c8
4
+ data.tar.gz: 80beab872ef52ae9818ff1d87d283cf726ad0cb5
5
5
  SHA512:
6
- metadata.gz: 67274313c2d786c42f637b597048138b5f9a0739779bb751c41ea14a1299e255310eff32abb75c93e022a4db785d2fb2368f11db9992d627b761f12364078b08
7
- data.tar.gz: 4eda72acc23b6b4fefe76d6be567f8b2a7c047eca9e4cf967bc3a03d64b1f749edc65c0266e91a3f8eb19bf0c255b9bcc8d25b9fc19838d4af07ec8874b83d86
6
+ metadata.gz: b4ef32eedda3e6e84810f01fe4dd5a4f3adfe2faf35bc74fbb2f4130248d0295d3ac2c0855d3625f47492fe355e98d43ef4a7d4897eca60f5e8a654ec806fec9
7
+ data.tar.gz: e067faf2d9cf1d14e1367cc3afbca08754de15bd1360b09343455efdf59498acf4066d43603719a6ac74053d1a9d9c790ad67a60ff949db223b89b8c33ad9d14
data/.document CHANGED
@@ -1,6 +1,6 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- -
6
- LICENSE
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ -
6
+ LICENSE
data/.gitignore CHANGED
@@ -1,25 +1,25 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
- .rbx
21
- Gemfile.lock
22
- .ruby-version
23
- .bundle
24
-
25
- ## PROJECT::SPECIFIC
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ .rbx
21
+ Gemfile.lock
22
+ .ruby-version
23
+ .bundle
24
+
25
+ ## PROJECT::SPECIFIC
data/.rspec CHANGED
@@ -1 +1 @@
1
- --color
1
+ --color
@@ -1,18 +1,20 @@
1
- rvm:
2
- - 1.9.3
3
- - jruby
4
- - rbx
5
- - 2.0.0
6
- - 2.1.0
7
- - ruby-head
8
- sudo: false
9
- cache: bundler
10
- env:
11
- - CHILDPROCESS_POSIX_SPAWN=true CHILDPROCESS_UNSET=should-be-unset
12
- - CHILDPROCESS_POSIX_SPAWN=false CHILDPROCESS_UNSET=should-be-unset
13
- matrix:
14
- allow_failures:
15
- - rvm: rbx
16
- - rvm: ruby-head
17
- - rvm: 2.1.0
18
- env: "CHILDPROCESS_POSIX_SPAWN=true"
1
+ rvm:
2
+ - 1.9.3
3
+ - jruby
4
+ - rbx-3
5
+ - 2.0.0
6
+ - 2.1
7
+ - 2.2
8
+ - 2.3.3
9
+ - 2.4.0
10
+ - ruby-head
11
+ sudo: false
12
+ cache: bundler
13
+ env:
14
+ - CHILDPROCESS_POSIX_SPAWN=true CHILDPROCESS_UNSET=should-be-unset
15
+ - CHILDPROCESS_POSIX_SPAWN=false CHILDPROCESS_UNSET=should-be-unset
16
+ matrix:
17
+ allow_failures:
18
+ - rvm: rbx-3
19
+ - rvm: ruby-head
20
+ env: "CHILDPROCESS_POSIX_SPAWN=true"
@@ -0,0 +1,8 @@
1
+ ### Version 0.6.0 / 2017-01-22
2
+
3
+ * Support for Ruby 2.4 added
4
+
5
+
6
+ ### Version 0.5.9 / 2016-01-06
7
+
8
+ * The Great Before Times...
data/Gemfile CHANGED
@@ -1,4 +1,11 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in child_process.gemspec
4
- gemspec
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in child_process.gemspec
4
+ gemspec
5
+
6
+
7
+ if RUBY_VERSION =~ /^1\./
8
+ gem 'tins', '< 1.7' # The 'tins' gem requires Ruby 2.x on/after this version
9
+ gem 'json', '< 2.0' # The 'json' gem drops pre-Ruby 2.x support on/after this version
10
+ gem 'term-ansicolor', '< 1.4' # The 'term-ansicolor' gem requires Ruby 2.x on/after this version
11
+ end
data/LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- Copyright (c) 2010-2015 Jari Bakken
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2010-2015 Jari Bakken
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,178 +1,178 @@
1
- # childprocess
2
-
3
- This gem aims at being a simple and reliable solution for controlling
4
- external programs running in the background on any Ruby / OS combination.
5
-
6
- The code originated in the [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver) gem, but should prove useful as
7
- a standalone library.
8
-
9
- [![Build Status](https://secure.travis-ci.org/jarib/childprocess.png)](http://travis-ci.org/jarib/childprocess)
10
- [![Gem Version](https://badge.fury.io/rb/childprocess.png)](http://badge.fury.io/rb/childprocess)
11
- [![Code Climate](https://codeclimate.com/github/jarib/childprocess.png)](https://codeclimate.com/github/jarib/childprocess)
12
- [![Coverage Status](https://coveralls.io/repos/jarib/childprocess/badge.png?branch=master)](https://coveralls.io/r/jarib/childprocess?branch=master)
13
-
14
- # Usage
15
-
16
- The object returned from `ChildProcess.build` will implement `ChildProcess::AbstractProcess`.
17
-
18
- ### Basic examples
19
-
20
- ```ruby
21
- process = ChildProcess.build("ruby", "-e", "sleep")
22
-
23
- # inherit stdout/stderr from parent...
24
- process.io.inherit!
25
-
26
- # ...or pass an IO
27
- process.io.stdout = Tempfile.new("child-output")
28
-
29
- # modify the environment for the child
30
- process.environment["a"] = "b"
31
- process.environment["c"] = nil
32
-
33
- # set the child's working directory
34
- process.cwd = '/some/path'
35
-
36
- # start the process
37
- process.start
38
-
39
- # check process status
40
- process.alive? #=> true
41
- process.exited? #=> false
42
-
43
- # wait indefinitely for process to exit...
44
- process.wait
45
- process.exited? #=> true
46
-
47
- # get the exit code
48
- process.exit_code #=> 0
49
-
50
- # ...or poll for exit + force quit
51
- begin
52
- process.poll_for_exit(10)
53
- rescue ChildProcess::TimeoutError
54
- process.stop # tries increasingly harsher methods to kill the process.
55
- end
56
- ```
57
-
58
- ### Advanced examples
59
-
60
- #### Output to pipe
61
-
62
- ```ruby
63
- r, w = IO.pipe
64
-
65
- proc = ChildProcess.build("echo", "foo")
66
- proc.io.stdout = proc.io.stderr = w
67
- proc.start
68
- w.close
69
-
70
- begin
71
- loop { print r.readpartial(8192) }
72
- rescue EOFError
73
- end
74
-
75
- proc.wait
76
- ```
77
-
78
- Note that if you just want to get the output of a command, the backtick method on Kernel may be a better fit.
79
-
80
- #### Write to stdin
81
-
82
- ```ruby
83
- process = ChildProcess.build("cat")
84
-
85
- out = Tempfile.new("duplex")
86
- out.sync = true
87
-
88
- process.io.stdout = process.io.stderr = out
89
- process.duplex = true # sets up pipe so process.io.stdin will be available after .start
90
-
91
- process.start
92
- process.io.stdin.puts "hello world"
93
- process.io.stdin.close
94
-
95
- process.poll_for_exit(exit_timeout_in_seconds)
96
-
97
- out.rewind
98
- out.read #=> "hello world\n"
99
- ```
100
-
101
- #### Pipe output to another ChildProcess
102
-
103
- ```ruby
104
- search = ChildProcess.build("grep", '-E', %w(redis memcached).join('|'))
105
- search.duplex = true # sets up pipe so search.io.stdin will be available after .start
106
- search.io.stdout = $stdout
107
- search.start
108
-
109
- listing = ChildProcess.build("ps", "aux")
110
- listing.io.stdout = search.io.stdin
111
- listing.start
112
- listing.wait
113
-
114
- search.io.stdin.close
115
- search.wait
116
- ```
117
-
118
- #### Prefer posix_spawn on *nix
119
-
120
- If the parent process is using a lot of memory, `fork+exec` can be very expensive. The `posix_spawn()` API removes this overhead.
121
-
122
- ```ruby
123
- ChildProcess.posix_spawn = true
124
- process = ChildProcess.build(*args)
125
- ```
126
-
127
- ### Ensure entire process tree dies
128
-
129
- By default, the child process does not create a new process group. This means there's no guarantee that the entire process tree will die when the child process is killed. To solve this:
130
-
131
- ```ruby
132
- process = ChildProcess.build(*args)
133
- process.leader = true
134
- process.start
135
- ```
136
-
137
- #### Detach from parent
138
-
139
- ```ruby
140
- process = ChildProcess.build("sleep", "10")
141
- process.detach = true
142
- process.start
143
- ```
144
-
145
- #### Invoking a shell
146
-
147
- As opposed to `Kernel#system`, `Kernel#exec` et al., ChildProcess will not automatically execute your command in a shell (like `/bin/sh` or `cmd.exe`) depending on the arguments.
148
- This means that if you try to execute e.g. gem executables (like `bundle` or `gem`) or Windows executables (with `.com` or `.bat` extensions) you may see a `ChildProcess::LaunchError`.
149
- You can work around this by being explicit about what interpreter to invoke:
150
-
151
- ```ruby
152
- ChildProcess.build("cmd.exe", "/c", "bundle")
153
- ChildProcess.build("ruby", "-S", "bundle")
154
- ```
155
-
156
- ## Caveats
157
-
158
- * With JRuby on Unix, modifying `ENV["PATH"]` before using childprocess could lead to 'Command not found' errors, since JRuby is unable to modify the environemnt used for PATH searches in `java.lang.ProcessBuilder`. This can be avoided by setting `ChildProcess.posix_spawn = true`.
159
-
160
- # Implementation
161
-
162
- How the process is launched and killed depends on the platform:
163
-
164
- * Unix : `fork + exec` (or `posix_spawn` if enabled)
165
- * Windows : `CreateProcess()` and friends
166
- * JRuby : `java.lang.{Process,ProcessBuilder}`
167
-
168
- # Note on Patches/Pull Requests
169
-
170
- * Fork the project.
171
- * Make your feature addition or bug fix.
172
- * Add tests for it. This is important so I don't break it in a future version unintentionally.
173
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
174
- * Send me a pull request. Bonus points for topic branches.
175
-
176
- # Copyright
177
-
178
- Copyright (c) 2010-2015 Jari Bakken. See LICENSE for details.
1
+ # childprocess
2
+
3
+ This gem aims at being a simple and reliable solution for controlling
4
+ external programs running in the background on any Ruby / OS combination.
5
+
6
+ The code originated in the [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver) gem, but should prove useful as
7
+ a standalone library.
8
+
9
+ [![Build Status](https://secure.travis-ci.org/enkessler/childprocess.png)](http://travis-ci.org/enkessler/childprocess)
10
+ [![Gem Version](https://badge.fury.io/rb/childprocess.png)](http://badge.fury.io/rb/childprocess)
11
+ [![Code Climate](https://codeclimate.com/github/enkessler/childprocess.png)](https://codeclimate.com/github/enkessler/childprocess)
12
+ [![Coverage Status](https://coveralls.io/repos/enkessler/childprocess/badge.png?branch=master)](https://coveralls.io/r/enkessler/childprocess?branch=master)
13
+
14
+ # Usage
15
+
16
+ The object returned from `ChildProcess.build` will implement `ChildProcess::AbstractProcess`.
17
+
18
+ ### Basic examples
19
+
20
+ ```ruby
21
+ process = ChildProcess.build("ruby", "-e", "sleep")
22
+
23
+ # inherit stdout/stderr from parent...
24
+ process.io.inherit!
25
+
26
+ # ...or pass an IO
27
+ process.io.stdout = Tempfile.new("child-output")
28
+
29
+ # modify the environment for the child
30
+ process.environment["a"] = "b"
31
+ process.environment["c"] = nil
32
+
33
+ # set the child's working directory
34
+ process.cwd = '/some/path'
35
+
36
+ # start the process
37
+ process.start
38
+
39
+ # check process status
40
+ process.alive? #=> true
41
+ process.exited? #=> false
42
+
43
+ # wait indefinitely for process to exit...
44
+ process.wait
45
+ process.exited? #=> true
46
+
47
+ # get the exit code
48
+ process.exit_code #=> 0
49
+
50
+ # ...or poll for exit + force quit
51
+ begin
52
+ process.poll_for_exit(10)
53
+ rescue ChildProcess::TimeoutError
54
+ process.stop # tries increasingly harsher methods to kill the process.
55
+ end
56
+ ```
57
+
58
+ ### Advanced examples
59
+
60
+ #### Output to pipe
61
+
62
+ ```ruby
63
+ r, w = IO.pipe
64
+
65
+ proc = ChildProcess.build("echo", "foo")
66
+ proc.io.stdout = proc.io.stderr = w
67
+ proc.start
68
+ w.close
69
+
70
+ begin
71
+ loop { print r.readpartial(8192) }
72
+ rescue EOFError
73
+ end
74
+
75
+ proc.wait
76
+ ```
77
+
78
+ Note that if you just want to get the output of a command, the backtick method on Kernel may be a better fit.
79
+
80
+ #### Write to stdin
81
+
82
+ ```ruby
83
+ process = ChildProcess.build("cat")
84
+
85
+ out = Tempfile.new("duplex")
86
+ out.sync = true
87
+
88
+ process.io.stdout = process.io.stderr = out
89
+ process.duplex = true # sets up pipe so process.io.stdin will be available after .start
90
+
91
+ process.start
92
+ process.io.stdin.puts "hello world"
93
+ process.io.stdin.close
94
+
95
+ process.poll_for_exit(exit_timeout_in_seconds)
96
+
97
+ out.rewind
98
+ out.read #=> "hello world\n"
99
+ ```
100
+
101
+ #### Pipe output to another ChildProcess
102
+
103
+ ```ruby
104
+ search = ChildProcess.build("grep", '-E', %w(redis memcached).join('|'))
105
+ search.duplex = true # sets up pipe so search.io.stdin will be available after .start
106
+ search.io.stdout = $stdout
107
+ search.start
108
+
109
+ listing = ChildProcess.build("ps", "aux")
110
+ listing.io.stdout = search.io.stdin
111
+ listing.start
112
+ listing.wait
113
+
114
+ search.io.stdin.close
115
+ search.wait
116
+ ```
117
+
118
+ #### Prefer posix_spawn on *nix
119
+
120
+ If the parent process is using a lot of memory, `fork+exec` can be very expensive. The `posix_spawn()` API removes this overhead.
121
+
122
+ ```ruby
123
+ ChildProcess.posix_spawn = true
124
+ process = ChildProcess.build(*args)
125
+ ```
126
+
127
+ ### Ensure entire process tree dies
128
+
129
+ By default, the child process does not create a new process group. This means there's no guarantee that the entire process tree will die when the child process is killed. To solve this:
130
+
131
+ ```ruby
132
+ process = ChildProcess.build(*args)
133
+ process.leader = true
134
+ process.start
135
+ ```
136
+
137
+ #### Detach from parent
138
+
139
+ ```ruby
140
+ process = ChildProcess.build("sleep", "10")
141
+ process.detach = true
142
+ process.start
143
+ ```
144
+
145
+ #### Invoking a shell
146
+
147
+ As opposed to `Kernel#system`, `Kernel#exec` et al., ChildProcess will not automatically execute your command in a shell (like `/bin/sh` or `cmd.exe`) depending on the arguments.
148
+ This means that if you try to execute e.g. gem executables (like `bundle` or `gem`) or Windows executables (with `.com` or `.bat` extensions) you may see a `ChildProcess::LaunchError`.
149
+ You can work around this by being explicit about what interpreter to invoke:
150
+
151
+ ```ruby
152
+ ChildProcess.build("cmd.exe", "/c", "bundle")
153
+ ChildProcess.build("ruby", "-S", "bundle")
154
+ ```
155
+
156
+ ## Caveats
157
+
158
+ * With JRuby on Unix, modifying `ENV["PATH"]` before using childprocess could lead to 'Command not found' errors, since JRuby is unable to modify the environemnt used for PATH searches in `java.lang.ProcessBuilder`. This can be avoided by setting `ChildProcess.posix_spawn = true`.
159
+
160
+ # Implementation
161
+
162
+ How the process is launched and killed depends on the platform:
163
+
164
+ * Unix : `fork + exec` (or `posix_spawn` if enabled)
165
+ * Windows : `CreateProcess()` and friends
166
+ * JRuby : `java.lang.{Process,ProcessBuilder}`
167
+
168
+ # Note on Patches/Pull Requests
169
+
170
+ * Fork the project.
171
+ * Make your feature addition or bug fix.
172
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
173
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
174
+ * Send me a pull request. Bonus points for topic branches.
175
+
176
+ # Copyright
177
+
178
+ Copyright (c) 2010-2015 Jari Bakken. See LICENSE for details.