1/* Declarations for common convenience functions. 2 Copyright (C) 2006-2011 Red Hat, Inc. 3 Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org> 4 This file is part of elfutils. 5 6 This file is free software; you can redistribute it and/or modify 7 it under the terms of either 8 9 * the GNU Lesser General Public License as published by the Free 10 Software Foundation; either version 3 of the License, or (at 11 your option) any later version 12 13 or 14 15 * the GNU General Public License as published by the Free 16 Software Foundation; either version 2 of the License, or (at 17 your option) any later version 18 19 or both in parallel, as here. 20 21 elfutils is distributed in the hope that it will be useful, but 22 WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 General Public License for more details. 25 26 You should have received copies of the GNU General Public License and 27 the GNU Lesser General Public License along with this program. If 28 not, see <http://www.gnu.org/licenses/>. */ 29 30#ifndef LIB_SYSTEM_H 31#define LIB_SYSTEM_H 1 32 33#include <config.h> 34 35#include <errno.h> 36#include <stddef.h> 37#include <stdint.h> 38#include <string.h> 39#include <stdarg.h> 40#include <stdlib.h> 41 42/* System dependend headers */ 43#include <byteswap.h> 44#include <endian.h> 45#include <sys/mman.h> 46#include <sys/param.h> 47#include <unistd.h> 48 49#if defined(HAVE_ERROR_H) 50#include <error.h> 51#elif defined(HAVE_ERR_H) 52extern int error_message_count; 53void error(int status, int errnum, const char *format, ...); 54#else 55#error "err.h or error.h must be available" 56#endif 57 58/* error (EXIT_FAILURE, ...) should be noreturn but on some systems it 59 isn't. This may cause warnings about code that should not be reachable. 60 So have an explicit error_exit wrapper that is noreturn (because it 61 calls exit explicitly). */ 62#define error_exit(errnum,...) do { \ 63 error (EXIT_FAILURE,errnum,__VA_ARGS__); \ 64 exit (EXIT_FAILURE); \ 65 } while (0) 66 67#if BYTE_ORDER == LITTLE_ENDIAN 68# define LE32(n) (n) 69# define LE64(n) (n) 70# define BE32(n) bswap_32 (n) 71# define BE64(n) bswap_64 (n) 72#elif BYTE_ORDER == BIG_ENDIAN 73# define BE32(n) (n) 74# define BE64(n) (n) 75# define LE32(n) bswap_32 (n) 76# define LE64(n) bswap_64 (n) 77#else 78# error "Unknown byte order" 79#endif 80 81#ifndef MAX 82#define MAX(m, n) ((m) < (n) ? (n) : (m)) 83#endif 84 85#ifndef MIN 86#define MIN(m, n) ((m) < (n) ? (m) : (n)) 87#endif 88 89#if !HAVE_DECL_POWEROF2 90#define powerof2(x) (((x) & ((x) - 1)) == 0) 91#endif 92 93#if !HAVE_DECL_MEMPCPY 94#define mempcpy(dest, src, n) \ 95 ((void *) ((char *) memcpy (dest, src, n) + (size_t) n)) 96#endif 97 98#if !HAVE_DECL_REALLOCARRAY 99static inline void * 100reallocarray (void *ptr, size_t nmemb, size_t size) 101{ 102 if (size > 0 && nmemb > SIZE_MAX / size) 103 { 104 errno = ENOMEM; 105 return NULL; 106 } 107 return realloc (ptr, nmemb * size); 108} 109#endif 110 111/* Return TRUE if the start of STR matches PREFIX, FALSE otherwise. */ 112 113static inline int 114startswith (const char *str, const char *prefix) 115{ 116 return strncmp (str, prefix, strlen (prefix)) == 0; 117} 118 119/* A special gettext function we use if the strings are too short. */ 120#define sgettext(Str) \ 121 ({ const char *__res = strrchr (_(Str), '|'); \ 122 __res ? __res + 1 : Str; }) 123 124#define gettext_noop(Str) Str 125 126#ifndef TEMP_FAILURE_RETRY 127#define TEMP_FAILURE_RETRY(expression) \ 128 ({ ssize_t __res; \ 129 do \ 130 __res = expression; \ 131 while (__res == -1 && errno == EINTR); \ 132 __res; }) 133#endif 134 135#ifndef ACCESSPERMS 136#define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */ 137#endif 138 139#ifndef ALLPERMS 140#define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) /* 07777 */ 141#endif 142 143#ifndef DEFFILEMODE 144#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* 0666 */ 145#endif 146 147static inline ssize_t __attribute__ ((unused)) 148pwrite_retry (int fd, const void *buf, size_t len, off_t off) 149{ 150 ssize_t recvd = 0; 151 152 do 153 { 154 ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, ((char *)buf) + recvd, len - recvd, 155 off + recvd)); 156 if (ret <= 0) 157 return ret < 0 ? ret : recvd; 158 159 recvd += ret; 160 } 161 while ((size_t) recvd < len); 162 163 return recvd; 164} 165 166static inline ssize_t __attribute__ ((unused)) 167write_retry (int fd, const void *buf, size_t len) 168{ 169 ssize_t recvd = 0; 170 171 do 172 { 173 ssize_t ret = TEMP_FAILURE_RETRY (write (fd, ((char *)buf) + recvd, len - recvd)); 174 if (ret <= 0) 175 return ret < 0 ? ret : recvd; 176 177 recvd += ret; 178 } 179 while ((size_t) recvd < len); 180 181 return recvd; 182} 183 184static inline ssize_t __attribute__ ((unused)) 185pread_retry (int fd, void *buf, size_t len, off_t off) 186{ 187 ssize_t recvd = 0; 188 189 do 190 { 191 ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, ((char *)buf) + recvd, len - recvd, 192 off + recvd)); 193 if (ret <= 0) 194 return ret < 0 ? ret : recvd; 195 196 recvd += ret; 197 } 198 while ((size_t) recvd < len); 199 200 return recvd; 201} 202 203/* The demangler from libstdc++. */ 204extern char *__cxa_demangle (const char *mangled_name, char *output_buffer, 205 size_t *length, int *status); 206 207/* A static assertion. This will cause a compile-time error if EXPR, 208 which must be a compile-time constant, is false. */ 209 210#define eu_static_assert(expr) \ 211 extern int never_defined_just_used_for_checking[(expr) ? 1 : -1] \ 212 __attribute__ ((unused)) 213 214#endif /* system.h */ 215