]> git.proxmox.com Git - ceph.git/blob - ceph/src/include/compat.h
c65a6ae4465aed486ee8c1d9043b058d9669324d
[ceph.git] / ceph / src / include / compat.h
1 /*
2 * Ceph - scalable distributed file system
3 *
4 * Copyright (C) 2011 Stanislav Sedov <stas@FreeBSD.org>
5 *
6 * This is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1, as published by the Free Software
9 * Foundation. See file COPYING.
10 */
11
12 #ifndef CEPH_COMPAT_H
13 #define CEPH_COMPAT_H
14
15 #include "acconfig.h"
16 #include <sys/types.h>
17 #include <errno.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20
21 #if defined(__linux__)
22 #define PROCPREFIX
23 #endif
24
25 #include <fcntl.h>
26 #ifndef F_OFD_SETLK
27 #define F_OFD_SETLK F_SETLK
28 #endif
29
30 #include <sys/stat.h>
31
32 #ifdef _WIN32
33 #include "include/win32/fs_compat.h"
34 #endif
35
36 #ifndef ACCESSPERMS
37 #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
38 #endif
39
40 #ifndef ALLPERMS
41 #define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
42 #endif
43
44 #if defined(__FreeBSD__)
45
46 // FreeBSD supports Linux procfs with its compatibility module
47 // And all compatibility stuff is standard mounted on this
48 #define PROCPREFIX "/compat/linux"
49
50 #ifndef MSG_MORE
51 #define MSG_MORE 0
52 #endif
53
54 #ifndef O_DSYNC
55 #define O_DSYNC O_SYNC
56 #endif
57
58 /* And include the extra required include file */
59 #include <pthread_np.h>
60
61 #include <sys/param.h>
62 #include <sys/cpuset.h>
63 #define cpu_set_t cpuset_t
64 int sched_setaffinity(pid_t pid, size_t cpusetsize,
65 cpu_set_t *mask);
66
67 #endif /* __FreeBSD__ */
68
69 #if defined(__APPLE__)
70 struct cpu_set_t;
71 #endif
72
73 #if defined(__APPLE__) || defined(__FreeBSD__)
74 /* Make sure that ENODATA is defined in the correct way */
75 #ifdef ENODATA
76 #if (ENODATA == 9919)
77 // #warning ENODATA already defined to be 9919, redefining to fix
78 // Silencing this warning because it fires at all files where compat.h
79 // is included after boost files.
80 //
81 // This value stems from the definition in the boost library
82 // And when this case occurs it is due to the fact that boost files
83 // are included before this file. Redefinition might not help in this
84 // case since already parsed code has evaluated to the wrong value.
85 // This would warrrant for d definition that would actually be evaluated
86 // at the location of usage and report a possible conflict.
87 // This is left up to a future improvement
88 #elif (ENODATA != 87)
89 // #warning ENODATA already defined to a value different from 87 (ENOATRR), refining to fix
90 #endif
91 #undef ENODATA
92 #endif
93 #define ENODATA ENOATTR
94
95 // Fix clock accuracy
96 #if !defined(CLOCK_MONOTONIC_COARSE)
97 #if defined(CLOCK_MONOTONIC_FAST)
98 #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST
99 #else
100 #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
101 #endif
102 #endif
103 #if !defined(CLOCK_REALTIME_COARSE)
104 #if defined(CLOCK_REALTIME_FAST)
105 #define CLOCK_REALTIME_COARSE CLOCK_REALTIME_FAST
106 #else
107 #define CLOCK_REALTIME_COARSE CLOCK_REALTIME
108 #endif
109 #endif
110
111 /* get PATH_MAX */
112 #include <limits.h>
113
114 #ifndef EUCLEAN
115 #define EUCLEAN 117
116 #endif
117 #ifndef EREMOTEIO
118 #define EREMOTEIO 121
119 #endif
120 #ifndef EKEYREJECTED
121 #define EKEYREJECTED 129
122 #endif
123 #ifndef XATTR_CREATE
124 #define XATTR_CREATE 1
125 #endif
126
127 #endif /* __APPLE__ */
128
129 #ifndef HOST_NAME_MAX
130 #ifdef MAXHOSTNAMELEN
131 #define HOST_NAME_MAX MAXHOSTNAMELEN
132 #else
133 #define HOST_NAME_MAX 255
134 #endif
135 #endif /* HOST_NAME_MAX */
136
137 /* O_LARGEFILE is not defined/required on OSX/FreeBSD */
138 #ifndef O_LARGEFILE
139 #define O_LARGEFILE 0
140 #endif
141
142 /* Could be relevant for other platforms */
143 #ifndef ERESTART
144 #define ERESTART EINTR
145 #endif
146
147 #ifndef TEMP_FAILURE_RETRY
148 #define TEMP_FAILURE_RETRY(expression) ({ \
149 __typeof(expression) __result; \
150 do { \
151 __result = (expression); \
152 } while (__result == -1 && errno == EINTR); \
153 __result; })
154 #endif
155
156 #ifdef __cplusplus
157 # define VOID_TEMP_FAILURE_RETRY(expression) \
158 static_cast<void>(TEMP_FAILURE_RETRY(expression))
159 #else
160 # define VOID_TEMP_FAILURE_RETRY(expression) \
161 do { (void)TEMP_FAILURE_RETRY(expression); } while (0)
162 #endif
163
164 #if defined(__FreeBSD__) || defined(__APPLE__)
165 #define lseek64(fd, offset, whence) lseek(fd, offset, whence)
166 #endif
167
168 #if defined(__sun) || defined(_AIX)
169 #define LOG_AUTHPRIV (10<<3)
170 #define LOG_FTP (11<<3)
171 #define __STRING(x) "x"
172 #endif
173
174 #if defined(__sun) || defined(_AIX) || defined(_WIN32)
175 #define IFTODT(mode) (((mode) & 0170000) >> 12)
176 #endif
177
178 #if defined(_AIX)
179 #define MSG_DONTWAIT MSG_NONBLOCK
180 #endif
181
182 #if defined(HAVE_PTHREAD_SETNAME_NP)
183 #if defined(__APPLE__)
184 #define ceph_pthread_setname(thread, name) ({ \
185 int __result = 0; \
186 if (thread == pthread_self()) \
187 __result = pthread_setname_np(name); \
188 __result; })
189 #else
190 #define ceph_pthread_setname pthread_setname_np
191 #endif
192 #elif defined(HAVE_PTHREAD_SET_NAME_NP)
193 /* Fix a small name diff and return 0 */
194 #define ceph_pthread_setname(thread, name) ({ \
195 pthread_set_name_np(thread, name); \
196 0; })
197 #else
198 /* compiler warning free success noop */
199 #define ceph_pthread_setname(thread, name) ({ \
200 int __i = 0; \
201 __i; })
202 #endif
203
204 #if defined(HAVE_PTHREAD_GETNAME_NP)
205 #define ceph_pthread_getname pthread_getname_np
206 #elif defined(HAVE_PTHREAD_GET_NAME_NP)
207 #define ceph_pthread_getname(thread, name, len) ({ \
208 pthread_get_name_np(thread, name, len); \
209 0; })
210 #else
211 /* compiler warning free success noop */
212 #define ceph_pthread_getname(thread, name, len) ({ \
213 if (name != NULL) \
214 *name = '\0'; \
215 0; })
216 #endif
217
218 int ceph_posix_fallocate(int fd, off_t offset, off_t len);
219
220 #ifdef __cplusplus
221 extern "C" {
222 #endif
223
224 int pipe_cloexec(int pipefd[2], int flags);
225 char *ceph_strerror_r(int errnum, char *buf, size_t buflen);
226 unsigned get_page_size();
227 // On success, returns the number of bytes written to the buffer. On
228 // failure, returns -1.
229 ssize_t get_self_exe_path(char* path, int buff_length);
230
231 int ceph_memzero_s(void *dest, size_t destsz, size_t count);
232
233 #ifdef __cplusplus
234 }
235 #endif
236
237 #if defined(_WIN32)
238
239 #include "include/win32/winsock_compat.h"
240
241 #include <windows.h>
242 #include <time.h>
243
244 #include "include/win32/win32_errno.h"
245
246 // There are a few name collisions between Windows headers and Ceph.
247 // Updating Ceph definitions would be the prefferable fix in order to avoid
248 // confussion, unless it requires too many changes, in which case we're going
249 // to redefine Windows values by adding the "WIN32_" prefix.
250 #define WIN32_DELETE 0x00010000L
251 #undef DELETE
252
253 #define WIN32_ERROR 0
254 #undef ERROR
255
256 #ifndef uint
257 typedef unsigned int uint;
258 #endif
259
260 typedef _sigset_t sigset_t;
261
262 typedef unsigned int uid_t;
263 typedef unsigned int gid_t;
264
265 typedef unsigned int blksize_t;
266 typedef unsigned __int64 blkcnt_t;
267 typedef unsigned short nlink_t;
268
269 typedef long long loff_t;
270
271 #define CPU_SETSIZE (sizeof(size_t)*8)
272
273 typedef union
274 {
275 char cpuset[CPU_SETSIZE/8];
276 size_t _align;
277 } cpu_set_t;
278
279 struct iovec {
280 void *iov_base;
281 size_t iov_len;
282 };
283
284 #define SHUT_RD SD_RECEIVE
285 #define SHUT_WR SD_SEND
286 #define SHUT_RDWR SD_BOTH
287
288 #ifndef SIGINT
289 #define SIGINT 2
290 #endif
291
292 #ifndef SIGKILL
293 #define SIGKILL 9
294 #endif
295
296 #define IOV_MAX 1024
297
298 #ifdef __cplusplus
299 extern "C" {
300 #endif
301
302 ssize_t readv(int fd, const struct iovec *iov, int iov_cnt);
303 ssize_t writev(int fd, const struct iovec *iov, int iov_cnt);
304
305 int fsync(int fd);
306 ssize_t pread(int fd, void *buf, size_t count, off_t offset);
307 ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
308
309 long int lrand48(void);
310 int random();
311
312 int pipe(int pipefd[2]);
313
314 int posix_memalign(void **memptr, size_t alignment, size_t size);
315
316 char *strptime(const char *s, const char *format, struct tm *tm);
317
318 int chown(const char *path, uid_t owner, gid_t group);
319 int fchown(int fd, uid_t owner, gid_t group);
320 int lchown(const char *path, uid_t owner, gid_t group);
321 int setenv(const char *name, const char *value, int overwrite);
322
323 int geteuid();
324 int getegid();
325 int getuid();
326 int getgid();
327
328 #define unsetenv(name) _putenv_s(name, "")
329
330 int win_socketpair(int socks[2]);
331
332 #ifdef __MINGW32__
333 extern _CRTIMP errno_t __cdecl _putenv_s(const char *_Name,const char *_Value);
334
335 #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
336 #define htobe16(x) __builtin_bswap16(x)
337 #define htole16(x) (x)
338 #define be16toh(x) __builtin_bswap16(x)
339 #define le16toh(x) (x)
340
341 #define htobe32(x) __builtin_bswap32(x)
342 #define htole32(x) (x)
343 #define be32toh(x) __builtin_bswap32(x)
344 #define le32toh(x) (x)
345
346 #define htobe64(x) __builtin_bswap64(x)
347 #define htole64(x) (x)
348 #define be64toh(x) __builtin_bswap64(x)
349 #define le64toh(x) (x)
350 #endif // defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
351
352 #endif // __MINGW32__
353
354 #ifdef __cplusplus
355 }
356 #endif
357
358 #define compat_closesocket closesocket
359 // Use "aligned_free" when freeing memory allocated using posix_memalign or
360 // _aligned_malloc. Using "free" will crash.
361 static inline void aligned_free(void* ptr) {
362 _aligned_free(ptr);
363 }
364
365 // O_CLOEXEC is not defined on Windows. Since handles aren't inherited
366 // with subprocesses unless explicitly requested, we'll define this
367 // flag as a no-op.
368 #define O_CLOEXEC 0
369 #define SOCKOPT_VAL_TYPE char*
370
371 #define DEV_NULL "nul"
372
373 #else /* WIN32 */
374
375 #define SOCKOPT_VAL_TYPE void*
376
377 static inline void aligned_free(void* ptr) {
378 free(ptr);
379 }
380 static inline int compat_closesocket(int fildes) {
381 return close(fildes);
382 }
383
384 #define DEV_NULL "/dev/null"
385
386 #endif /* WIN32 */
387
388 /* Supplies code to be run at startup time before invoking main().
389 * Use as:
390 *
391 * CEPH_CONSTRUCTOR(my_constructor) {
392 * ...some code...
393 * }
394 */
395 #ifdef _MSC_VER
396 #pragma section(".CRT$XCU",read)
397 #define CEPH_CONSTRUCTOR(f) \
398 static void __cdecl f(void); \
399 __declspec(allocate(".CRT$XCU")) static void (__cdecl*f##_)(void) = f; \
400 static void __cdecl f(void)
401 #else
402 #define CEPH_CONSTRUCTOR(f) \
403 static void f(void) __attribute__((constructor)); \
404 static void f(void)
405 #endif
406
407 /* This should only be used with the socket API. */
408 static inline int ceph_sock_errno() {
409 #ifdef _WIN32
410 return wsae_to_errno(WSAGetLastError());
411 #else
412 return errno;
413 #endif
414 }
415
416 // Needed on Windows when handling binary files. Without it, line
417 // endings will be replaced and certain characters can be treated as
418 // EOF.
419 #ifndef O_BINARY
420 #define O_BINARY 0
421 #endif
422
423 #endif /* !CEPH_COMPAT_H */