summaryrefslogtreecommitdiffstats
path: root/src/bfstd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bfstd.c')
-rw-r--r--src/bfstd.c161
1 files changed, 88 insertions, 73 deletions
diff --git a/src/bfstd.c b/src/bfstd.c
index 2499f00..7680f17 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -1,9 +1,9 @@
// Copyright © Tavian Barnes <tavianator@tavianator.com>
// SPDX-License-Identifier: 0BSD
+#include "prelude.h"
#include "bfstd.h"
#include "bit.h"
-#include "config.h"
#include "diag.h"
#include "sanity.h"
#include "thread.h"
@@ -186,10 +186,10 @@ char *xgetdelim(FILE *file, char delim) {
const char *xgetprogname(void) {
const char *cmd = NULL;
-#if __GLIBC__
- cmd = program_invocation_short_name;
-#elif BSD
+#if BFS_HAS_GETPROGNAME
cmd = getprogname();
+#elif BFS_HAS_GETPROGNAME_GNU
+ cmd = program_invocation_short_name;
#endif
if (!cmd) {
@@ -252,40 +252,6 @@ int ynprompt(void) {
return ret;
}
-/** Get the single character describing the given file type. */
-static char type_char(mode_t mode) {
- switch (mode & S_IFMT) {
- case S_IFREG:
- return '-';
- case S_IFBLK:
- return 'b';
- case S_IFCHR:
- return 'c';
- case S_IFDIR:
- return 'd';
- case S_IFLNK:
- return 'l';
- case S_IFIFO:
- return 'p';
- case S_IFSOCK:
- return 's';
-#ifdef S_IFDOOR
- case S_IFDOOR:
- return 'D';
-#endif
-#ifdef S_IFPORT
- case S_IFPORT:
- return 'P';
-#endif
-#ifdef S_IFWHT
- case S_IFWHT:
- return 'w';
-#endif
- }
-
- return '?';
-}
-
void *xmemdup(const void *src, size_t size) {
void *ret = malloc(size);
if (ret) {
@@ -317,35 +283,33 @@ const char *xstrerror(int errnum) {
const char *ret = NULL;
static thread_local char buf[256];
- // - __APPLE__
- // - __COSMOPOLITAN__
- // - No strerror_l()
- // - __FreeBSD__ && SANITIZE_MEMORY
- // - duplocale() triggers https://github.com/llvm/llvm-project/issues/65532
-#if __APPLE__ || __COSMOPOLITAN__ || (__FreeBSD__ && SANITIZE_MEMORY)
- if (strerror_r(errnum, buf, sizeof(buf)) == 0) {
- ret = buf;
- }
-#else
-# if __NetBSD__
- // NetBSD has no thread-specific locales
- locale_t loc = LC_GLOBAL_LOCALE;
-# else
+ // On FreeBSD with MemorySanitizer, duplocale() triggers
+ // https://github.com/llvm/llvm-project/issues/65532
+#if BFS_HAS_STRERROR_L && !(__FreeBSD__ && SANITIZE_MEMORY)
+# if BFS_HAS_USELOCALE
locale_t loc = uselocale((locale_t)0);
+# else
+ locale_t loc = LC_GLOBAL_LOCALE;
# endif
- locale_t copy = loc;
- if (copy == LC_GLOBAL_LOCALE) {
- copy = duplocale(copy);
+ bool free_loc = false;
+ if (loc == LC_GLOBAL_LOCALE) {
+ loc = duplocale(loc);
+ free_loc = true;
}
- if (copy != (locale_t)0) {
- ret = strerror_l(errnum, copy);
-
- if (loc == LC_GLOBAL_LOCALE) {
- freelocale(copy);
+ if (loc != (locale_t)0) {
+ ret = strerror_l(errnum, loc);
+ if (free_loc) {
+ freelocale(loc);
}
}
+#elif BFS_HAS_STRERROR_R_POSIX
+ if (strerror_r(errnum, buf, sizeof(buf)) == 0) {
+ ret = buf;
+ }
+#elif BFS_HAS_STRERROR_R_GNU
+ ret = strerror_r(errnum, buf, sizeof(buf));
#endif
if (!ret) {
@@ -358,6 +322,40 @@ const char *xstrerror(int errnum) {
return ret;
}
+/** Get the single character describing the given file type. */
+static char type_char(mode_t mode) {
+ switch (mode & S_IFMT) {
+ case S_IFREG:
+ return '-';
+ case S_IFBLK:
+ return 'b';
+ case S_IFCHR:
+ return 'c';
+ case S_IFDIR:
+ return 'd';
+ case S_IFLNK:
+ return 'l';
+ case S_IFIFO:
+ return 'p';
+ case S_IFSOCK:
+ return 's';
+#ifdef S_IFDOOR
+ case S_IFDOOR:
+ return 'D';
+#endif
+#ifdef S_IFPORT
+ case S_IFPORT:
+ return 'P';
+#endif
+#ifdef S_IFWHT
+ case S_IFWHT:
+ return 'w';
+#endif
+ }
+
+ return '?';
+}
+
void xstrmode(mode_t mode, char str[11]) {
strcpy(str, "----------");
@@ -489,7 +487,7 @@ int dup_cloexec(int fd) {
}
int pipe_cloexec(int pipefd[2]) {
-#if __linux__ || (BSD && !__APPLE__)
+#if BFS_HAS_PIPE2
return pipe2(pipefd, O_CLOEXEC);
#else
if (pipe(pipefd) != 0) {
@@ -581,10 +579,7 @@ int xfaccessat(int fd, const char *path, int amode) {
}
char *xconfstr(int name) {
-#if __ANDROID__
- errno = ENOTSUP;
- return NULL;
-#else
+#if BFS_HAS_CONFSTR
size_t len = confstr(name, NULL, 0);
if (len == 0) {
return NULL;
@@ -601,7 +596,10 @@ char *xconfstr(int name) {
}
return str;
-#endif // !__ANDROID__
+#else
+ errno = ENOTSUP;
+ return NULL;
+#endif
}
char *xreadlinkat(int fd, const char *path, size_t size) {
@@ -639,8 +637,14 @@ error:
return NULL;
}
+#if BFS_HAS_STRTOFFLAGS
+# define BFS_STRTOFFLAGS strtofflags
+#elif BFS_HAS_STRING_TO_FLAGS
+# define BFS_STRTOFFLAGS string_to_flags
+#endif
+
int xstrtofflags(const char **str, unsigned long long *set, unsigned long long *clear) {
-#if BSD && !__GNU__
+#ifdef BFS_STRTOFFLAGS
char *str_arg = (char *)*str;
#if __OpenBSD__
@@ -651,11 +655,7 @@ int xstrtofflags(const char **str, unsigned long long *set, unsigned long long *
bfs_fflags_t set_arg = 0;
bfs_fflags_t clear_arg = 0;
-#if __NetBSD__
- int ret = string_to_flags(&str_arg, &set_arg, &clear_arg);
-#else
- int ret = strtofflags(&str_arg, &set_arg, &clear_arg);
-#endif
+ int ret = BFS_STRTOFFLAGS(&str_arg, &set_arg, &clear_arg);
*str = str_arg;
*set = set_arg;
@@ -665,12 +665,27 @@ int xstrtofflags(const char **str, unsigned long long *set, unsigned long long *
errno = EINVAL;
}
return ret;
-#else // !BSD
+#else // !BFS_STRTOFFLAGS
errno = ENOTSUP;
return -1;
#endif
}
+long xsysconf(int name) {
+#if __FreeBSD__ && SANITIZE_MEMORY
+ // Work around https://github.com/llvm/llvm-project/issues/88163
+ __msan_scoped_disable_interceptor_checks();
+#endif
+
+ long ret = sysconf(name);
+
+#if __FreeBSD__ && SANITIZE_MEMORY
+ __msan_scoped_enable_interceptor_checks();
+#endif
+
+ return ret;
+}
+
size_t asciilen(const char *str) {
return asciinlen(str, strlen(str));
}