1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 """
36 WorkerPopen2
37
38 ClusterShell worker for executing local commands with popen2.
39 """
40
41 from ClusterShell.NodeSet import NodeSet
42
43 from Worker import WorkerSimple
44
45 import fcntl
46 import os
47 import popen2
48 import signal
49
50
52 """
53 Implements the Popen2 Worker.
54 """
55
56 - def __init__(self, command, key, handler, timeout, autoclose=False):
57 """
58 Initialize Popen2 worker.
59 """
60 WorkerSimple.__init__(self, None, None, None, key, handler, timeout, autoclose)
61
62 self.command = command
63 if not self.command:
64 raise WorkerBadArgumentException()
65
66 self.fid = None
67 self.rc = None
68
70 """
71 Start worker.
72 """
73 assert self.fid is None
74
75 cmdlist = ['/bin/sh', '-c', self.command]
76 self.fid = self._exec_nonblock(cmdlist)
77 self.file_reader = self.fid.fromchild
78 self.file_writer = self.fid.tochild
79
80 if self.task.info("debug", False):
81 self.task.info("print_debug")(self.task, "POPEN2: [%s]" % ','.join(cmdlist))
82
83 return WorkerSimple._start(self)
84
85 - def _close(self, force, timeout):
86 """
87 Close worker. Called by engine after worker has been
88 unregistered. This method should handle all termination types
89 (normal, forced or on timeout).
90 """
91 rc = -1
92 if force or timeout:
93
94 status = self.fid.poll()
95 if status == -1:
96
97 os.kill(self.fid.pid, signal.SIGKILL)
98 else:
99
100 status = self.fid.wait()
101
102 if os.WIFEXITED(status):
103
104 rc = os.WEXITSTATUS(status)
105 elif os.WIFSIGNALED(status):
106
107 rc = 128 + os.WSTOPSIG(status)
108 else:
109
110 rc = 255
111
112 self.fid.tochild.close()
113 self.fid.fromchild.close()
114
115 if rc >= 0:
116 self._on_rc(rc)
117 elif timeout:
118 self._on_timeout()
119
120 self._invoke("ev_close")
121
123 """
124 Set return code.
125 """
126 self.rc = rc
127 self.task._rc_set((self, self.key), rc)
128
129 self._invoke("ev_hup")
130
132 """
133 Return return code or None if command is still in progress.
134 """
135 return self.rc
136