"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Christian Weisgerber <naddy@mips.inka.de>
Subject:
-portable: add a wrapper for open() on FreeBSD
To:
gameoftrees@openbsd.org
Date:
Sat, 25 Sep 2021 23:20:54 +0200

Download raw body.

Thread
add a wrapper function to render open() POSIX-compliant on FreeBSD

POSIX mandates that open(symlink, O_NOFOLLOW) fail with errno == ELOOP.
FreeBSD chooses to deviate from this, but Got depends on it.  Introducing
a wrapper avoids (1) the need to patch every occurrence, (2) having to
check each release for new instances, and (3) slipups when modifying
complex boolean expressions.

That is one evil trap.  I'll note that the policy of only including
"got_compat.h" where necessary undermines point (2) above.

See...
https://cgit.freebsd.org/ports/commit/devel/got?id=18588b77ae6f90bfd0ee211a8555bbd4a494fc7f
... for what the alternative to using a wrapper looks like.

diff refs/heads/linux refs/heads/open
blob - 77a4b663e28d1206c2b7ed331a3fef25b9a5e44d
blob + cac0ca10868902d4b8f13bd9c598ffb46199b277
--- compat/Makefile.am
+++ compat/Makefile.am
@@ -33,6 +33,7 @@ libopenbsd_compat_a_SOURCES =  \
 	queue.h \
 	tree.h
 if HOST_FREEBSD
+libopenbsd_compat_a_SOURCES += open.c
 else
 libopenbsd_compat_a_SOURCES += uuid.c
 endif
blob - /dev/null
blob + fa9207c0814e06787a1c4d0fefeb49f9884eac1d (mode 644)
--- /dev/null
+++ compat/open.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020 Christian Weisgerber <naddy@FreeBSD.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+/*
+ * POSIX mandates that open(symlink, O_NOFOLLOW) fail with errno == ELOOP.
+ * FreeBSD chooses to deviate from this, but Got depends on it.
+ */
+int
+open_posix(const char *path, int flags, ...)
+{
+	va_list ap;
+	mode_t mode;
+	int ret;
+
+	if (flags & O_CREAT) {
+		va_start(ap, flags);
+		mode = va_arg(ap, int);
+		va_end(ap);
+		ret = open(path, flags, mode);
+	} else
+		ret = open(path, flags);
+
+	if (ret == -1 && (flags & O_NOFOLLOW) && errno == EMLINK)
+		errno = ELOOP;
+
+	return (ret);
+}
+
+int
+openat_posix(int fd, const char *path, int flags, ...)
+{
+	va_list ap;
+	mode_t mode;
+	int ret;
+
+	if (flags & O_CREAT) {
+		va_start(ap, flags);
+		mode = va_arg(ap, int);
+		va_end(ap);
+		ret = openat(fd, path, flags, mode);
+	} else
+		ret = openat(fd, path, flags);
+
+	if (ret == -1 && (flags & O_NOFOLLOW) && errno == EMLINK)
+		errno = ELOOP;
+
+	return (ret);
+}
blob - 78da94b5a6a66a86e58077352388589e6c6a18f2
blob + 6ec59b41e2b31f7a66136536f5250312b01ce941
--- include/got_compat.h
+++ include/got_compat.h
@@ -143,6 +143,12 @@ int		 getdtablecount(void);
 
 #if defined (__FreeBSD__)
 #define closefrom(fd) (closefrom(fd), 0)
+
+#define open(...)	open_posix(__VA_ARGS__)
+#define openat(...)	openat_posix(__VA_ARGS__)
+
+int		 open_posix(const char *path, int flags, ...);
+int		 openat_posix(int fd, const char *path, int flags, ...);
 #endif
 
 #ifndef HAVE_STRSEP
blob - 38acc9c78c5f563fd844785003973ca9c8bcd73e
blob + b6c85dcb97b05b93e0008f39724e9b5ed3a2a0e2
--- lib/buf.c
+++ lib/buf.c
@@ -34,6 +34,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "got_compat.h"
+
 #include "buf.h"
 
 #include "got_error.h"
blob - 165216e417422d26d0b171457e55841b60a1fe94
blob + 58992a31e092963d14ba9f21602a91a64c570397
--- lib/lockfile.c
+++ lib/lockfile.c
@@ -24,6 +24,8 @@
 #include <stdio.h>
 #include <time.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_path.h"
 
blob - 0dd65c8a831a778b1fb0333b3c7f20b4b0700e43
blob + bbecfeb436f8dcdfe38b00b23f0739915cf1b0a1
--- lib/pack.c
+++ lib/pack.c
@@ -29,6 +29,8 @@
 #include <unistd.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 #include "got_opentemp.h"
blob - f73c38388a2637a76122e000a939cc43c4314c89
blob + f323e1ea677a8090b5d4c43e98334e5429bfccb6
--- lib/repository_admin.c
+++ lib/repository_admin.c
@@ -30,6 +30,8 @@
 #include <limits.h>
 #include <unistd.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_cancel.h"
 #include "got_object.h"
-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de