This file is indexed.

/usr/share/pyshared/MoinMoin/util/daemon.py is in python-moinmoin 1.9.3-1ubuntu2.3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
"""
Daemon - daemon script and controller

This module is based on twisted.scripts.twistd, modified by Nir Soffer
to work with non Twisted code.

The Daemon class, represents a background process using a pid
file. When you create an instance, the process may be running or not.
After creating an instance, you can call one of its do_xxx() methods.

The DaemonScript class is a script that control a daemon, with a
functionality similar to apachectl. To create a daemon script, create an
instacne and call its run() method.

Typical usage::

    # Daemon script
    import daemon
    import myserver
    script = daemon.DaemonScript('myserver', 'myserver.pid',
                                 myserver.run, myserver.Config)
    script.run()


Copyright (c) 2005 Nir Soffer <nirs@freeshell.org>

Twisted, the Framework of Your Internet
Copyright (c) 2001-2004 Twisted Matrix Laboratories.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""

import sys, os, errno, signal, time


class Error(Exception):
    """ Daemon error """


class Daemon:
    """ A background process

    Represent a background process, which may be running or not. The
    process can be started, stopped, restarted or killed.
    """
    commandPrefix = 'do_'

    def __init__(self, name, pidfile, function, *args, **kw):
        """ Create a daemon

        @param name: name of the process
        @param pidfile: pid filename
        @param function: the server main function, will block until the
            server is done.
        @param args: arguments to pass to function
        @param kw: keyword arguments to pass to function
        """
        self.name = name
        self.function = function
        self.args = args
        self.kw = kw
        self.pidFile = os.path.abspath(pidfile)

    # --------------------------------------------------------------------
    # Commands

    def do_start(self):
        """ Start the daemon process

        Start will daemonize then block until the server is killed and
        then cleanup the pid file on the way out.
        """
        running, pid = self.status()
        if running:
            raise Error("another application is running with pid %s "
                        "(try restart)" % pid)
        self.daemonize()
        self.writePID()
        try:
            self.function(*self.args, **self.kw)
        finally:
            self.removePID()

    def do_stop(self):
        """ Stop the daemon process

        Terminate or raise an error we can't handle here. On success,
        the pid file will be cleaned by the terminated process.
        """
        running, pid = self.status()
        if not running:
            return self.log("%s is not running" % self.name)
        os.kill(pid, signal.SIGINT)

    def do_kill(self):
        """ Kill the daemon process

        Kill or raise an error which we can't handle here. Clean the
        pid file for the killed process.
        """
        running, pid = self.status()
        if not running:
            return self.log("%s is not running" % self.name)
        os.kill(pid, signal.SIGKILL)
        self.removePID()

    def do_restart(self):
        """ stop, wait until pid file gone and start again """
        running, pid = self.status()
        if not running:
            self.log("%s is not running, trying to start" % self.name)
        else:
            self.do_stop()
        timeoutSeconds = 2.0
        start = time.time()
        while time.time() - start < timeoutSeconds:
            running, pid = self.status()
            if not running:
                break
            time.sleep(0.1)
        else:
            raise Error("could not start after %s seconds" % timeoutSeconds)
        self.do_start()

    # -------------------------------------------------------------------
    # Private

    def status(self):
        """ Return status tuple (running, pid)

        See http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC18
        """
        running = False
        pid = self.readPID()
        if pid is not None:
            try:
                os.kill(pid, 0)
                running = True
            except OSError, err:
                if err.errno == errno.ESRCH:
                    # No such process or security enhancements are causing
                    # the system to deny its existence.
                    self.log("removing stale pid file: %s" % self.pidFile)
                    self.removePID()
                else:
                    raise
        return running, pid

    def readPID(self):
        """ Return the pid from the pid file

        If there is no pid file, return None. If pid file is corrupted,
        remove it. If its not readable, raise.
        """
        pid = None
        try:
            pid = int(file(self.pidFile).read())
        except IOError, err:
            if err.errno != errno.ENOENT:
                raise
        except ValueError:
            self.warn("removing corrupted pid file: %s" % self.pidFile)
            self.removePID()
        return pid

    def daemonize(self):
        """ Make the current process a daemon

        See http://www.erlenstar.demon.co.uk/unix/faq_toc.html#TOC16
        """
        if os.fork():   # launch child and...
            os._exit(0) # kill off parent
        os.setsid()
        if os.fork():   # launch child and...
            os._exit(0) # kill off parent again.
        os.umask(0077)
        null = os.open('/dev/null', os.O_RDWR)
        for i in range(3):
            try:
                os.dup2(null, i)
            except OSError, e:
                if e.errno != errno.EBADF:
                    raise
        os.close(null)

    def writePID(self):
        pid = str(os.getpid())
        open(self.pidFile, 'wb').write(pid)

    def removePID(self):
        try:
            os.remove(self.pidFile)
        except OSError, err:
            if err.errno != errno.ENOENT:
                raise

    def warn(self, message):
        self.log('warning: %s' % message)

    def log(self, message):
        """ TODO: does it work after daemonize? """
        sys.stderr.write(message + '\n')


class DaemonScript(Daemon):
    """ A script controlling a daemon

    TODO: add --pid-dir option?
    """

    def run(self):
        """ Check commandline arguments and run a command """
        args = len(sys.argv)
        if args == 1:
            self.usage('nothing to do')
        elif args > 2:
            self.usage("too many arguments")
        try:
            command = sys.argv[1]
            func = getattr(self, self.commandPrefix + command)
            func()
        except AttributeError:
            self.usage('unknown command %r' % command)
        except Exception, why:
            sys.exit("error: %s" % str(why))

    def usage(self, message):
        sys.stderr.write('error: %s\n' % message)
        sys.stderr.write(self.help())
        sys.exit(1)

    def help(self):
        return """
%(name)s - MoinMoin daemon

usage: %(name)s command

commands:
  start     start the server
  stop      stop the server
  restart   stop then start the server
  kill      kill the server

@copyright: 2004-2005 Thomas Waldmann, Nir Soffer
@license: GNU GPL, see COPYING for details.
""" % {
    'name': self.name,
}