Minor fixes
[MonkeyD.git] / palm / lib / child.py
blob7048ce627fb246153949d190ff7a5149d549560e
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 print "My PID " + str(pid)
53 # Close unused pipe ends
54 os.close(self.int_w)
55 os.close(self.int_r)
56 else:
57 # Close unused pipe ends
58 os.close(self.ext_r)
59 os.close(self.ext_w)
61 # Start child loop
62 self.start_child()
64 def _child_exit(self,a, b):
65 os.close(self.ext_r)
66 os.close(self.ext_w)
67 self._create()
69 def write_to_child(self, message):
70 os.write(self.ext_w, message)
72 def read(self, fd):
73 buf = ""
74 while 1:
75 data = fd.recv(4096)
76 if len(data) == 0:
77 break
78 else:
79 buf += data
80 if buf[-4:] == '\r\n\r\n':
81 break;
83 try:
84 if os.environ['PALM_DEBUG'] is not None:
85 print buf
86 except:
87 pass
89 return buf
91 def parse_request(self, data):
92 arr = data.split('\r\n')
93 for line in arr[:-2]:
94 # print line
95 if line == arr[0]:
96 request = Request(line)
97 continue
99 sep = line.find('=')
100 if sep < 0:
101 continue
103 key = line[:sep]
104 val = line[sep+1:]
106 request.add_header(key, val)
108 try:
109 if os.environ['PALM_DEBUG'] is not None:
110 for h in request.headers:
111 print h + ' = \'' + request.headers[h] + '\''
112 except:
113 pass
115 return request
117 def start_child(self):
118 # Creating epoll for read pipe side
119 while 1:
120 remote, info = self._s.accept()
121 # print "Got connection! I won! ->", os.getpid()
122 buf = self.read(remote)
123 #print "reading, ", buf
125 request = self.parse_request(buf)
127 if self.c['bin'] is None:
128 bin = request.resource
129 else:
130 bin = self.c['bin']
132 if self.c['opts'] is None and bin != request.resource:
133 opts = [request.resource]
134 else:
135 opts = self.c['opts']
136 opts.append(request.resource)
138 os.dup2(remote.fileno(), sys.stdout.fileno())
139 try:
140 os.execve(bin, opts, request.headers)
141 except:
142 exit(1)
145 def write_to_parent(self, message):
146 time.sleep(1)
147 n = os.write(self.int_w, message)
148 print "Child wrote: ", n
150 def read_data(self, fd):
151 buf = os.read(fd, 1024)
152 os.write(self.int_w, buf)
153 print "Child got: ", buf
155 def get_pid(self):
156 return self._pid
158 def kill(self):
159 os.kill(self._pid, signal.SIGKILL)
161 class Request:
162 def __init__(self, resource):
163 self.resource = resource
164 self.headers = {}
166 def add_header(self, key, val):
167 self.headers[key] = val
168 # print self.headers