Page MenuHomeFreeBSD

D56365.id175628.diff
No OneTemporary

D56365.id175628.diff

diff --git a/include/unistd.h b/include/unistd.h
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -518,6 +518,7 @@
int feature_present(const char *);
int fchroot(int);
char *fflagstostr(u_long);
+ssize_t freadlink(int fd, char *buf, size_t bufsize);
int getdomainname(char *, int);
int getentropy(void *, size_t);
int getgrouplist(const char *, gid_t, gid_t *, int *);
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -56,6 +56,7 @@
fmtmsg.c \
fnmatch.c \
fpclassify.c \
+ freadlink.c \
frexp.c \
fstab.c \
ftok.c \
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -475,6 +475,7 @@
};
FBSD_1.9 {
+ freadlink;
posix_spawn_file_actions_addchdir;
posix_spawn_file_actions_addfchdir;
posix_spawnattr_getexecfd_np;
diff --git a/lib/libc/gen/freadlink.c b/lib/libc/gen/freadlink.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/gen/freadlink.c
@@ -0,0 +1,16 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2026 The FreeBSD Foundation
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#include <unistd.h>
+
+ssize_t
+freadlink(int fd, char *buf, size_t bufsize)
+{
+ return (readlinkat(fd, "", buf, bufsize));
+}
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
--- a/lib/libc/include/libc_private.h
+++ b/lib/libc/include/libc_private.h
@@ -384,4 +384,7 @@
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
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -75,3 +75,7 @@
FBSD_1.9 {
pdwait;
};
+
+FBSDprivate_1.0 {
+ __openat_symlink;
+};
diff --git a/lib/libc/sys/open.c b/lib/libc/sys/open.c
--- 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 <sys/types.h>
#include <sys/fcntl.h>
#include <stdarg.h>
+#include "un-namespace.h"
#include "libc_private.h"
#pragma weak open
@@ -48,5 +50,5 @@
} 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
--- 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 <sys/types.h>
#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
#include <stdarg.h>
+#include <unistd.h>
+#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 @@
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
--- a/lib/libthr/thread/thr_syscalls.c
+++ b/lib/libthr/thread/thr_syscalls.c
@@ -298,7 +298,10 @@
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
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -142,6 +142,13 @@
#define O_EMPTY_PATH 0x02000000
#define O_NAMEDATTR 0x04000000 /* NFSv4 named attributes */
#define O_XATTR O_NAMEDATTR /* Solaris compatibility */
+
+/*
+ * Emulate MacOSX compatibility flag without consuming a flags bit.
+ * 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_DSYNC | O_DIRECT)
#endif
#if __POSIX_VISIBLE >= 202405

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 12, 6:35 AM (7 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40657131
Default Alt Text
D56365.id175628.diff (5 KB)

Event Timeline