/** * bookmarkfs/src/xstd.c * ---- * * Copyright (C) 2024 CismonX * * This file is part of BookmarkFS. * * BookmarkFS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * BookmarkFS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with BookmarkFS. If not, see . */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "xstd.h" #include #include #include #include #include #include void xabort_ ( #ifdef BOOKMARKFS_DEBUG char const *assertion, #endif char const *name, int line ) { #ifdef BOOKMARKFS_DEBUG fprintf(stderr, "%s:%d: assertion failed: %s\n", name, line, assertion); #else fprintf(stderr, "%s:%d: assertion failed\n", name, line); #endif abort(); } void * xcalloc ( size_t nmemb, size_t size ) { void *p = calloc(nmemb, size); xassert(p != NULL); return p; } int xfsync ( int fd ) { while (unlikely(0 != fsync(fd))) { int err = errno; log_printf("fsync(): %s", xstrerror(err)); switch (err) { case EIO: #ifdef __FreeBSD__ case EINTEGRITY: #endif abort(); case EINTR: continue; default: return -1; } } return 0; } void * xmalloc ( size_t size ) { void *p = malloc(size); xassert(p != NULL); return p; } int xpipe2 ( int pipefd[2], int flags ) { #ifdef HAVE_PIPE2 if (0 != pipe2(pipefd, flags)) { log_printf("pipe2(): %s", xstrerror(errno)); return -1; } return 0; #else /* !defined(HAVE_PIPE2) */ if (0 != pipe(pipefd)) { log_printf("pipe(): %s", xstrerror(errno)); return -1; } int extra_fdflags = 0; if (flags & O_CLOEXEC) { extra_fdflags |= FD_CLOEXEC; } for (int i = 0; i < 2; ++i) { int fd = pipefd[i]; int fdflags = fcntl(fd, F_GETFD); if (fdflags < 0) { goto fail; } if (0 != fcntl(fd, F_SETFD, fdflags | extra_fdflags)) { goto fail; } } return 0; fail: log_printf("fcntl(): %s", xstrerror(errno)); close(pipefd[0]); close(pipefd[1]); return -1; #endif /* defined(HAVE_PIPE2) */ } void * xrealloc ( void *p, size_t size ) { p = realloc(p, size); xassert(p != NULL); return p; } char const * xstrerror ( int err_num ) { locale_t loc = uselocale((locale_t)0); xassert(loc != (locale_t)0); locale_t loc_copy = loc; if (loc == LC_GLOBAL_LOCALE) { loc_copy = duplocale(loc); xassert(loc_copy != (locale_t)0); } char const *err_str = strerror_l(err_num, loc_copy); if (loc == LC_GLOBAL_LOCALE) { freelocale(loc_copy); } return err_str; }