Skip to content

Commit

Permalink
non-portable stdlib imports to function scope
Browse files Browse the repository at this point in the history
  • Loading branch information
pajod committed Dec 12, 2023
1 parent a606602 commit f59f799
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 20 deletions.
4 changes: 2 additions & 2 deletions gunicorn/arbiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ def init_signals(self):
os.close(p)

# initialize the pipe
self.PIPE = pair = os.pipe()
for p in pair:
self.PIPE = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC)
for p in self.PIPE:
util.set_non_blocking(p)
util.close_on_exec(p)

Expand Down
15 changes: 7 additions & 8 deletions gunicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

import argparse
import copy
import grp
import inspect
import os
import pwd
import re
import shlex
import ssl
Expand Down Expand Up @@ -442,7 +440,9 @@ def _validate_callable(val):

def validate_user(val):
if val is None:
return os.geteuid()
return None

import pwd
if isinstance(val, int):
return val
elif val.isdigit():
Expand All @@ -456,8 +456,9 @@ def validate_user(val):

def validate_group(val):
if val is None:
return os.getegid()
return None

import grp
if isinstance(val, int):
return val
elif val.isdigit():
Expand Down Expand Up @@ -1140,8 +1141,7 @@ class User(Setting):
cli = ["-u", "--user"]
meta = "USER"
validator = validate_user
default = os.geteuid()
default_doc = "``os.geteuid()``"
default = None
desc = """\
Switch worker processes to run as this user.
Expand All @@ -1157,8 +1157,7 @@ class Group(Setting):
cli = ["-g", "--group"]
meta = "GROUP"
validator = validate_group
default = os.getegid()
default_doc = "``os.getegid()``"
default = None
desc = """\
Switch worker process to run as this group.
Expand Down
28 changes: 21 additions & 7 deletions gunicorn/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@
import ast
import email.utils
import errno
import fcntl
import html
import importlib
import inspect
import io
import logging
import os
import pwd
import random
import re
import socket
Expand Down Expand Up @@ -133,13 +131,15 @@ def get_arity(f):


def get_username(uid):
import pwd
""" get the username for a user id"""
return pwd.getpwuid(uid).pw_name


def set_owner_process(uid, gid, initgroups=False):
""" set user and group of workers processes """

# FIXME: odd inconsistency with 0/None
if gid:
if uid:
try:
Expand All @@ -161,9 +161,12 @@ def set_owner_process(uid, gid, initgroups=False):


def chown(path, uid, gid):
# we use None for unchanged
# os.chown semantics are -1 for unchanged
uid = -1 if uid is None else uid
gid = -1 if gid is None else gid
os.chown(path, uid, gid)


if sys.platform.startswith("win"):
def _waitfor(func, pathname, waitall=False):
# Perform the operation
Expand Down Expand Up @@ -255,14 +258,25 @@ def parse_address(netloc, default_port='8000'):


def close_on_exec(fd):
# Python 3.4+: file descriptors created by Python non-inheritable by default
import fcntl
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(fd, fcntl.F_SETFD, flags)
# mind the difference between os.O_CLOEXEC and fcntl.FD_CLOEXEC
if not flags | fcntl.FD_CLOEXEC:
raise AssertionError("Expected FD_CLOEXEC set on fd %r" % fd)
# flags |= fcntl.FD_CLOEXEC
# fcntl.fcntl(fd, fcntl.F_SETFD, flags)


def set_non_blocking(fd):
flags = fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
# no need for portability: on Unix it can be set atomically using os.pipe2()
# or we want a queue or socket instead of a pipe anyway
import fcntl
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
if not flags | os.O_NONBLOCK:
raise AssertionError("Expected O_NONBLOCK set on fd %r" % fd)
# flags |= os.O_NONBLOCK
# fcntl.fcntl(fd, fcntl.F_SETFL, flags)


def close(sock):
Expand Down
2 changes: 1 addition & 1 deletion gunicorn/workers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def init_process(self):
util.seed()

# For waking ourselves up
self.PIPE = os.pipe()
self.PIPE = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC)
for p in self.PIPE:
util.set_non_blocking(p)
util.close_on_exec(p)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ def test_property_access():
assert c.address == [("127.0.0.1", 8000)]

# User and group defaults
assert os.geteuid() == c.uid
assert os.getegid() == c.gid
assert c.uid is None
assert c.gid is None

# Proc name
assert "gunicorn" == c.proc_name
Expand Down

0 comments on commit f59f799

Please sign in to comment.