def start(self, name, program, *args, **kargs): tracedir = kargs.get("trace_dir") appdir = kargs.get("app_dir") pidfile = joinpths(tracedir, name + ".pid") stderr = joinpths(tracedir, name + ".stderr") stdout = joinpths(tracedir, name + ".stdout") tracefn = Trace.trace_fn(tracedir, name) tracefn = Trace.touch_trace(tracedir, name) runtrace = Trace.Trace(tracefn) runtrace.trace(RUN, RUN_TYPE) runtrace.trace(PID_FN, pidfile) runtrace.trace(STDERR_FN, stderr) runtrace.trace(STDOUT_FN, stdout) #fork to get daemon out pid = os.fork() if(pid == 0): os.setsid() pid = os.fork() #fork to get daemon out - this time under init control #and now fully detached (no shell possible) if(pid == 0): #move to where application should be os.chdir(appdir) #close other fds limits = resource.getrlimit(resource.RLIMIT_NOFILE) mkfd = limits[1] if(mkfd == resource.RLIM_INFINITY): mkfd = MAXFD for fd in range(0, mkfd): try: os.close(fd) except OSError: #not open, thats ok pass #now adjust stderr and stdout stdoh = open(stdout, "w") stdeh = open(stderr, "w") os.dup2(stdoh.fileno(), sys.stdout.fileno()) os.dup2(stdeh.fileno(), sys.stderr.fileno()) #now exec... #the arguments to the child process should #start with the name of the command being run actualargs = [program] + list(args) os.execlp(program, *actualargs) else: #write out the child pid contents = str(pid) + "\n" write_file(pidfile, contents) #not exit or sys.exit, this is recommended #since it will do the right cleanups that we want #not calling any atexit functions, which would #be bad right now os._exit(0) else: return tracefn