Branch data Line data Source code
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 <sys/param.h>
39 : : #include <endian.h>
40 : : #include <byteswap.h>
41 : : #include <unistd.h>
42 : : #include <string.h>
43 : : #include <stdarg.h>
44 : : #include <stdlib.h>
45 : :
46 : : #if defined(HAVE_ERROR_H)
47 : : #include <error.h>
48 : : #elif defined(HAVE_ERR_H)
49 : : extern int error_message_count;
50 : : void error(int status, int errnum, const char *format, ...);
51 : : #else
52 : : #error "err.h or error.h must be available"
53 : : #endif
54 : :
55 : : /* error (EXIT_FAILURE, ...) should be noreturn but on some systems it
56 : : isn't. This may cause warnings about code that should not be reachable.
57 : : So have an explicit error_exit wrapper that is noreturn (because it
58 : : calls exit explicitly). */
59 : : #define error_exit(errnum,...) do { \
60 : : error (EXIT_FAILURE,errnum,__VA_ARGS__); \
61 : : exit (EXIT_FAILURE); \
62 : : } while (0)
63 : :
64 : : #if __BYTE_ORDER == __LITTLE_ENDIAN
65 : : # define LE32(n) (n)
66 : : # define LE64(n) (n)
67 : : # define BE32(n) bswap_32 (n)
68 : : # define BE64(n) bswap_64 (n)
69 : : #elif __BYTE_ORDER == __BIG_ENDIAN
70 : : # define BE32(n) (n)
71 : : # define BE64(n) (n)
72 : : # define LE32(n) bswap_32 (n)
73 : : # define LE64(n) bswap_64 (n)
74 : : #else
75 : : # error "Unknown byte order"
76 : : #endif
77 : :
78 : : #ifndef MAX
79 : : #define MAX(m, n) ((m) < (n) ? (n) : (m))
80 : : #endif
81 : :
82 : : #ifndef MIN
83 : : #define MIN(m, n) ((m) < (n) ? (m) : (n))
84 : : #endif
85 : :
86 : : #if !HAVE_DECL_POWEROF2
87 : : #define powerof2(x) (((x) & ((x) - 1)) == 0)
88 : : #endif
89 : :
90 : : #if !HAVE_DECL_MEMPCPY
91 : : #define mempcpy(dest, src, n) \
92 : : ((void *) ((char *) memcpy (dest, src, n) + (size_t) n))
93 : : #endif
94 : :
95 : : #if !HAVE_DECL_REALLOCARRAY
96 : : static inline void *
97 : : reallocarray (void *ptr, size_t nmemb, size_t size)
98 : : {
99 : : if (size > 0 && nmemb > SIZE_MAX / size)
100 : : {
101 : : errno = ENOMEM;
102 : : return NULL;
103 : : }
104 : : return realloc (ptr, nmemb * size);
105 : : }
106 : : #endif
107 : :
108 : : /* Return TRUE if the start of STR matches PREFIX, FALSE otherwise. */
109 : :
110 : : static inline int
111 : 8223350 : startswith (const char *str, const char *prefix)
112 : : {
113 : 8223350 : return strncmp (str, prefix, strlen (prefix)) == 0;
114 : : }
115 : :
116 : : /* A special gettext function we use if the strings are too short. */
117 : : #define sgettext(Str) \
118 : : ({ const char *__res = strrchr (_(Str), '|'); \
119 : : __res ? __res + 1 : Str; })
120 : :
121 : : #define gettext_noop(Str) Str
122 : :
123 : : #ifndef TEMP_FAILURE_RETRY
124 : : #define TEMP_FAILURE_RETRY(expression) \
125 : : ({ ssize_t __res; \
126 : : do \
127 : : __res = expression; \
128 : : while (__res == -1 && errno == EINTR); \
129 : : __res; })
130 : : #endif
131 : :
132 : : #ifndef ACCESSPERMS
133 : : #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */
134 : : #endif
135 : :
136 : : #ifndef ALLPERMS
137 : : #define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) /* 07777 */
138 : : #endif
139 : :
140 : : #ifndef DEFFILEMODE
141 : : #define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* 0666 */
142 : : #endif
143 : :
144 : : static inline ssize_t __attribute__ ((unused))
145 : 1845268 : pwrite_retry (int fd, const void *buf, size_t len, off_t off)
146 : : {
147 : 1845268 : ssize_t recvd = 0;
148 : :
149 : 1845268 : do
150 : : {
151 [ - + - - ]: 1845268 : ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, ((char *)buf) + recvd, len - recvd,
152 : : off + recvd));
153 [ + + ]: 1845268 : if (ret <= 0)
154 [ + - ]: 210 : return ret < 0 ? ret : recvd;
155 : :
156 : 1845058 : recvd += ret;
157 : : }
158 [ - + ]: 1845058 : while ((size_t) recvd < len);
159 : :
160 : : return recvd;
161 : : }
162 : :
163 : : static inline ssize_t __attribute__ ((unused))
164 : 56 : write_retry (int fd, const void *buf, size_t len)
165 : : {
166 : 56 : ssize_t recvd = 0;
167 : :
168 : 56 : do
169 : : {
170 [ - + - - ]: 56 : ssize_t ret = TEMP_FAILURE_RETRY (write (fd, ((char *)buf) + recvd, len - recvd));
171 [ - + ]: 56 : if (ret <= 0)
172 [ # # ]: 0 : return ret < 0 ? ret : recvd;
173 : :
174 : 56 : recvd += ret;
175 : : }
176 [ - + ]: 56 : while ((size_t) recvd < len);
177 : :
178 : : return recvd;
179 : : }
180 : :
181 : : static inline ssize_t __attribute__ ((unused))
182 : 1277785 : pread_retry (int fd, void *buf, size_t len, off_t off)
183 : : {
184 : 1277785 : ssize_t recvd = 0;
185 : :
186 : 1282794 : do
187 : : {
188 [ - + - + : 2565588 : ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, ((char *)buf) + recvd, len - recvd,
- - ]
189 : : off + recvd));
190 [ + + ]: 1282794 : if (ret <= 0)
191 [ + - ]: 5014 : return ret < 0 ? ret : recvd;
192 : :
193 : 1277780 : recvd += ret;
194 : : }
195 [ + + ]: 1277780 : while ((size_t) recvd < len);
196 : :
197 : : return recvd;
198 : : }
199 : :
200 : : /* The demangler from libstdc++. */
201 : : extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
202 : : size_t *length, int *status);
203 : :
204 : : /* A static assertion. This will cause a compile-time error if EXPR,
205 : : which must be a compile-time constant, is false. */
206 : :
207 : : #define eu_static_assert(expr) \
208 : : extern int never_defined_just_used_for_checking[(expr) ? 1 : -1] \
209 : : __attribute__ ((unused))
210 : :
211 : : #endif /* system.h */
|