Line data Source code
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 : #ifdef HAVE_CONFIG_H
33 : # include <config.h>
34 : #endif
35 :
36 : #include <argp.h>
37 : #include <errno.h>
38 : #include <stddef.h>
39 : #include <stdint.h>
40 : #include <sys/param.h>
41 : #include <endian.h>
42 : #include <byteswap.h>
43 : #include <unistd.h>
44 :
45 : #if __BYTE_ORDER == __LITTLE_ENDIAN
46 : # define LE32(n) (n)
47 : # define LE64(n) (n)
48 : # define BE32(n) bswap_32 (n)
49 : # define BE64(n) bswap_64 (n)
50 : #elif __BYTE_ORDER == __BIG_ENDIAN
51 : # define BE32(n) (n)
52 : # define BE64(n) (n)
53 : # define LE32(n) bswap_32 (n)
54 : # define LE64(n) bswap_64 (n)
55 : #else
56 : # error "Unknown byte order"
57 : #endif
58 :
59 : #ifndef MAX
60 : #define MAX(m, n) ((m) < (n) ? (n) : (m))
61 : #endif
62 :
63 : #ifndef MIN
64 : #define MIN(m, n) ((m) < (n) ? (m) : (n))
65 : #endif
66 :
67 : #if !HAVE_DECL_POWEROF2
68 : #define powerof2(x) (((x) & ((x) - 1)) == 0)
69 : #endif
70 :
71 : /* A special gettext function we use if the strings are too short. */
72 : #define sgettext(Str) \
73 : ({ const char *__res = strrchr (gettext (Str), '|'); \
74 : __res ? __res + 1 : Str; })
75 :
76 : #define gettext_noop(Str) Str
77 :
78 : #ifndef TEMP_FAILURE_RETRY
79 : #define TEMP_FAILURE_RETRY(expression) \
80 : ({ ssize_t __res; \
81 : do \
82 : __res = expression; \
83 : while (__res == -1 && errno == EINTR); \
84 : __res; });
85 : #endif
86 :
87 : static inline ssize_t __attribute__ ((unused))
88 4906 : pwrite_retry (int fd, const void *buf, size_t len, off_t off)
89 : {
90 4906 : ssize_t recvd = 0;
91 :
92 : do
93 : {
94 4906 : ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, buf + recvd, len - recvd,
95 : off + recvd));
96 4906 : if (ret <= 0)
97 71 : return ret < 0 ? ret : recvd;
98 :
99 4835 : recvd += ret;
100 : }
101 4835 : while ((size_t) recvd < len);
102 :
103 : return recvd;
104 : }
105 :
106 : static inline ssize_t __attribute__ ((unused))
107 14 : write_retry (int fd, const void *buf, size_t len)
108 : {
109 14 : ssize_t recvd = 0;
110 :
111 : do
112 : {
113 14 : ssize_t ret = TEMP_FAILURE_RETRY (write (fd, buf + recvd, len - recvd));
114 14 : if (ret <= 0)
115 0 : return ret < 0 ? ret : recvd;
116 :
117 14 : recvd += ret;
118 : }
119 14 : while ((size_t) recvd < len);
120 :
121 : return recvd;
122 : }
123 :
124 : static inline ssize_t __attribute__ ((unused))
125 25039 : pread_retry (int fd, void *buf, size_t len, off_t off)
126 : {
127 25039 : ssize_t recvd = 0;
128 :
129 : do
130 : {
131 30050 : ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, buf + recvd, len - recvd,
132 : off + recvd));
133 30050 : if (ret <= 0)
134 5011 : return ret < 0 ? ret : recvd;
135 :
136 25039 : recvd += ret;
137 : }
138 25039 : while ((size_t) recvd < len);
139 :
140 : return recvd;
141 : }
142 :
143 :
144 : /* We need define two variables, argp_program_version_hook and
145 : argp_program_bug_address, in all programs. argp.h declares these
146 : variables as non-const (which is correct in general). But we can
147 : do better, it is not going to change. So we want to move them into
148 : the .rodata section. Define macros to do the trick. */
149 : #define ARGP_PROGRAM_VERSION_HOOK_DEF \
150 : void (*const apvh) (FILE *, struct argp_state *) \
151 : __asm ("argp_program_version_hook")
152 : #define ARGP_PROGRAM_BUG_ADDRESS_DEF \
153 : const char *const apba__ __asm ("argp_program_bug_address")
154 :
155 : /* Defined in version.c. Common ARGP_PROGRAM_VERSION_HOOK_DEF. */
156 : void print_version (FILE *stream, struct argp_state *state);
157 :
158 : /* The demangler from libstdc++. */
159 : extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
160 : size_t *length, int *status);
161 :
162 : /* A static assertion. This will cause a compile-time error if EXPR,
163 : which must be a compile-time constant, is false. */
164 :
165 : #define eu_static_assert(expr) \
166 : extern int never_defined_just_used_for_checking[(expr) ? 1 : -1] \
167 : __attribute__ ((unused))
168 :
169 : #endif /* system.h */
|