    import os
    import sys
    import atexit

    class ProcessRunning(Exception):
        pass

    def removePidFile(pidfile):
        pidfile.remove()

    class PidFile:

        def __init__(self, path):
            self._path = path
            self._createdPID = 0
            if os.path.exists(path):
                try:
                    pid = int(open(path).read())
                except (IOError, ValueError, TypeError):
                    # can't open file or read PID from file.  File is probably
                    # invalid or stale, so try to delete it.
                    pid = None
                    print "%s is invalid or cannot be opened; " \
                        "attempting to remove it." % path
                    os.unlink(path) # should we catch errors here?
                else:
                    if self.pidRunning(pid):
                        raise ProcessRunning()
                    else:
                        print "%s is stale; removing." % path
                        try:
                            os.unlink(path)
                        except OSError:
                            # maybe the other process has just quit
                            # and has removed the file.
                            pass # try continuing...

            pidfile = open(path, 'w')
            pidfile.write(str(self.currentPID()))
            pidfile.close()

            self._createdPID = 1

            # Delete the pid file when python exits, so that the pid file is
            # removed if the process exits abnormally.
            # If the process crashes, though, the pid file will be left behind.
            atexit.register(removePidFile, self)

        def pidRunning(self, pid):
            if os.name == 'posix':
                try:
                    os.kill(pid, 0)
                except OSError, e:
                    if e.errno == 3: # No such process
                        return 0
                return 1
            else:
                try:
                    import win32api
                    import win32con
                    import pywintypes
                    try:
                        win32api.OpenProcess(
                            win32con.PROCESS_QUERY_INFORMATION, 0, pid)
                    except pywintypes.error, e:
                        if e[0] == 87: # returned when process does not exist
                            return 0
                except ImportError:
                    pass # couldn't import win32 modules
                return 1

        def currentPID(self):
            if os.name == 'posix':
                return os.getpid()
            else:
                try:
                    import win32api
                except ImportError:
                    pass
                if sys.modules.has_key('win32api'):
                    return win32api.GetCurrentProcessId()
            return None

        def __del__(self):
            self.remove()

        def remove(self):
            # Only remove the file if we created it. Otherwise attempting to start
            # a second process will remove the file created by the first.
            if self._createdPID:
                try:
                    os.unlink(self._path)
                except (AttributeError, OSError):
                    pass