childlabor 0.0.1 → 0.0.2

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 (2) hide show
  1. data/lib/child_labor.rb +151 -2
  2. metadata +4 -4
data/lib/child_labor.rb CHANGED
@@ -1,3 +1,152 @@
1
1
  module ChildLabor
2
- # Nothing here yet
3
- end
2
+ VERSION = '0.0.2'
3
+
4
+ def self.subprocess(cmd)
5
+ t = Task.new(cmd)
6
+ t.launch
7
+
8
+ if block_given?
9
+ begin
10
+ yield t
11
+ ensure
12
+ t.wait
13
+ t.close
14
+ end
15
+ end
16
+
17
+ return t
18
+ end
19
+
20
+ class Task
21
+ attr_reader :cmd
22
+
23
+ def initialize(cmd)
24
+ @cmd = cmd
25
+ @pid = nil
26
+ @exit_status = nil
27
+ @terminated = false
28
+ end
29
+
30
+ def launch
31
+ create_pipes
32
+
33
+ @pid = Process.fork
34
+
35
+ # child
36
+ unless @pid
37
+ @stdout.close
38
+ STDOUT.reopen @stdout_child
39
+
40
+ @stdin.close
41
+ STDIN.reopen @stdin_child
42
+
43
+ @stderr.close
44
+ STDERR.reopen @stderr_child
45
+
46
+ Process.exec cmd
47
+ end
48
+
49
+ @stdout_child.close
50
+ @stdin_child.close
51
+ @stderr_child.close
52
+
53
+ true
54
+ end
55
+
56
+ def launched?
57
+ @pid
58
+ end
59
+
60
+ def running?
61
+ poll_status(Process::WNOHANG)
62
+ end
63
+
64
+ def terminated?
65
+ !running?
66
+ end
67
+
68
+ def exit_status
69
+ poll_status
70
+ @exit_status
71
+ end
72
+
73
+ def wait
74
+ exit_status
75
+ end
76
+
77
+ def suspend
78
+ signal('STOP')
79
+ end
80
+
81
+ def resume
82
+ signal('CONT')
83
+ end
84
+
85
+ def terminate(signal = 'TERM')
86
+ signal(signal)
87
+ end
88
+
89
+ def read(length = nil, buffer = nil)
90
+ @stdout.read(length, buffer)
91
+ end
92
+
93
+ def read_stderr(length = nil, buffer = nil)
94
+ @stderr.read(length, buffer)
95
+ end
96
+
97
+ def write(str)
98
+ @stdin.write(str)
99
+ end
100
+
101
+ def signal(signal)
102
+ Process.kill(signal, @pid)
103
+ end
104
+
105
+ def close_read
106
+ @stdout.close if @stdout
107
+ @stdout = nil
108
+ end
109
+
110
+ def close_write
111
+ @stdin.close if @stdin
112
+ @stdin = nil
113
+ end
114
+
115
+ def close_stderr
116
+ @stderr.close if @stderr
117
+ @stderr = nil
118
+ end
119
+
120
+ def close
121
+ close_read
122
+ close_write
123
+ close_stderr
124
+ end
125
+
126
+ private
127
+
128
+ # Handles the state of the Task in a single call to
129
+ # Process.wait2.
130
+ # Returns true if the process is currently running
131
+ def poll_status(flags = 0)
132
+ return false unless @pid
133
+ return false if @terminated
134
+
135
+ pid, status = Process.wait2(@pid, flags)
136
+
137
+ return true unless pid
138
+
139
+ @terminated = true
140
+ @exit_status = status
141
+ false
142
+ rescue Errno::ECHILD
143
+ false
144
+ end
145
+
146
+ def create_pipes
147
+ @stdout, @stdout_child = IO.pipe
148
+ @stdin_child, @stdin = IO.pipe
149
+ @stderr, @stderr_child = IO.pipe
150
+ end
151
+ end
152
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: childlabor
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Carl Lerche
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-25 00:00:00 -07:00
18
+ date: 2010-06-28 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency