From 273bcfa2ee4211c5b630cdc7d27ccb559b86bdfc Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 25 Aug 2026 16:49:56 +0900 Subject: [PATCH 1/2] skip close_on_exec(). It is default since in Python 3.4. --- benchmarks/dirty_benchmark.py | 3 --- benchmarks/dirty_streaming.py | 3 --- examples/dirty_example/test_worker_integration.py | 1 - gunicorn/arbiter.py | 2 -- gunicorn/dirty/worker.py | 4 ---- gunicorn/glogging.py | 10 +--------- gunicorn/util.py | 4 +--- gunicorn/workers/base.py | 8 -------- gunicorn/workers/sync.py | 1 - tests/dirty/test_multi_app_routing.py | 3 --- tests/dirty/test_per_app_worker_allocation.py | 3 --- tests/dirty/test_streaming_integration.py | 3 --- tests/test_dirty_arbiter.py | 3 --- tests/test_dirty_integration.py | 3 --- tests/test_dirty_worker.py | 3 --- 15 files changed, 2 insertions(+), 52 deletions(-) diff --git a/benchmarks/dirty_benchmark.py b/benchmarks/dirty_benchmark.py index f59fdf18da..86ddc40410 100755 --- a/benchmarks/dirty_benchmark.py +++ b/benchmarks/dirty_benchmark.py @@ -185,9 +185,6 @@ def exception(self, msg, *args): def reopen_files(self): pass - def close_on_exec(self): - pass - class IsolatedBenchmark: """ diff --git a/benchmarks/dirty_streaming.py b/benchmarks/dirty_streaming.py index f5a279187f..dc92d5ca6e 100644 --- a/benchmarks/dirty_streaming.py +++ b/benchmarks/dirty_streaming.py @@ -114,9 +114,6 @@ def warning(self, msg, *args): def error(self, msg, *args): pass - def close_on_exec(self): - pass - def reopen_files(self): pass diff --git a/examples/dirty_example/test_worker_integration.py b/examples/dirty_example/test_worker_integration.py index acca996178..8f5433be50 100644 --- a/examples/dirty_example/test_worker_integration.py +++ b/examples/dirty_example/test_worker_integration.py @@ -31,7 +31,6 @@ def debug(self, msg, *args): print(f"[DEBUG] {msg % args if args else msg}") def info(self, msg, *args): print(f"[INFO] {msg % args if args else msg}") def warning(self, msg, *args): print(f"[WARN] {msg % args if args else msg}") def error(self, msg, *args): print(f"[ERROR] {msg % args if args else msg}") - def close_on_exec(self): pass def reopen_files(self): pass diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py index e0575cce82..7590a6e6f5 100644 --- a/gunicorn/arbiter.py +++ b/gunicorn/arbiter.py @@ -228,8 +228,6 @@ def init_signals(self): Initialize master signal handling. Most of the signals are queued. Child signals only wake up the master. """ - self.log.close_on_exec() - # initialize all signals for s in self.SIGNALS: signal.signal(s, self.signal) diff --git a/gunicorn/dirty/worker.py b/gunicorn/dirty/worker.py index 43b91043d4..5e6cd211c0 100644 --- a/gunicorn/dirty/worker.py +++ b/gunicorn/dirty/worker.py @@ -157,10 +157,6 @@ def init_process(self): # Reseed random number generator util.seed() - # Prevent fd inheritance - util.close_on_exec(self.tmp.fileno()) - self.log.close_on_exec() - # Set up signals self.init_signals() diff --git a/gunicorn/glogging.py b/gunicorn/glogging.py index 9287d98691..f258bda65f 100644 --- a/gunicorn/glogging.py +++ b/gunicorn/glogging.py @@ -411,15 +411,7 @@ def reopen_files(self): handler.release() def close_on_exec(self): - for log in loggers(): - for handler in log.handlers: - if isinstance(handler, logging.FileHandler): - handler.acquire() - try: - if handler.stream: - util.close_on_exec(handler.stream.fileno()) - finally: - handler.release() + pass def _get_gunicorn_handler(self, log): for h in log.handlers: diff --git a/gunicorn/util.py b/gunicorn/util.py index 6dec339f4a..fcb448fed7 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -271,9 +271,7 @@ def parse_address(netloc, default_port='8000'): def close_on_exec(fd): - flags = fcntl.fcntl(fd, fcntl.F_GETFD) - flags |= fcntl.FD_CLOEXEC - fcntl.fcntl(fd, fcntl.F_SETFD, flags) + os.set_inheritable(fd, False) def set_non_blocking(fd): diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py index bb74f32123..a53f0e1d18 100644 --- a/gunicorn/workers/base.py +++ b/gunicorn/workers/base.py @@ -106,17 +106,9 @@ def init_process(self): self.PIPE = os.pipe() for p in self.PIPE: util.set_non_blocking(p) - util.close_on_exec(p) - - # Prevent fd inheritance - for s in self.sockets: - util.close_on_exec(s) - util.close_on_exec(self.tmp.fileno()) self.wait_fds = self.sockets + [self.PIPE[0]] - self.log.close_on_exec() - self.init_signals() # start the reloader diff --git a/gunicorn/workers/sync.py b/gunicorn/workers/sync.py index c11597f22e..75b3b54493 100644 --- a/gunicorn/workers/sync.py +++ b/gunicorn/workers/sync.py @@ -26,7 +26,6 @@ class SyncWorker(base.Worker): def accept(self, listener): client, addr = listener.accept() client.setblocking(1) - util.close_on_exec(client) self.handle(listener, client, addr) def wait(self, timeout): diff --git a/tests/dirty/test_multi_app_routing.py b/tests/dirty/test_multi_app_routing.py index 4e01b711c3..1d8ee11bdf 100644 --- a/tests/dirty/test_multi_app_routing.py +++ b/tests/dirty/test_multi_app_routing.py @@ -57,9 +57,6 @@ def critical(self, msg, *args): def exception(self, msg, *args): self.messages.append(("exception", msg % args if args else msg)) - def close_on_exec(self): - pass - def reopen_files(self): pass diff --git a/tests/dirty/test_per_app_worker_allocation.py b/tests/dirty/test_per_app_worker_allocation.py index abdfb37ee0..be8d0c7c52 100644 --- a/tests/dirty/test_per_app_worker_allocation.py +++ b/tests/dirty/test_per_app_worker_allocation.py @@ -34,9 +34,6 @@ def critical(self, msg, *args): def exception(self, msg, *args): self.messages.append(("exception", msg % args if args else msg)) - def close_on_exec(self): - pass - def reopen_files(self): pass diff --git a/tests/dirty/test_streaming_integration.py b/tests/dirty/test_streaming_integration.py index b23fee3867..248b304195 100644 --- a/tests/dirty/test_streaming_integration.py +++ b/tests/dirty/test_streaming_integration.py @@ -50,9 +50,6 @@ def warning(self, msg, *args): def error(self, msg, *args): self.messages.append(("error", msg % args if args else msg)) - def close_on_exec(self): - pass - def reopen_files(self): pass diff --git a/tests/test_dirty_arbiter.py b/tests/test_dirty_arbiter.py index c8667b0eca..7da7d96119 100644 --- a/tests/test_dirty_arbiter.py +++ b/tests/test_dirty_arbiter.py @@ -88,9 +88,6 @@ def critical(self, msg, *args): def exception(self, msg, *args): self.messages.append(("exception", msg % args if args else msg)) - def close_on_exec(self): - pass - def reopen_files(self): pass diff --git a/tests/test_dirty_integration.py b/tests/test_dirty_integration.py index a841cf2c1c..823e51fbfa 100644 --- a/tests/test_dirty_integration.py +++ b/tests/test_dirty_integration.py @@ -136,7 +136,6 @@ def debug(self, *a, **kw): pass def info(self, *a, **kw): pass def warning(self, *a, **kw): pass def error(self, *a, **kw): pass - def close_on_exec(self): pass def reopen_files(self): pass cfg = Config() @@ -205,7 +204,6 @@ def warning(self, *a, **kw): pass def error(self, *a, **kw): pass def critical(self, *a, **kw): pass def exception(self, *a, **kw): pass - def close_on_exec(self): pass def reopen_files(self): pass cfg = Config() @@ -297,7 +295,6 @@ def warning(self, *a, **kw): pass def error(self, *a, **kw): pass def critical(self, *a, **kw): pass def exception(self, *a, **kw): pass - def close_on_exec(self): pass def reopen_files(self): pass cfg = Config() diff --git a/tests/test_dirty_worker.py b/tests/test_dirty_worker.py index e50e7c4121..66bedbf4f1 100644 --- a/tests/test_dirty_worker.py +++ b/tests/test_dirty_worker.py @@ -43,9 +43,6 @@ def warning(self, msg, *args): def error(self, msg, *args): self.messages.append(("error", msg % args if args else msg)) - def close_on_exec(self): - pass - def reopen_files(self): pass From efc213c05481c21452ccf70126dd49b1e25c6312 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 25 Aug 2026 17:13:23 +0900 Subject: [PATCH 2/2] call fd = fd.fileno() --- gunicorn/util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gunicorn/util.py b/gunicorn/util.py index fcb448fed7..9ed2f17455 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -271,6 +271,8 @@ def parse_address(netloc, default_port='8000'): def close_on_exec(fd): + if not isinstance(fd, int): + fd = fd.fileno() os.set_inheritable(fd, False)