childprocess 0.5.9 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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.