Class: RightScale::RightPopen::Process

Inherits:
Object
  • Object
show all
Defined in:
lib/right_popen/linux/process.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parameters = {}) ⇒ Process

Returns a new instance of Process.



32
33
34
35
36
# File 'lib/right_popen/linux/process.rb', line 32

def initialize(parameters={})
  parameters[:locale] = true unless parameters.has_key?(:locale)
  @parameters = parameters
  @status_fd = nil
end

Instance Attribute Details

#pidObject (readonly)

Returns the value of attribute pid.



29
30
31
# File 'lib/right_popen/linux/process.rb', line 29

def pid
  @pid
end

#statusObject

Returns the value of attribute status.



30
31
32
# File 'lib/right_popen/linux/process.rb', line 30

def status
  @status
end

#status_fdObject (readonly)

Returns the value of attribute status_fd.



29
30
31
# File 'lib/right_popen/linux/process.rb', line 29

def status_fd
  @status_fd
end

#stderrObject (readonly)

Returns the value of attribute stderr.



29
30
31
# File 'lib/right_popen/linux/process.rb', line 29

def stderr
  @stderr
end

#stdinObject (readonly)

Returns the value of attribute stdin.



29
30
31
# File 'lib/right_popen/linux/process.rb', line 29

def stdin
  @stdin
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



29
30
31
# File 'lib/right_popen/linux/process.rb', line 29

def stdout
  @stdout
end

Instance Method Details

#fork(cmd) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/right_popen/linux/process.rb', line 38

def fork(cmd)
  @cmd = cmd
  stdin_r, stdin_w = IO.pipe
  stdout_r, stdout_w = IO.pipe
  stderr_r, stderr_w = IO.pipe
  status_r, status_w = IO.pipe

  [stdin_r, stdin_w, stdout_r, stdout_w,
   stderr_r, stderr_w, status_r, status_w].each {|fdes| fdes.sync = true}

  @pid = Kernel::fork do
    begin
      stdin_w.close
      STDIN.reopen stdin_r

      stdout_r.close
      STDOUT.reopen stdout_w

      stderr_r.close
      STDERR.reopen stderr_w

      status_r.close
      status_w.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)

      ObjectSpace.each_object(IO) do |io|
        if ![STDIN, STDOUT, STDERR, status_w].include?(io)
      	  io.close unless io.closed?
      	end
      end

      if group = get_group
        ::Process.egid = group
        ::Process.gid = group
      end

      if user = get_user
        ::Process.euid = user
        ::Process.uid = user
      end

      Dir.chdir(@parameters[:directory]) if @parameters[:directory]

      ENV["LC_ALL"] = "C" if @parameters[:locale]

      @parameters[:environment].each do |key,value|
        ENV[key.to_s] = value.to_s
      end if @parameters[:environment]

      File.umask(get_umask) if @parameters[:umask]

      if cmd.kind_of?(Array)
        exec(*cmd)
      else
        exec("sh", "-c", cmd)
      end
      raise 'forty-two' 
    rescue Exception => e
      Marshal.dump(e, status_w)
    end
    status_w.close
    exit!
  end

  stdin_r.close
  stdout_w.close
  stderr_w.close
  status_w.close
  @stdin = stdin_w
  @stdout = stdout_r
  @stderr = stderr_r
  @status_fd = status_r
end

#wait_for_execObject



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/right_popen/linux/process.rb', line 111

def wait_for_exec
  begin
    e = Marshal.load @status_fd
    # thus meaning that the process failed to exec...
    @stdin.close
    @stdout.close
    @stderr.close
    raise(Exception === e ? e : "unknown failure!")
  rescue EOFError
    # thus meaning that the process did exec and we can continue.
  ensure
    @status_fd.close
  end
end