Imported Upstream version 12.1.0
[contrib/python-twisted.git] / twisted / runner / inetd.py
1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4
5
6 """
7 Twisted inetd.
8
9 Maintainer: Andrew Bennetts
10
11 Future Plans: Bugfixes.  Specifically for UDP and Sun-RPC, which don't work
12 correctly yet.
13 """
14
15 import os
16
17 from twisted.internet import process, reactor, fdesc
18 from twisted.internet.protocol import Protocol, ServerFactory
19 from twisted.protocols import wire
20
21 # A dict of known 'internal' services (i.e. those that don't involve spawning
22 # another process.
23 internalProtocols = {
24     'echo': wire.Echo,
25     'chargen': wire.Chargen,
26     'discard': wire.Discard,
27     'daytime': wire.Daytime,
28     'time': wire.Time,
29 }
30             
31
32 class InetdProtocol(Protocol):
33     """Forks a child process on connectionMade, passing the socket as fd 0."""
34     def connectionMade(self):
35         sockFD = self.transport.fileno()
36         childFDs = {0: sockFD, 1: sockFD}
37         if self.factory.stderrFile:
38             childFDs[2] = self.factory.stderrFile.fileno()
39
40         # processes run by inetd expect blocking sockets
41         # FIXME: maybe this should be done in process.py?  are other uses of
42         #        Process possibly affected by this?
43         fdesc.setBlocking(sockFD)
44         if childFDs.has_key(2):
45             fdesc.setBlocking(childFDs[2])
46
47         service = self.factory.service
48         uid = service.user
49         gid = service.group
50
51         # don't tell Process to change our UID/GID if it's what we
52         # already are
53         if uid == os.getuid():
54             uid = None
55         if gid == os.getgid():
56             gid = None
57
58         process.Process(None, service.program, service.programArgs, os.environ,
59                         None, None, uid, gid, childFDs)
60
61         reactor.removeReader(self.transport)
62         reactor.removeWriter(self.transport)
63                         
64
65 class InetdFactory(ServerFactory):
66     protocol = InetdProtocol
67     stderrFile = None
68     
69     def __init__(self, service):
70         self.service = service