1 /* Declarations for common convenience functions.
2 Copyright (C) 2006-2011 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
28
29 #ifndef LIB_SYSTEM_H
30 #define LIB_SYSTEM_H 1
31
32 #include <config.h>
33
34 #include <errno.h>
35 #include <stddef.h>
36 #include <stdint.h>
37 #include <sys/param.h>
38 #include <endian.h>
39 #include <byteswap.h>
40 #include <unistd.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #include <stdlib.h>
44
45 #if defined(HAVE_ERROR_H)
46 #include <error.h>
47 #elif defined(HAVE_ERR_H)
48 extern int error_message_count;
49 void error(int status, int errnum, const char *format, ...);
50 #else
51 #error "err.h or error.h must be available"
52 #endif
53
54 #if __BYTE_ORDER == __LITTLE_ENDIAN
55 # define LE32(n) (n)
56 # define LE64(n) (n)
57 # define BE32(n) bswap_32 (n)
58 # define BE64(n) bswap_64 (n)
59 #elif __BYTE_ORDER == __BIG_ENDIAN
60 # define BE32(n) (n)
61 # define BE64(n) (n)
62 # define LE32(n) bswap_32 (n)
63 # define LE64(n) bswap_64 (n)
64 #else
65 # error "Unknown byte order"
66 #endif
67
68 #ifndef MAX
69 #define MAX(m, n) ((m) < (n) ? (n) : (m))
70 #endif
71
72 #ifndef MIN
73 #define MIN(m, n) ((m) < (n) ? (m) : (n))
74 #endif
75
76 #if !HAVE_DECL_POWEROF2
77 #define powerof2(x) (((x) & ((x) - 1)) == 0)
78 #endif
79
80 #if !HAVE_DECL_MEMPCPY
81 #define mempcpy(dest, src, n) \
82 ((void *) ((char *) memcpy (dest, src, n) + (size_t) n))
83 #endif
84
85 #if !HAVE_DECL_REALLOCARRAY
86 static inline void *
reallocarray(void * ptr,size_t nmemb,size_t size)87 reallocarray (void *ptr, size_t nmemb, size_t size)
88 {
89 if (size > 0 && nmemb > SIZE_MAX / size)
90 {
91 errno = ENOMEM;
92 return NULL;
93 }
94 return realloc (ptr, nmemb * size);
95 }
96 #endif
97
98 /* Return TRUE if the start of STR matches PREFIX, FALSE otherwise. */
99
100 static inline int
startswith(const char * str,const char * prefix)101 startswith (const char *str, const char *prefix)
102 {
103 return strncmp (str, prefix, strlen (prefix)) == 0;
104 }
105
106 /* A special gettext function we use if the strings are too short. */
107 #define sgettext(Str) \
108 ({ const char *__res = strrchr (_(Str), '|'); \
109 __res ? __res + 1 : Str; })
110
111 #define gettext_noop(Str) Str
112
113 #ifndef TEMP_FAILURE_RETRY
114 #define TEMP_FAILURE_RETRY(expression) \
115 ({ ssize_t __res; \
116 do \
117 __res = expression; \
118 while (__res == -1 && errno == EINTR); \
119 __res; })
120 #endif
121
122 #ifndef ACCESSPERMS
123 #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */
124 #endif
125
126 #ifndef ALLPERMS
127 #define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) /* 07777 */
128 #endif
129
130 #ifndef DEFFILEMODE
131 #define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* 0666 */
132 #endif
133
134 static inline ssize_t __attribute__ ((unused))
pwrite_retry(int fd,const void * buf,size_t len,off_t off)135 pwrite_retry (int fd, const void *buf, size_t len, off_t off)
136 {
137 ssize_t recvd = 0;
138
139 do
140 {
141 ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, ((char *)buf) + recvd, len - recvd,
142 off + recvd));
143 if (ret <= 0)
144 return ret < 0 ? ret : recvd;
145
146 recvd += ret;
147 }
148 while ((size_t) recvd < len);
149
150 return recvd;
151 }
152
153 static inline ssize_t __attribute__ ((unused))
write_retry(int fd,const void * buf,size_t len)154 write_retry (int fd, const void *buf, size_t len)
155 {
156 ssize_t recvd = 0;
157
158 do
159 {
160 ssize_t ret = TEMP_FAILURE_RETRY (write (fd, ((char *)buf) + recvd, len - recvd));
161 if (ret <= 0)
162 return ret < 0 ? ret : recvd;
163
164 recvd += ret;
165 }
166 while ((size_t) recvd < len);
167
168 return recvd;
169 }
170
171 static inline ssize_t __attribute__ ((unused))
pread_retry(int fd,void * buf,size_t len,off_t off)172 pread_retry (int fd, void *buf, size_t len, off_t off)
173 {
174 ssize_t recvd = 0;
175
176 do
177 {
178 ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, ((char *)buf) + recvd, len - recvd,
179 off + recvd));
180 if (ret <= 0)
181 return ret < 0 ? ret : recvd;
182
183 recvd += ret;
184 }
185 while ((size_t) recvd < len);
186
187 return recvd;
188 }
189
190 /* The demangler from libstdc++. */
191 extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
192 size_t *length, int *status);
193
194 /* A static assertion. This will cause a compile-time error if EXPR,
195 which must be a compile-time constant, is false. */
196
197 #define eu_static_assert(expr) \
198 extern int never_defined_just_used_for_checking[(expr) ? 1 : -1] \
199 __attribute__ ((unused))
200
201 #endif /* system.h */
202