| 42 | |
| 43 | |
| 44 | def check_daemon(pidfile): |
| 45 | global _pidname |
| 46 | _pidname = os.path.abspath(pidfile) |
| 47 | try: |
| 48 | oldpid = open(_pidname).read(1024) |
| 49 | except IOError as e: |
| 50 | if e.errno == errno.ENOENT: |
| 51 | return # no pidfile, ok |
| 52 | else: |
| 53 | raise Fatal("can't read %s: %s" % (_pidname, e)) |
| 54 | if not oldpid: |
| 55 | os.unlink(_pidname) |
| 56 | return # invalid pidfile, ok |
| 57 | oldpid = int(oldpid.strip() or 0) |
| 58 | if oldpid <= 0: |
| 59 | os.unlink(_pidname) |
| 60 | return # invalid pidfile, ok |
| 61 | try: |
| 62 | os.kill(oldpid, 0) |
| 63 | except OSError as e: |
| 64 | if e.errno == errno.ESRCH: |
| 65 | os.unlink(_pidname) |
| 66 | return # outdated pidfile, ok |
| 67 | elif e.errno == errno.EPERM: |
| 68 | pass |
| 69 | else: |
| 70 | raise |
| 71 | raise Fatal("%s: sshuttle is already running (pid=%d)" |
| 72 | % (_pidname, oldpid)) |
| 73 | |
| 74 | |
| 75 | def daemonize(): |