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)
52 extern int error_message_count;
53 void 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
99 static inline void *
reallocarray(void * ptr,size_t nmemb,size_t size)100 reallocarray (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
113 static inline int
startswith(const char * str,const char * prefix)114 startswith (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
147 static inline ssize_t __attribute__ ((unused))
pwrite_retry(int fd,const void * buf,size_t len,off_t off)148 pwrite_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
166 static inline ssize_t __attribute__ ((unused))
write_retry(int fd,const void * buf,size_t len)167 write_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
184 static inline ssize_t __attribute__ ((unused))
pread_retry(int fd,void * buf,size_t len,off_t off)185 pread_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++. */
204 extern 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