Download raw body.
-portable: add a wrapper for open() on FreeBSD
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
-portable: add a wrapper for open() on FreeBSD