| Class | Dsadmin::SystemCommand |
| In: |
lib/dsadmin/system_command.rb
|
| Parent: | Object |
Wrapper class around system commands (typically specified in the configfile).
| See also: | ../config.html |
| command | [RW] | |
| dir | [RW] | |
| env | [RW] | |
| group | [RW] | |
| params | [RW] | |
| user | [RW] |
Constructor.
| csect: | a ConfigSection to read the command specification from. If set to nil, everything has to be set manually via the accessors |
# File lib/dsadmin/system_command.rb, line 189
189: def initialize(csect = nil)
190: @env = Hash.new
191: @params = Array.new
192: @group = Process.egid
193:
194: if(csect)
195: requireKindOf(ConfigSection, csect)
196:
197: cmdline = csect.get('cmdline', String)
198: @command, *@params = shellwords(cmdline.strip)
199: @user = csect.get('user', String)
200: @group = csect.get('group', String, false) || @group
201: @dir = csect.get('dir', String, false)
202:
203: params = csect.get('param', Array, false)
204: @params.push(*params) if(params)
205:
206: @env = csect.get('env', Hash, false) || @env
207: end
208: end
Execute the given command
The command is executed in the background to avoid stalling the rest of the system. The method itself only returns once the command has finished however.
| Returns: | nothing |
Raises: RuntimeError if the command returned with an error code
# File lib/dsadmin/system_command.rb, line 163
163: def exec(*aParameterList)
164: res = exec1(*aParameterList)
165: if(! res.success?)
166: raise RuntimeError, "Executed command '#{@command}' returned exit status #{res}"
167: end
168: end
Execute the given command
The command is executed in the background to avoid stalling the rest of the system. The method itself only returns once the command has finished however.
| Returns: | Process status (Process::Status) of the command on its return |
# File lib/dsadmin/system_command.rb, line 129
129: def exec1(*aParameterList)
130: paramlist = params + aParameterList
131:
132: pid = fork {
133: ObjectSpace.each_object(BasicSocket) { |obj|
134: obj.closed? or obj.close rescue nil
135: }
136:
137: sys.runAs(user, group) {
138: Dir.chdir(dir) if(dir)
139: Kernel.exec(command, *paramlist)
140: }
141: }
142:
143: # allows RequestProcessor to issue a "kill" if necessary
144: Thread.current['EXEC_PID'] = pid
145:
146: (pid, res) = Process.waitpid2(pid)
147:
148: Thread.current['EXEC_PID'] = nil
149:
150: return res
151: end
exec() replacement that returns
* status code, * stdout output as String, * stderr output as String
Modeled after Open3.popen3(). The command is executed in the background to avoid stalling the rest of the system. The method itself only returns once the command has finished however.
| Returns: | A Hash {"status" => Integer, "stdout" => String, "stderr" => String} |
# File lib/dsadmin/system_command.rb, line 54
54: def exec3(*aParameterList)
55: exec3e(Hash.new, *aParameterList)
56: end
Like exec3(), but additionally takes a hash with environment variables to set for the command.
# File lib/dsadmin/system_command.rb, line 63
63: def exec3e(anEnvironment, *aParameterList)
64: env = @env.merge(anEnvironment)
65: paramlist = params + aParameterList
66:
67: pipe_stdout = IO::pipe # pipe[0] for read, pipe[1] for write
68: pipe_stderr = IO::pipe
69: pid = nil
70:
71: pid = fork {
72: ObjectSpace.each_object(BasicSocket) { |obj|
73: obj.closed? or obj.close rescue nil
74: }
75:
76: sys.runAs(user, group) {
77: # child
78: STDIN.close
79:
80: pipe_stdout[0].close
81: STDOUT.reopen(pipe_stdout[1])
82: pipe_stdout[1].close
83:
84: pipe_stderr[0].close
85: STDERR.reopen(pipe_stderr[1])
86: pipe_stderr[1].close
87:
88: env.each { |key, val|
89: ENV[key] = val
90: }
91:
92: Dir.chdir(dir) if(dir)
93: Kernel.exec(command, *paramlist)
94: }
95: }
96:
97: # allows RequestProcessor to issue a "kill" if necessary
98: Thread.current['EXEC_PID'] = pid
99:
100: pipe_stdout[1].close
101: pipe_stderr[1].close
102:
103: stderr_text = ""
104: stdout_text = ""
105:
106: oreader = Thread.new { stdout_text = pipe_stdout[0].read }
107: ereader = Thread.new { stderr_text = pipe_stderr[0].read }
108:
109: oreader.join
110: ereader.join
111: (pid, status) = Process.waitpid2(pid)
112:
113: Thread.current['EXEC_PID'] = nil
114:
115: return {"status" => status,
116: "stderr" => stderr_text,
117: "stdout" => stdout_text}
118: end