• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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