1 """This module makes it easier to use other programs to process data."""
9 """This represents another process. You should subclass this
10 and override the various methods. Use this when you want to
11 run another process in the background, but still be able to
12 communicate with it."""
17 """Create the subprocess. Calls pre_fork() and forks.
18 The parent then calls parent_post_fork() and returns,
19 while the child calls child_post_fork() and then
22 assert self
.child
is None
26 stderr_r
, stderr_w
= os
.pipe()
35 # This is the child process
38 os
.setpgid(0, 0) # Start a new process group
45 self
.child_post_fork()
47 raise Exception('child_run() returned!')
57 # This is the parent process
59 self
.err_from_child
= stderr_r
62 if not hasattr(gobject
, 'io_add_watch'):
63 self
.tag
= g
.input_add_full(self
.err_from_child
,
64 g
.gdk
.INPUT_READ
, self
._got
_errors
)
66 self
.tag
= gobject
.io_add_watch(self
.err_from_child
,
67 gobject
.IO_IN | gobject
.IO_HUP | gobject
.IO_ERR
,
70 self
.parent_post_fork()
73 """This is called in 'start' just before forking into
74 two processes. If you want to share a resource between
75 both processes (eg, a pipe), create it here.
76 Default method does nothing."""
78 def parent_post_fork(self
):
79 """This is called in the parent after forking. Free the
80 child part of any resources allocated in pre_fork().
81 Also called if the fork or pre_fork() fails.
82 Default method does nothing."""
84 def child_post_fork(self
):
85 """Called in the child after forking. Release the parent
86 part of any resources allocated in pre_fork().
87 Also called (in the parent) if the fork or pre_fork()
88 fails. Default method does nothing."""
90 def start_error(self
):
91 """An error occurred before or during the fork (possibly
92 in pre_fork(). Clean up. Default method calls
93 parent_post_fork() and child_post_fork(). On returning,
94 the original exception will be raised."""
95 self
.parent_post_fork()
96 self
.child_post_fork()
99 """Called in the child process (after child_post_fork()).
100 Do whatever processing is required (perhaps exec another
101 process). If you don't exec, call os._exit(n) when done.
102 DO NOT make gtk calls in the child process, as it shares its
103 parent's connection to the X server until you exec()."""
106 def kill(self
, sig
= signal
.SIGTERM
):
107 """Send a signal to all processes in the child's process
108 group. The default, SIGTERM, requests all the processes
109 terminate. SIGKILL is more forceful."""
110 assert self
.child
is not None
111 os
.kill(-self
.child
, sig
)
113 def got_error_output(self
, data
):
114 """Read some characters from the child's stderr stream.
115 The default method copies to our stderr. Note that 'data'
116 isn't necessarily a complete line; it could be a single
117 character, or several lines, etc."""
118 sys
.stderr
.write(data
)
120 def _got_errors(self
, source
, cond
):
121 got
= os
.read(self
.err_from_child
, 100)
123 self
.got_error_output(got
)
126 os
.close(self
.err_from_child
)
127 g
.input_remove(self
.tag
)
130 pid
, status
= os
.waitpid(self
.child
, 0)
132 self
.child_died(status
)
134 def child_died(self
, status
):
135 """Called when the child died (actually, when the child
136 closes its end of the stderr pipe). The child process has
137 already been reaped at this point; 'status' is the status
138 returned by os.waitpid."""