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

Methods

exec   exec1   exec3   exec3e   new   to_s  

Included Modules

Shellwords Contractor CoreClient

Attributes

command  [RW] 
dir  [RW] 
env  [RW] 
group  [RW] 
params  [RW] 
user  [RW] 

Public Class methods

Constructor.

csect:a ConfigSection to read the command specification from. If set to nil, everything has to be set manually via the accessors

[Source]

     # 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

Public Instance methods

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

[Source]

     # 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

[Source]

     # 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}

[Source]

    # 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.

[Source]

     # 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

[Source]

     # File lib/dsadmin/system_command.rb, line 171
171:   def to_s(extra_params = [])
172:         res = ""
173:         env.each { |key, val| res << "#{key}=#{val} " }
174:         res << "#{command} "
175:         params.each { |val|   res << "#{val} " }
176:         extra_params.each { |val|   res << "#{val} " }
177:         res
178:   end

[Validate]