| Trees | Indices | Help |
|
|---|
|
|
1 #
2 # Copyright CEA/DAM/DIF (2008, 2009, 2010)
3 # Contributor: Stephane THIELL <stephane.thiell@cea.fr>
4 #
5 # This file is part of the ClusterShell library.
6 #
7 # This software is governed by the CeCILL-C license under French law and
8 # abiding by the rules of distribution of free software. You can use,
9 # modify and/ or redistribute the software under the terms of the CeCILL-C
10 # license as circulated by CEA, CNRS and INRIA at the following URL
11 # "http://www.cecill.info".
12 #
13 # As a counterpart to the access to the source code and rights to copy,
14 # modify and redistribute granted by the license, users are provided only
15 # with a limited warranty and the software's author, the holder of the
16 # economic rights, and the successive licensors have only limited
17 # liability.
18 #
19 # In this respect, the user's attention is drawn to the risks associated
20 # with loading, using, modifying and/or developing or reproducing the
21 # software by the user in light of its specific status of free software,
22 # that may mean that it is complicated to manipulate, and that also
23 # therefore means that it is reserved for developers and experienced
24 # professionals having in-depth computer knowledge. Users are therefore
25 # encouraged to load and test the software's suitability as regards their
26 # requirements in conditions enabling the security of their systems and/or
27 # data to be ensured and, more generally, to use and operate it in the
28 # same conditions as regards security.
29 #
30 # The fact that you are presently reading this means that you have had
31 # knowledge of the CeCILL-C license and that you accept its terms.
32 #
33 # $Id: Popen.py 292 2010-07-15 22:43:46Z st-cea $
34
35 """
36 WorkerPopen
37
38 ClusterShell worker for executing local commands.
39
40 Usage example:
41 >>> worker = WorkerPopen("/bin/uname", key="mykernel")
42 >>> task.schedule(worker) # schedule worker
43 >>> task.resume() # run task
44 >>> worker.retcode() # get return code
45 0
46 >>> worker.read() # read command output
47 'Linux'
48
49 """
50
51 import os
52 import signal
53
54 from ClusterShell.Worker.Worker import WorkerSimple, WorkerBadArgumentError
55
56
58 """
59 Implements the Popen Worker.
60 """
61
62 - def __init__(self, command, key=None, handler=None,
63 stderr=False, timeout=-1, autoclose=False):
64 """
65 Initialize Popen worker.
66 """
67 WorkerSimple.__init__(self, None, None, None, key, handler,
68 stderr, timeout, autoclose)
69
70 self.command = command
71 if not self.command:
72 raise WorkerBadArgumentError()
73
74 self.popen = None
75 self.rc = None
76
78 """
79 Start worker.
80 """
81 assert self.popen is None
82
83 self.popen = self._exec_nonblock(self.command, shell=True)
84 self.file_reader = self.popen.stdout
85 self.file_error = self.popen.stderr
86 self.file_writer = self.popen.stdin
87
88 if self.task.info("debug", False):
89 self.task.info("print_debug")(self.task, "POPEN: %s" % self.command)
90
91 self._invoke("ev_start")
92
93 return self
94
96 """
97 Close worker. Called by engine after worker has been
98 unregistered. This method should handle all termination types
99 (normal, forced or on timeout).
100 """
101 if not force and self._rbuf:
102 # We still have some read data available in buffer, but no
103 # EOL. Generate a final message before closing.
104 self.worker._on_msgline(self._rbuf)
105
106 rc = -1
107 if force or timeout:
108 # check if process has terminated
109 prc = self.popen.poll()
110 if prc is None:
111 # process is still running, kill it
112 os.kill(self.popen.pid, signal.SIGKILL)
113 else:
114 # close process / check if it has terminated
115 prc = self.popen.wait()
116 # get exit status
117 if prc >= 0:
118 # process exited normally
119 rc = prc
120 else:
121 # if process was signaled, return 128 + signum (bash-like)
122 rc = 128 + -prc
123
124 self.popen.stdin.close()
125 self.popen.stdout.close()
126
127 if rc >= 0:
128 self._on_rc(rc)
129 elif timeout:
130 self._on_timeout()
131
132 self._invoke("ev_close")
133
135 """
136 Set return code.
137 """
138 self.rc = rc
139 self.task._rc_set((self, self.key), rc)
140
141 self._invoke("ev_hup")
142
148
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Jul 27 21:53:22 2010 | http://epydoc.sourceforge.net |