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 <string.h>
39 : : #include <stdarg.h>
40 : : #include <stdlib.h>
41 : :
42 : : /* System dependent 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 *
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
114 : 13669876 : startswith (const char *str, const char *prefix)
115 : : {
116 : 13669876 : 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))
148 : 2122850 : pwrite_retry (int fd, const void *buf, size_t len, off_t off)
149 : : {
150 : 2122850 : ssize_t recvd = 0;
151 : :
152 : 2122874 : do
153 : : {
154 [ - + - - ]: 2122874 : ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, ((char *)buf) + recvd, len - recvd,
155 : : off + recvd));
156 [ + + ]: 2122874 : if (ret <= 0)
157 [ + - ]: 486 : return ret < 0 ? ret : recvd;
158 : :
159 : 2122388 : recvd += ret;
160 : : }
161 [ + + ]: 2122388 : while ((size_t) recvd < len);
162 : :
163 : : return recvd;
164 : : }
165 : :
166 : : static inline ssize_t __attribute__ ((unused))
167 : 158 : write_retry (int fd, const void *buf, size_t len)
168 : : {
169 : 158 : ssize_t recvd = 0;
170 : :
171 : 158 : do
172 : : {
173 [ - + - - ]: 158 : ssize_t ret = TEMP_FAILURE_RETRY (write (fd, ((char *)buf) + recvd, len - recvd));
174 [ - + ]: 158 : if (ret <= 0)
175 [ # # ]: 0 : return ret < 0 ? ret : recvd;
176 : :
177 : 158 : recvd += ret;
178 : : }
179 [ - + ]: 158 : while ((size_t) recvd < len);
180 : :
181 : : return recvd;
182 : : }
183 : :
184 : : static inline ssize_t __attribute__ ((unused))
185 : 1510592 : pread_retry (int fd, void *buf, size_t len, off_t off)
186 : : {
187 : 1510592 : ssize_t recvd = 0;
188 : :
189 : 1520630 : do
190 : : {
191 [ + + - + : 3041260 : ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, ((char *)buf) + recvd, len - recvd,
- - ]
192 : : off + recvd));
193 [ + + ]: 1520630 : if (ret <= 0)
194 [ + - ]: 10032 : return ret < 0 ? ret : recvd;
195 : :
196 : 1510598 : recvd += ret;
197 : : }
198 [ + + ]: 1510598 : 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 */
|