description: routes, addresses and validation functions
[nepi.git] / src / nepi / util / server.py
1 # -*- coding: utf-8 -*-
2 # vim:ts=4:sw=4:et:ai:sts=4
3 import errno
4 import os
5 import select
6 import socket
7 import sys
8 import threading
9
10 CTRL_SOCK = "ctrl.sock"
11 STD_ERR = "stderr.log"
12 MAX_FD = 1024
13
14 STOP_MSG = "STOP"
15
16 class Server(object):
17     def __init__(self):
18         self.stop = False
19         self.ctrl_sock = None
20
21     def run(self):
22         if self.daemonize():
23             self.loop()
24             self.cleanup()
25
26     def daemonize(self):
27         if True:
28             return 1
29
30         pid1 = os.fork()
31         if pid1 > 0:
32             return 0
33
34         # Decouple from parent environment.
35         #os.chdir(?)
36         os.umask(0)
37         os.setsid()
38
39         # fork 2
40         pid2 = os.fork()
41         if pid2 > 0:
42             return 0
43
44         # close all open file descriptors.
45         for fd in range(0, MAX_FD):
46             try:
47                 os.close(fd)
48             except OSError:
49                 pass
50
51         # Redirect standard file descriptors.
52         stdout = stderr = file(STD_ERR, "a", 0)
53         stdin = open('/dev/null', 'r')
54         os.dup2(stdin.fileno(), sys.stdin.fileno())
55         os.dup2(stdout.fileno(), sys.stdout.fileno())
56         os.dup2(stderr.fileno(), sys.stderr.fileno())
57         return 1
58
59     def loop(self):
60         self.ctrl_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
61         self.ctrl_sock.bind(CTRL_SOCK)
62         self.ctrl_sock.listen(0)
63         while not self.stop:
64             print 'accept'
65             conn, addr = self.ctrl_sock.accept()
66             conn.settimeout(5)
67             while True:
68                 try:
69                     print 'recv'
70                     data = conn.recv(1024)
71                 except socket.timeout, e:
72                     print e
73                     break
74                     
75                 if data == STOP_MSG:
76                     self.stop = True
77                 else:
78                     conn.send("%s received" % data)
79             conn.close()
80         
81     def cleanup(self):
82         self.ctrl_sock.close()
83         try:
84             s.remove(CTRL_SOCK)
85         except:
86             pass
87
88 class Forwarder(object):
89     def __init__(self):
90         self.ctrl_sock = None
91
92     def forward(self):
93         self.connect()
94         while True:
95             msg = sys.stdin.readline()
96             self.send(msg)
97             reply = self.ctrl_sock.recv(1024)
98             sys.stdout.write(reply)
99
100     def send(self, msg):
101         try:
102             self.ctrl_sock.send(msg)
103         except IOError, e:
104             if e.errno == errno.EPIPE:
105                 self.connect()
106                 self.ctrl_sock.send(msg)
107             else:
108                 raise e
109     
110     def connect(self):
111         try:
112             self.ctrl_sock.close()
113         except:
114             pass
115         self.ctrl_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
116         self.ctrl_sock.connect(CTRL_SOCK)
117
118 # Client
119 # import subprocess
120 # s = subprocess.Popen(['python' ,'-c' 'import server;c=server.Forwarder();c.forward()'], stdin = subprocess.PIPE)
121 # s.stdin.write('aaaa\n')