Add some TRACE messages
[MonkeyD.git] / palm / lib / child.py
blob578c01adff2622027551a215c216d36a7f357124
1 # Copyright (C) 2008-2009, Eduardo Silva <edsiper@gmail.com>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 import os
18 import sys
19 import time
20 import signal
21 from epoll import *
23 class Child:
24 def __init__(self, s, conf):
25 self._s = s
26 self.conf = conf
27 self.split_conf()
29 # On child end, re-create it
30 signal.signal(signal.SIGCHLD, self._child_exit)
32 # Start our child
33 self._create()
35 def split_conf(self):
36 try:
37 opts = self.conf.opts.split()
38 except:
39 opts = []
41 self.c = {'bin': self.conf.bin, 'opts': opts}
43 def _create(self):
44 # Creating pipes
45 [self.ext_r, self.int_w] = os.pipe()
46 [self.int_r, self.ext_w] = os.pipe()
48 # Fork process
49 pid = os.fork()
50 if pid:
51 self._pid = pid
52 # Close unused pipe ends
53 os.close(self.int_w)
54 os.close(self.int_r)
55 else:
56 # Close unused pipe ends
57 os.close(self.ext_r)
58 os.close(self.ext_w)
60 # Start child loop
61 self.start_child()
63 def _child_exit(self,a, b):
64 os.close(self.ext_r)
65 os.close(self.ext_w)
66 self._create()
68 def write_to_child(self, message):
69 os.write(self.ext_w, message)
71 def read(self, fd):
72 buf = ""
73 while 1:
74 data = fd.recv(4096)
75 if len(data) == 0:
76 break
77 else:
78 buf += data
79 if buf[-4:] == '\r\n\r\n':
80 break;
82 try:
83 if os.environ['PALM_DEBUG'] is not None:
84 print buf
85 except:
86 pass
88 return buf
90 def parse_request(self, data):
91 arr = data.split('\r\n')
92 for line in arr[:-2]:
93 # print line
94 if line == arr[0]:
95 request = Request(line)
96 continue
98 sep = line.find('=')
99 if sep < 0:
100 continue
102 key = line[:sep]
103 val = line[sep+1:]
105 request.add_header(key, val)
107 try:
108 if os.environ['PALM_DEBUG'] is not None:
109 for h in request.headers:
110 print h + ' = \'' + request.headers[h] + '\''
111 except:
112 pass
114 return request
116 def start_child(self):
117 # Creating epoll for read pipe side
118 while 1:
119 remote, info = self._s.accept()
120 # print "Got connection! I won! ->", os.getpid()
121 buf = self.read(remote)
122 #print "reading, ", buf
124 request = self.parse_request(buf)
126 if self.c['bin'] is None:
127 bin = request.resource
128 else:
129 bin = self.c['bin']
131 if self.c['opts'] is None and bin != request.resource:
132 opts = [request.resource]
133 else:
134 opts = self.c['opts']
135 opts.append(request.resource)
137 os.dup2(remote.fileno(), sys.stdout.fileno())
138 try:
139 os.execve(bin, opts, request.headers)
140 except:
141 exit(1)
144 def write_to_parent(self, message):
145 time.sleep(1)
146 n = os.write(self.int_w, message)
147 print "Child wrote: ", n
149 def read_data(self, fd):
150 buf = os.read(fd, 1024)
151 os.write(self.int_w, buf)
152 print "Child got: ", buf
154 def get_pid(self):
155 return self._pid
157 def kill(self):
158 os.kill(self._pid, signal.SIGKILL)
160 class Request:
161 def __init__(self, resource):
162 self.resource = resource
163 self.headers = {}
165 def add_header(self, key, val):
166 self.headers[key] = val
167 # print self.headers