Skip to content

Commit 9016bc5

Browse files
committed
Fix dirfd check, handle OpenBSD.
1 parent 4c9b3ce commit 9016bc5

5 files changed

Lines changed: 59 additions & 38 deletions

File tree

Tools/configure/conf_platform.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,9 @@ def check_posix_shmem(v):
655655
v.POSIXSHMEM_CFLAGS = "-I$(srcdir)/Modules/_multiprocessing"
656656
v.POSIXSHMEM_LIBS = ""
657657
with pyconf.save_env():
658-
shm_open_result = pyconf.search_libs("shm_open", ["rt"], required=False)
658+
shm_open_result = pyconf.search_libs(
659+
"shm_open", ["rt"], required=False
660+
)
659661
posixshmem_libs = "-lrt" if shm_open_result == "-lrt" else ""
660662
have_posix_shmem = pyconf.check_func(
661663
"shm_open", headers=["sys/mman.h"]
@@ -743,18 +745,14 @@ def check_posix_functions(v):
743745

744746
def check_special_functions(v):
745747
"""Check dirfd, PY_CHECK_FUNC equivalents, flock, unsetenv, socket libs, chflags."""
746-
# dirfd
748+
# AC_CHECK_DECL([dirfd], [AC_DEFINE([HAVE_DIRFD])], [], [dirent.h])
747749
pyconf.checking("whether dirfd is declared")
748-
if pyconf.compile_check(
749-
preamble="#include <sys/types.h>\n#include <dirent.h>",
750-
body="void *p = dirfd;",
750+
if pyconf.check_decl(
751+
"dirfd",
752+
includes=["sys/types.h", "dirent.h"],
753+
define_name="HAVE_DIRFD",
751754
):
752755
pyconf.result("yes")
753-
pyconf.define(
754-
"HAVE_DIRFD",
755-
1,
756-
"Define if you have the 'dirfd' function or macro.",
757-
)
758756
else:
759757
pyconf.result("no")
760758

Tools/configure/conf_security.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,9 @@ def check_ssl_cipher_suites(v):
303303
pyconf.define("PY_SSL_DEFAULT_CIPHERS", 2)
304304
else:
305305
pyconf.define("PY_SSL_DEFAULT_CIPHERS", 0)
306-
pyconf.define_unquoted("PY_SSL_DEFAULT_CIPHER_STRING", f'"{ssl_suites}"')
306+
pyconf.define_unquoted(
307+
"PY_SSL_DEFAULT_CIPHER_STRING", f'"{ssl_suites}"'
308+
)
307309

308310

309311
def check_builtin_hashlib_hashes(v):

Tools/configure/pyconf.py

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ def _load_config_site() -> None:
217217
continue
218218
name, value = m.group(1), m.group(2)
219219
# Strip surrounding quotes (single or double)
220-
if len(value) >= 2 and value[0] == value[-1] and value[0] in ("'", '"'):
220+
if (
221+
len(value) >= 2
222+
and value[0] == value[-1]
223+
and value[0] in ("'", '"')
224+
):
221225
value = value[1:-1]
222226
# Command-line VAR=VALUE (already in os.environ) takes precedence
223227
if name not in os.environ and not vars.is_set(name):
@@ -1588,7 +1592,7 @@ def _canonicalize(triplet: str) -> str:
15881592
host_parts = host.split("-", 2)
15891593
host_cpu = host_parts[0]
15901594
if build_arg:
1591-
cross_compiling = (host != build)
1595+
cross_compiling = host != build
15921596
else:
15931597
# autoconf sets "maybe" when --host is given without --build
15941598
cross_compiling = "maybe" if host != build else False
@@ -2280,6 +2284,7 @@ def _compute_int(expr: str, includes: str = "") -> int | None:
22802284
22812285
Returns the integer value, or None if it could not be determined.
22822286
"""
2287+
22832288
def _try(boolean_expr: str) -> bool:
22842289
src = (
22852290
f"{includes}\n"
@@ -2602,10 +2607,7 @@ def check_sizeof(
26022607
size = int(output_str.strip())
26032608
if size is None:
26042609
# Cross-compiling or run failed: compile-time binary search
2605-
inc = (
2606-
"#include <stddef.h>\n"
2607-
"#include <stdint.h>\n" + extra_includes
2608-
)
2610+
inc = "#include <stddef.h>\n#include <stdint.h>\n" + extra_includes
26092611
size = _compute_int(f"(long int)(sizeof({type_}))", inc)
26102612
if size is None:
26112613
size = default if default is not None else 0
@@ -2658,10 +2660,7 @@ def check_alignof(type_: str) -> int:
26582660
# Cross-compiling or run failed: compile-time binary search using
26592661
# offsetof(struct{char c; TYPE x;}, x), matching autoconf.
26602662
inc = "#include <stddef.h>\n"
2661-
expr = (
2662-
f"(long int)(offsetof("
2663-
f"struct {{ char c; {type_} x; }}, x))"
2664-
)
2663+
expr = f"(long int)(offsetof(struct {{ char c; {type_} x; }}, x))"
26652664
alignment = _compute_int(expr, inc)
26662665
if alignment is None:
26672666
alignment = 0
@@ -3044,10 +3043,12 @@ def check_decl(
30443043
extra_includes: list[str] | None = None,
30453044
on_found: Any = None,
30463045
on_notfound: Any = None,
3046+
define_name: str | None = None,
30473047
) -> bool:
30483048
"""AC_CHECK_DECL — check if declaration/macro *decl* is available.
30493049
30503050
*includes* / *extra_includes*: headers to include in the test.
3051+
*define_name*: if given, define this macro to 1 when found (0 when not).
30513052
Calls *on_found()* or *on_notfound()* callbacks. Returns bool.
30523053
"""
30533054
if not _RE_DECL_NAME.match(decl):
@@ -3057,14 +3058,25 @@ def check_decl(
30573058
)
30583059
all_includes = list(includes or []) + list(extra_includes or [])
30593060
inc_lines = "".join(f"#include <{h}>\n" for h in all_includes)
3060-
src = f"{inc_lines}\nint main(void) {{\n (void){decl};\n return 0;\n}}\n"
3061-
found = _compile_test(src)
3062-
# AC_CHECK_DECL always writes HAVE_DECL_<name> as 0 or 1
3063-
define(
3064-
"HAVE_DECL_" + decl.upper(),
3065-
1 if found else 0,
3066-
f"Define to 1 if you have the declaration of `{decl}'.",
3061+
# Use #ifndef guard so macros (e.g. NetBSD's dirfd) are detected too.
3062+
# If decl is a macro, the #ifndef body is skipped and compilation
3063+
# succeeds. If it's a real declaration, (void)decl compiles.
3064+
src = (
3065+
f"{inc_lines}\n"
3066+
f"int main(void) {{\n"
3067+
f"#ifndef {decl}\n"
3068+
f" (void){decl};\n"
3069+
f"#endif\n"
3070+
f" return 0;\n"
3071+
f"}}\n"
30673072
)
3073+
found = _compile_test(src)
3074+
if define_name:
3075+
define(
3076+
define_name,
3077+
1 if found else 0,
3078+
f"Define to 1 if you have the declaration of `{decl}'.",
3079+
)
30683080
if found and callable(on_found):
30693081
on_found()
30703082
elif not found and callable(on_notfound):
@@ -3084,11 +3096,11 @@ def check_decls(
30843096
names = [decls] if isinstance(decls, str) else decls
30853097
all_includes = list(includes or []) + list(extra_includes or [])
30863098
for d in names:
3087-
found = check_decl(d, includes=all_includes)
3088-
define(
3089-
"HAVE_DECL_" + d.upper(),
3090-
1 if found else 0,
3091-
f"Define to 1 if you have the declaration of `{d}'.",
3099+
# AC_CHECK_DECLS defines HAVE_DECL_<NAME> as 1 or 0 (always defined)
3100+
check_decl(
3101+
d,
3102+
includes=all_includes,
3103+
define_name="HAVE_DECL_" + d.upper(),
30923104
)
30933105

30943106

Tools/configure/transpiler/pysh_to_awk.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,6 +2402,7 @@ def _check_decl_stmts(self, call: Call) -> list[A.Stmt]:
24022402
includes_var_expr: A.Expr | None = None
24032403
on_found = None
24042404
on_notfound = None
2405+
define_name_lit: str | None = None
24052406
for k, v in call.kwargs.items():
24062407
if k in ("includes", "extra_includes"):
24072408
if isinstance(v, PyshList):
@@ -2415,6 +2416,8 @@ def _check_decl_stmts(self, call: Call) -> list[A.Stmt]:
24152416
on_found = v.name
24162417
elif k == "on_notfound" and isinstance(v, Var):
24172418
on_notfound = v.name
2419+
elif k == "define_name" and isinstance(v, Const):
2420+
define_name_lit = str(v.value)
24182421
includes: A.Expr
24192422
if includes_parts:
24202423
includes = A.StringLit(" ".join(includes_parts))
@@ -2423,7 +2426,9 @@ def _check_decl_stmts(self, call: Call) -> list[A.Stmt]:
24232426
else:
24242427
includes = A.StringLit("")
24252428
define_args: list[A.Expr] = []
2426-
if isinstance(decl_arg, Const) and isinstance(decl_arg.value, str):
2429+
if define_name_lit is not None:
2430+
define_args = [A.StringLit(define_name_lit)]
2431+
elif isinstance(decl_arg, Const) and isinstance(decl_arg.value, str):
24272432
define_args = [
24282433
A.StringLit(_precompute_decl_define(decl_arg.value))
24292434
]
@@ -2466,7 +2471,10 @@ def _build_check_decl_expr(self, call: Call) -> A.FuncCall:
24662471
decl = self._expr(decl_arg)
24672472
includes = self._extract_includes_expr(call)
24682473
define_args: list[A.Expr] = []
2469-
if isinstance(decl_arg, Const) and isinstance(decl_arg.value, str):
2474+
define_name_kw = call.kwargs.get("define_name")
2475+
if define_name_kw is not None and isinstance(define_name_kw, Const):
2476+
define_args = [A.StringLit(str(define_name_kw.value))]
2477+
elif isinstance(decl_arg, Const) and isinstance(decl_arg.value, str):
24702478
define_args = [
24712479
A.StringLit(_precompute_decl_define(decl_arg.value))
24722480
]
@@ -2766,7 +2774,9 @@ def _build_link_check_call(self, method: str, call: Call) -> A.FuncCall:
27662774
else:
27672775
# Insert a literal space between cflags and libs
27682776
args.append(
2769-
A.Concat([extra_parts[0], A.StringLit(" "), extra_parts[1]])
2777+
A.Concat(
2778+
[extra_parts[0], A.StringLit(" "), extra_parts[1]]
2779+
)
27702780
)
27712781
if compiler_kw is not None:
27722782
# Pad extra_flags if not already present

configure-new

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6424,9 +6424,8 @@ function u_check_posix_functions( ANDROID_API_LEVEL, _i_name, blocked_len, ma
64246424

64256425
function u_check_special_functions( _pyconf_cond_sys_eventfd_h, _pyconf_cond_sys_memfd_h, _pyconf_cond_sys_mman_h, _pyconf_cond_sys_timerfd_h, ac_cv_have_chflags, ac_cv_have_lchflags) {
64266426
pyconf_checking("whether dirfd is declared")
6427-
if (pyconf_compile_check("", "#include <sys/types.h>\n#include <dirent.h>\nint main(void) { void *p = dirfd; return 0; }")) {
6427+
if (pyconf_check_decl("dirfd", "sys/types.h dirent.h", "HAVE_DIRFD")) {
64286428
pyconf_result("yes")
6429-
pyconf_define("HAVE_DIRFD", 1, 0, "Define if you have the 'dirfd' function or macro.")
64306429
} else {
64316430
pyconf_result("no")
64326431
}

0 commit comments

Comments
 (0)