From nobody Sun May 3 19:59:06 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4g7wZy3Dgpz6c138 for ; Sun, 03 May 2026 19:59:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4g7wZy1n65z42Hk for ; Sun, 03 May 2026 19:59:06 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777838346; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=e9q1k44nN44BXxTg/fq4bmmhip6jOc7LTyrlw//Chpo=; b=BRNiGT3vCXrtnQpt3G/ET/nb/TonOKtjTMcDekwBKSGp1KOeuwHJe/QbBre+0baALVO6Jy Pf19U+lZKCDc/i6Ii8duwA8iQOT8YLDfx6dZGniLL3/Ewxx0pj10vMx80UMkHEGxiw1/fF gYJa9ye6b4GRPs+syZtlJ47GRtmp5VOMPjt+jg9F+bZ78JpXayudY7HjXBX48VU6DtPt4P 0WihiFaTsKSlSemKfTwaWC9dOGjtg45tXLkFgZn1/YgcgRHgK0ZgL6QfAWM5Yu0hOa/05t ZuSbIbHSu4miGEGIJlPad2ydIFUinOC/KWne79yW6X19iDI+Mc8aiJFDkALeoA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1777838346; a=rsa-sha256; cv=none; b=bNnn6DusmS5eECCPJfAdIgkrfJOztyUedfIjv2Wu0kok3ibVZeV0Um/akb+o+mZB0qli/n mqRwmdFiYnm6EPH09w4YkKGyB8XqvlqYSFsozDEQSMXXKRsucLJlFO2nWY6o+CzjRYfueF qnYnVGoXXH0e9Pl4pao/muEIvDKbozz8jUeHjUcg2oNc0XJif0AFx1t3JTd9onRf16+Fre GXDqvWd/JAX+iJCZQ1Rm+1nLmXn4pYIf/1GDb8ewVaCcRib7c7wz4/TvYmpVgN5oSKRBw0 myZxrDhCAInbR/MYXDioaTCzcHvogpazZA1OLxQXCXBwrjfr6RdGacWSBzkHKA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777838346; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=e9q1k44nN44BXxTg/fq4bmmhip6jOc7LTyrlw//Chpo=; b=rue0DK/iG/ivrH0L8n5OuN2W5XsiCjNI8l7Qc0SjA80yYJDHNfKGNxSsGkLhoKVnb6rPHD bfUNSQf3nKzS6wzaEuFlfdvqbnzlmw7yBuX9jOfL6SQ4VKQmMlX6DOzoxiW7mlwP1DZJxp kDiimkNSyQnTQzS+FNKj3ITjHP5pEKGg0MkTeBnU1Cu54DeqJrcUVurrqPFQOfi8ABeZFk oKOmjyfzYRDNRnc+3j3MW3EHXJzSdWG7GU3MAAn/QI4Jgiv52O5LzS/YHyx6srkHHeiW0k jSsJW8+m8LvEOFHrdNDoB7F3RDDH4KNzZadkbxLsBW86/B4mAaQa1aLHu6uXnA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g7wZy1JC0zn3t for ; Sun, 03 May 2026 19:59:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 40cde by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 03 May 2026 19:59:06 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: f9458655e78f - main - Add O_SYMLINK emulation List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f9458655e78f6532e962a13d28d6a6086b4156de Auto-Submitted: auto-generated Date: Sun, 03 May 2026 19:59:06 +0000 Message-Id: <69f7a90a.40cde.3f32aeed@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=f9458655e78f6532e962a13d28d6a6086b4156de commit f9458655e78f6532e962a13d28d6a6086b4156de Author: Konstantin Belousov AuthorDate: 2026-04-12 08:48:32 +0000 Commit: Konstantin Belousov CommitDate: 2026-05-03 19:58:36 +0000 Add O_SYMLINK emulation for MacOSX partial compatibility, defined as O_PATH | O_SYNC | O_DIRECT. libc openat() wrapper is modified to fstat() the descriptor and re-open in the normal mode if the type is not symlink. Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D56365 --- lib/libc/include/libc_private.h | 3 +++ lib/libc/sys/Symbol.map | 4 ++++ lib/libc/sys/open.c | 4 +++- lib/libc/sys/openat.c | 44 +++++++++++++++++++++++++++++++++++++++- lib/libthr/thread/thr_syscalls.c | 5 ++++- sys/sys/fcntl.h | 6 +++--- 6 files changed, 60 insertions(+), 6 deletions(-) diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 299629fce2ad..ef490e1a66ef 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -384,4 +384,7 @@ struct uexterror; int __uexterr_format(const struct uexterror *ue, char *buf, size_t bufsz); int __libc_uexterr_gettext(char *buf, size_t bufsz); +int __impl_openat(int fd, const char *path, int flags, ...); +int __openat_symlink(int fd, const char *path, int flags, int interposed); + #endif /* _LIBC_PRIVATE_H_ */ diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index 8acffcfd714e..1bae1fb78538 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -75,3 +75,7 @@ FBSD_1.7 { FBSD_1.9 { pdwait; }; + +FBSDprivate_1.0 { + __openat_symlink; +}; diff --git a/lib/libc/sys/open.c b/lib/libc/sys/open.c index dd7bedebf141..d58a81f60b18 100644 --- a/lib/libc/sys/open.c +++ b/lib/libc/sys/open.c @@ -29,9 +29,11 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "namespace.h" #include #include #include +#include "un-namespace.h" #include "libc_private.h" #pragma weak open @@ -48,5 +50,5 @@ open(const char *path, int flags, ...) } else { mode = 0; } - return (INTERPOS_SYS(openat, AT_FDCWD, path, flags, mode)); + return (__impl_openat(AT_FDCWD, path, flags, mode)); } diff --git a/lib/libc/sys/openat.c b/lib/libc/sys/openat.c index ba937cae3a3e..f4223be8aad7 100644 --- a/lib/libc/sys/openat.c +++ b/lib/libc/sys/openat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 The FreeBSD Foundation. + * Copyright 2014, 2026 The FreeBSD Foundation. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. @@ -29,11 +29,46 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "namespace.h" #include #include +#include +#include #include +#include +#include "un-namespace.h" #include "libc_private.h" +static int +do_openat(int fd, const char *path, int flags, int interposed) +{ + if (interposed) + return (__sys_openat(fd, path, flags | O_PATH, 0)); + return (INTERPOS_SYS(openat, fd, path, flags | O_PATH, 0)); +} + +int +__openat_symlink(int fd, const char *path, int flags, int interposed) +{ + struct stat st; + int rfd, xfd, saved_errno; + + flags &= ~O_SYMLINK; + rfd = do_openat(fd, path, flags | O_PATH | O_NOFOLLOW, interposed); + if (rfd != -1 && _fstat(rfd, &st) != -1 && !S_ISLNK(st.st_mode)) { + xfd = do_openat(rfd, "", flags | O_EMPTY_PATH, interposed); + saved_errno = errno; + /* dup to rfd to guarantee lowest fd number value */ + if (_dup2(xfd, rfd) == -1) { + _close(rfd); + rfd = -1; + } + _close(xfd); + errno = saved_errno; + } + return (rfd); +} + __sym_compat(openat, __impl_openat, FBSD_1.1); __weak_reference(openat, __impl_openat); __sym_default(openat, openat, FBSD_1.2); @@ -45,12 +80,19 @@ openat(int fd, const char *path, int flags, ...) va_list ap; int mode; + if (__predict_false((flags & (O_SYMLINK | O_CREAT)) == + (O_SYMLINK | O_CREAT))) { + errno = EINVAL; + return (-1); + } if ((flags & O_CREAT) != 0) { va_start(ap, flags); mode = va_arg(ap, int); va_end(ap); } else { mode = 0; + if (__predict_false((flags & O_SYMLINK) == O_SYMLINK)) + return (__openat_symlink(fd, path, flags, 0)); } return (INTERPOS_SYS(openat, fd, path, flags, mode)); } diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c index bff2d0624aee..8168185188ea 100644 --- a/lib/libthr/thread/thr_syscalls.c +++ b/lib/libthr/thread/thr_syscalls.c @@ -298,7 +298,10 @@ __thr_openat(int fd, const char *path, int flags, int mode) curthread = _get_curthread(); _thr_cancel_enter(curthread); - ret = __sys_openat(fd, path, flags, mode); + if (__predict_false((flags & O_SYMLINK) == O_SYMLINK)) + ret = __openat_symlink(fd, path, flags, 1); + else + ret = __sys_openat(fd, path, flags, mode); _thr_cancel_leave(curthread, ret == -1); return (ret); diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 80cbca4ea753..bf64d06f2a4d 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -145,10 +145,10 @@ typedef __pid_t pid_t; /* * Emulate MacOSX compatibility flag without consuming a flags bit. - * It is not fully correct since reads over regular files opened with - * this definition fail. + * Selected bits set does not define a useful open request and is + * unlikely to be specified by reasonable code. */ -#define O_SYMLINK (O_PATH | O_NOFOLLOW) +#define O_SYMLINK (O_PATH | O_DSYNC | O_DIRECT) #endif #if __POSIX_VISIBLE >= 202405