xref: /third_party/elfutils/lib/system.h (revision da0c48c4)
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