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