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