Edgewall Software
Modify

Opened 2 weeks ago

Last modified 2 weeks ago

#13764 assigned defect

os._exit() should be used rather than sys.exit() in the child process after a os.fork()

Reported by: Jun Omae Owned by: Jun Omae
Priority: normal Milestone: 1.6.1
Component: web frontend/tracd Version:
Severity: normal Keywords:
Cc: Branch:
Release Notes:
API Changes:
Internal Changes:

Description

According to the documentation of os._exit()t:

Exit the process with status n, without calling cleanup handlers, flushing stdio buffers, etc. Note: The standard way to exit is sys.exit(n). _exit() should normally only be used in the child process after a fork().

However, sys.exit() is used in daemonize().

  • trac/util/daemon.py

    diff --git a/trac/util/daemon.py b/trac/util/daemon.py
    index 3a2db5c27..984025825 100644
    a b def daemonize(pidfile=None, progname=None, stdin='/dev/null',  
    5353    # Perform first fork
    5454    pid = os.fork()
    5555    if pid > 0:
    56         sys.exit(0) # exit first parent
     56        # exit first parent
    5757
    5858    # Decouple from parent environment
    5959    os.chdir('/')
    def daemonize(pidfile=None, progname=None, stdin='/dev/null',  
    6363    # Perform second fork
    6464    pid = os.fork()
    6565    if pid > 0:
    66         sys.exit(0) # exit second parent
     66        # exit second parent
    6767
    6868    # The process is now daemonized, redirect standard file descriptors
    6969    for stream in sys.stdout, sys.stderr:

Attachments (0)

Change History (1)

comment:1 by Jun Omae, 2 weeks ago

Test script:

import sys
from trac.util.daemon import daemonize

sys.stdout.write('stdout')
sys.stderr.write('stderr')
daemonize()

Before the patch:

Data written to stdout and stderr before a call of daemonize are written to files thrice.

$ ~/venv/trac/1.6/bin/python /tmp/test-daemonize.py >/tmp/test-daemonize.stdout 2>/tmp/test-daemonize.stderr
$ ls -l /tmp/test-daemonize.std???
-rw-r--r-- 1 jun66j5 jun66j5 18 Jul  3 15:51 /tmp/test-daemonize.stderr
-rw-r--r-- 1 jun66j5 jun66j5 18 Jul  3 15:51 /tmp/test-daemonize.stdout
$ od -c /tmp/test-daemonize.stdout
0000000   s   t   d   o   u   t   s   t   d   o   u   t   s   t   d   o
0000020   u   t
0000022
$ od -c /tmp/test-daemonize.stderr
0000000   s   t   d   e   r   r   s   t   d   e   r   r   s   t   d   e
0000020   r   r
0000022

After the patch:

Data written to stdout and stderr before a call of daemonize are written to files only once.

$ PYTHONPATH=. ~/venv/py311/bin/python /tmp/test-daemonize.py >/tmp/test-daemonize.stdout 2>/tmp/test-daemonize.stderr
$ ls -l /tmp/test-daemonize.std???
-rw-r--r-- 1 jun66j5 jun66j5 6 Jul  3 15:58 /tmp/test-daemonize.stderr
-rw-r--r-- 1 jun66j5 jun66j5 6 Jul  3 15:58 /tmp/test-daemonize.stdout
$ od -c /tmp/test-daemonize.stdout
0000000   s   t   d   o   u   t
0000006
$ od -c /tmp/test-daemonize.stderr
0000000   s   t   d   e   r   r
0000006
Note: See TracTickets for help on using tickets.