2013-02-21 173 views
3

,當我有這樣的代碼在我的應用程序:的Python:關閉文件描述符daemonizing過程

def daemonize_process(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): 
''' 
Fork the current process as a daemon (background process), redirecting 
standard file descriptors 

@param string stdin standard input file name 
@param string stdout standard output file name 
@param string stderr standard error file name 
''' 

# To transform a process in a daemon, it is necessary to fork, decouple from 
# parent environment, fork again and close all opened file descriptors. 

# do first fork 
try: 
    pid = os.fork() 
    if pid > 0: 
     # exit from first parent process 
     # using os._exit() instead of sys.exit() in a child process after 
     # a fork is recommended by Python API docs 
     os._exit(0) 
except OSError as e: 
    sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror)) 
    sys.exit(1) 

# decouple from parent environment 
os.chdir("/") 
os.umask(0) 
os.setsid() 

# do second fork 
try: 
    pid = os.fork() 
    if pid > 0: 
     # exit from second parent process 
     # using os._exit() instead of sys.exit() in a child process after 
     # a fork is recommended by Python API docs 
     os._exit(0) 
except OSError, e: 
    sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror)) 
    sys.exit(1) 

# close all file descriptors 
import resource 
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] 
if (maxfd == resource.RLIM_INFINITY): 
    maxfd = 1024 

for fd in range(0, maxfd): 
    try: 
     os.close(fd) 
    except OSError: 
     sys.stderr.write("error closing file: (%d) %s\n" % (e.errno, e.strerror)) 
     pass 

# process is now daemonized, redirect standard file descriptors. 
for f in sys.stdout, sys.stderr: 
    f.flush() 
si = file(stdin, 'r') 
so = file(stdout, 'a+') 
se = file(stderr, 'a+', 0) 
os.dup2(si.fileno(), sys.stdin.fileno()) 
os.dup2(so.fileno(), sys.stdout.fileno()) 
os.dup2(se.fileno(), sys.stderr.fileno()) 

在系統守護進程的代碼,我在網上看到,該文件描述符不會在子進程關閉。我爲什麼要這樣做?在我看來,我可能想繼續在fork-detach-fork過程之前工作的文件中工作。

在此先感謝。

+0

您正在丟失SIGHUP處理程序 – LtWorf 2013-02-21 13:12:42

回答

1

爲什麼關閉文件描述符?通常你可以假定啓動守護進程的進程知道它在做什麼,並且會在exec()之前關閉它的文件描述符。

例如,如果您從bash運行,您將獲得的唯一打開的文件描述符是標準文件描述符,以及在shell中手動設置的任何重定向。

如果一個程序讓文件描述符左右打開,那就很麻煩了。 無論如何,可以使用FD_CLOEXEC打開文件,以便它們將在exec()上自動關閉。

+0

我同意,在調用daemonize_process()之前,父進程應該關閉它打開的任何東西。我不是那個在daemonize_process()中添加了關閉文件描述符的代碼的人。我在這裏要做的是完全理解它的用處,以及是否需要它。 – 2013-02-21 13:21:27

+0

我會說不。您可以在/ proc/pid/fd中檢入打開的文件描述符,並且如果有某些您覺得不應該在其中的描述符,那麼您可以修復父進程的代碼。 – LtWorf 2013-02-21 13:24:54