platform.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import os
  2. import sys
  3. import errno
  4. import resource
  5. # File mode creation mask of the daemon.
  6. # No point in changing this, as we don't really create any files.
  7. DAEMON_UMASK = 0
  8. # Default working directory for the daemon.
  9. DAEMON_WORKDIR = "/"
  10. # Default maximum for the number of available file descriptors.
  11. DAEMON_MAXFD = 1024
  12. # The standard I/O file descriptors are redirected to /dev/null by default.
  13. if (hasattr(os, "devnull")):
  14. REDIRECT_TO = os.devnull
  15. else:
  16. REDIRECT_TO = "/dev/null"
  17. class PIDFile(object):
  18. def __init__(self, pidfile):
  19. self.pidfile = pidfile
  20. def get_pid(self):
  21. pidfile_fh = file(self.pidfile, "r")
  22. pid = int(pidfile_fh.read().strip())
  23. pidfile_fh.close()
  24. return pid
  25. def check(self):
  26. if os.path.exists(self.pidfile) and os.path.isfile(self.pidfile):
  27. pid = self.get_pid()
  28. try:
  29. os.kill(pid, 0)
  30. except os.error, e:
  31. if e.errno == errno.ESRCH:
  32. sys.stderr.write("Stale pidfile exists. removing it.\n")
  33. self.remove()
  34. else:
  35. raise SystemExit("refreshd is already running.")
  36. def remove(self):
  37. os.unlink(self.pidfile)
  38. def write(self, pid=None):
  39. if not pid:
  40. pid = os.getpid()
  41. pidfile_fh = file(self.pidfile, "w")
  42. pidfile_fh.write("%d\n" % pid)
  43. pidfile_fh.close()
  44. def remove_pidfile(pidfile):
  45. os.unlink(pidfile)
  46. def daemonize(pidfile):
  47. """Detach a process from the controlling terminal and run it in the
  48. background as a daemon."""
  49. try:
  50. pid = os.fork()
  51. except OSError, e:
  52. raise Exception, "%s [%d]" % (e.strerror, e.errno)
  53. if pid == 0: # child
  54. os.setsid()
  55. try:
  56. pid = os.fork() # second child
  57. except OSError, e:
  58. raise Exception, "%s [%d]" % (e.strerror, e.errno)
  59. if pid == 0: # second child
  60. #os.chdir(DAEMON_WORKDIR)
  61. os.umask(DAEMON_UMASK)
  62. else: # parent (first child)
  63. pidfile.write(pid)
  64. os._exit(0)
  65. else: # root process
  66. os._exit(0)
  67. maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
  68. if (maxfd == resource.RLIM_INFINITY):
  69. maxfd = DAEMON_MAXFD
  70. # Iterate through and close all file descriptors.
  71. for fd in range(0, maxfd):
  72. try:
  73. os.close(fd)
  74. except OSError:
  75. pass
  76. os.open(REDIRECT_TO, os.O_RDWR)
  77. # Duplicate standard input to standard output and standard error.
  78. os.dup2(0, 1)
  79. os.dup2(0, 2)
  80. return 0