diff options
Diffstat (limited to 'src/bfstd.c')
-rw-r--r-- | src/bfstd.c | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/src/bfstd.c b/src/bfstd.c index f8ce871..6d244ca 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -184,6 +184,16 @@ char *xgetdelim(FILE *file, char delim) { } } +int open_cterm(int flags) { + char path[L_ctermid]; + if (ctermid(path) == NULL || strlen(path) == 0) { + errno = ENOTTY; + return -1; + } + + return open(path, flags); +} + const char *xgetprogname(void) { const char *cmd = NULL; #if BFS_HAS_GETPROGNAME @@ -199,6 +209,35 @@ const char *xgetprogname(void) { return cmd; } +int xstrtoll(const char *str, char **end, int base, long long *value) { + // strtoll() skips leading spaces, but we want to reject them + if (xisspace(str[0])) { + errno = EINVAL; + return -1; + } + + // If end is NULL, make sure the entire string is valid + bool entire = !end; + char *endp; + if (!end) { + end = &endp; + } + + errno = 0; + long long result = strtoll(str, end, base); + if (errno != 0) { + return -1; + } + + if (*end == str || (entire && **end != '\0')) { + errno = EINVAL; + return -1; + } + + *value = result; + return 0; +} + /** Compile and execute a regular expression for xrpmatch(). */ static int xrpregex(nl_item item, const char *response) { const char *pattern = nl_langinfo(item); @@ -322,6 +361,10 @@ const char *xstrerror(int errnum) { return ret; } +const char *errstr(void) { + return xstrerror(errno); +} + /** Get the single character describing the given file type. */ static char type_char(mode_t mode) { switch (mode & S_IFMT) { @@ -637,8 +680,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__ @@ -649,11 +698,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; @@ -663,12 +708,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)); } |