CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
platform_osx.h
Go to the documentation of this file.
1 
7 #ifndef CVMFS_UTIL_PLATFORM_OSX_H_
8 #define CVMFS_UTIL_PLATFORM_OSX_H_
9 
10 #include <alloca.h>
11 #include <dirent.h>
12 #include <fcntl.h>
13 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
14  __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
15 #include <os/lock.h> // NOLINT
16 #else
17 #include <libkern/OSAtomic.h>
18 #endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&
19  // __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
20 #include <mach-o/dyld.h>
21 #include <mach/mach.h> // NOLINT
22 #include <mach/mach_time.h>
23 #include <signal.h>
24 #include <sys/mount.h>
25 #include <sys/param.h>
26 #include <sys/stat.h>
27 #include <sys/sysctl.h>
28 #include <sys/types.h>
29 #include <sys/ucred.h>
30 #include <sys/xattr.h>
31 
32 #include <cassert>
33 #include <cstdio>
34 #include <cstdlib>
35 #include <cstring>
36 
37 #include <string>
38 #include <vector>
39 
40 #include "util/smalloc.h"
41 
42 #ifdef CVMFS_NAMESPACE_GUARD
43 namespace CVMFS_NAMESPACE_GUARD {
44 #endif
45 
52 #ifndef MSG_NOSIGNAL
53 #define MSG_NOSIGNAL SO_NOSIGPIPE
54 #endif
55 
59 #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
60 
61 #define platform_sighandler_t sig_t
62 
63 inline std::vector<std::string> platform_mountlist() {
64  std::vector<std::string> result;
65  struct statfs *mntbufp;
66  int num_elems = getmntinfo(&mntbufp, MNT_NOWAIT); // modifies static memory
67  for (int i = 0; i < num_elems; ++i) {
68  result.push_back(mntbufp[i].f_mntonname);
69  }
70  return result;
71 }
72 
73 inline bool platform_umount(const char *mountpoint, const bool lazy) {
74  const int flags = lazy ? MNT_FORCE : 0;
75  int retval = unmount(mountpoint, flags);
76  return retval == 0;
77 }
78 
79 
80 inline int platform_umount_lazy(const char *mountpoint) {
81  int retval = unmount(mountpoint, MNT_FORCE);
82  return retval == 0;
83 }
84 
88 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
89  __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
90 typedef os_unfair_lock platform_spinlock;
91 
92 inline int platform_spinlock_init(platform_spinlock *lock, int /*pshared*/) {
93  *lock = OS_UNFAIR_LOCK_INIT;
94  return 0;
95 }
96 
97 inline int platform_spinlock_destroy(platform_spinlock * /*lock*/) { return 0; }
98 
100  return os_unfair_lock_trylock(lock) ? 0 : -1;
101 }
102 
103 inline void platform_spinlock_unlock(platform_spinlock *lock) {
104  os_unfair_lock_unlock(lock);
105 }
106 
107 #else
108 typedef OSSpinLock platform_spinlock;
109 
110 inline int platform_spinlock_init(platform_spinlock *lock, int /*pshared*/) {
111  *lock = 0;
112  return 0;
113 }
114 
115 inline int platform_spinlock_destroy(platform_spinlock * /*lock*/) { return 0; }
116 
118  return OSSpinLockTry(lock) ? 0 : -1;
119 }
120 
122  OSSpinLockUnlock(lock);
123 }
124 
125 #endif
126 
130 inline thread_port_t platform_gettid() { return mach_thread_self(); }
131 
132 inline int platform_sigwait(const int signum) {
133  sigset_t sigset;
134  int retval = sigemptyset(&sigset);
135  assert(retval == 0);
136  retval = sigaddset(&sigset, signum);
137  assert(retval == 0);
138  int result;
139  retval = sigwait(&sigset, &result);
140  assert(retval == 0);
141  return result;
142 }
143 
147 inline bool platform_allow_ptrace(const pid_t pid) {
148  // No-op on Mac OS X
149  return true;
150 }
151 
155 typedef struct dirent platform_dirent64;
156 
157 inline platform_dirent64 *platform_readdir(DIR *dirp) { return readdir(dirp); }
158 
159 typedef struct stat platform_stat64;
160 
161 inline int platform_stat(const char *path, platform_stat64 *buf) {
162  return stat(path, buf);
163 }
164 
165 inline int platform_lstat(const char *path, platform_stat64 *buf) {
166  return lstat(path, buf);
167 }
168 
169 inline int platform_fstat(int filedes, platform_stat64 *buf) {
170  return fstat(filedes, buf);
171 }
172 
173 inline bool platform_getxattr(const std::string &path, const std::string &name,
174  std::string *value) {
175  int size = 0;
176  void *buffer = NULL;
177  int retval;
178  retval = getxattr(path.c_str(), name.c_str(), buffer, size, 0, 0);
179  if (retval >= 1) {
180  size = retval;
181  buffer = smalloc(size);
182  retval = getxattr(path.c_str(), name.c_str(), buffer, size, 0, 0);
183  }
184  if ((retval < 0) || (retval > size)) {
185  free(buffer);
186  return false;
187  }
188  if (retval > 0) {
189  value->assign(static_cast<const char *>(buffer), size);
190  free(buffer);
191  } else {
192  value->assign("");
193  }
194  return true;
195 }
196 
197 inline bool platform_setxattr(const std::string &path, const std::string &name,
198  const std::string &value) {
199  int retval =
200  setxattr(path.c_str(), name.c_str(), value.c_str(), value.size(), 0, 0);
201  return retval == 0;
202 }
203 
204 inline bool platform_lsetxattr(const std::string &path, const std::string &name,
205  const std::string &value) {
206  int retval =
207  setxattr(
208  path.c_str(),
209  name.c_str(),
210  value.c_str(),
211  value.size(),
212  0,
213  XATTR_NOFOLLOW);
214  return retval == 0;
215 }
216 
217 inline ssize_t platform_lgetxattr(const char *path, const char *name,
218  void *value, size_t size) {
219  return getxattr(path, name, value, size, 0 /* position */, XATTR_NOFOLLOW);
220 }
221 
222 inline ssize_t platform_llistxattr(const char *path, char *list, size_t size) {
223  return listxattr(path, list, size, XATTR_NOFOLLOW);
224 }
225 
226 inline void platform_disable_kcache(int filedes) {
227  fcntl(filedes, F_RDAHEAD, 0);
228  fcntl(filedes, F_NOCACHE, 1);
229 }
230 
231 inline void platform_invalidate_kcache(const int fd, const off_t offset,
232  const off_t length) {
233  // NOOP
234  // TODO(rmeusel): implement
235 }
236 
237 inline ssize_t platform_readahead(int filedes) {
238  // TODO(jblomer): is there a readahead equivalent?
239  return 0;
240 }
241 
242 inline bool read_line(FILE *f, std::string *line) {
243  char *buffer_line = NULL;
244  size_t buffer_size = 0;
245  const int res = getline(&buffer_line, &buffer_size, f);
246  if (res < 0) {
247  free(buffer_line);
248  return false;
249  }
250 
251  line->clear();
252  line->assign(buffer_line);
253  free(buffer_line);
254  return true;
255 }
256 
257 inline uint64_t platform_monotonic_time() {
258  uint64_t val_abs = mach_absolute_time();
259  // Doing the conversion every time is slow but thread-safe
260  mach_timebase_info_data_t info;
261  mach_timebase_info(&info);
262  uint64_t val_ns = val_abs * (info.numer / info.denom);
263  return val_ns * 1e-9;
264 }
265 
266 inline uint64_t platform_monotonic_time_ns() {
267  uint64_t val_abs = mach_absolute_time();
268  // Doing the conversion every time is slow but thread-safe
269  mach_timebase_info_data_t info;
270  mach_timebase_info(&info);
271  uint64_t val_ns = val_abs * (info.numer / info.denom);
272  return val_ns;
273 }
274 
275 inline uint64_t platform_realtime_ns() {
276  struct timeval tv;
277  int ret = gettimeofday(&tv, NULL);
278  assert(ret == 0);
279  uint64_t time = tv.tv_sec * 1e6 + tv.tv_usec * 1e3;
280  return time;
281 }
282 
286 #define strdupa(s) \
287  strcpy(/* NOLINT(runtime/printf) */ \
288  reinterpret_cast<char *>(alloca(strlen((s)) + 1)), (s))
289 
290 inline std::string platform_libname(const std::string &base_name) {
291  return "lib" + base_name + ".dylib";
292 }
293 
294 inline std::string platform_getexepath() {
295  return std::string(_dyld_get_image_name(0));
296 }
297 
301 inline uint64_t platform_memsize() {
302  int mib[] = {CTL_HW, HW_MEMSIZE};
303  int64_t ramsize;
304  int rc;
305  size_t len;
306 
307  len = sizeof(ramsize);
308  rc = sysctl(mib, 2, &ramsize, &len, NULL, 0);
309  assert(rc == 0);
310  return ramsize;
311 }
312 
313 #ifdef CVMFS_NAMESPACE_GUARD
314 } // namespace CVMFS_NAMESPACE_GUARD
315 #endif
316 
317 inline int prctl(int, uint64_t, uint64_t, uint64_t, uint64_t) { return 0; }
318 #define PR_SET_DUMPABLE 0
319 
320 #endif // CVMFS_UTIL_PLATFORM_OSX_H_
struct stat64 platform_stat64
pthread_t platform_gettid()
int platform_spinlock_init(platform_spinlock *lock, int pshared)
assert((mem||(size==0))&&"Out Of Memory")
uint64_t platform_monotonic_time_ns()
bool platform_umount_lazy(const char *mountpoint)
bool platform_umount(const char *mountpoint, const bool lazy)
int platform_stat(const char *path, platform_stat64 *buf)
std::string platform_getexepath()
ssize_t platform_llistxattr(const char *path, char *list, size_t size)
bool platform_allow_ptrace(const pid_t pid)
int prctl(int, uint64_t, uint64_t, uint64_t, uint64_t)
Definition: platform_osx.h:317
uint64_t platform_memsize()
pthread_spinlock_t platform_spinlock
int platform_spinlock_trylock(platform_spinlock *lock)
int platform_invalidate_kcache(const int fd, const off_t offset, const off_t length)
bool platform_getxattr(const std::string &path, const std::string &name, std::string *value)
bool platform_setxattr(const std::string &path, const std::string &name, const std::string &value)
ssize_t platform_readahead(int filedes)
uint64_t platform_realtime_ns()
int platform_sigwait(const int signum)
ssize_t platform_lgetxattr(const char *path, const char *name, void *value, size_t size)
std::vector< std::string > platform_mountlist()
int platform_lstat(const char *path, platform_stat64 *buf)
uint64_t platform_monotonic_time()
std::string platform_libname(const std::string &base_name)
void platform_disable_kcache(int filedes)
void platform_spinlock_unlock(platform_spinlock *lock)
platform_dirent64 * platform_readdir(DIR *dirp)
int platform_spinlock_destroy(platform_spinlock *lock)
int platform_fstat(int filedes, platform_stat64 *buf)
static void size_t size
Definition: smalloc.h:54
bool platform_lsetxattr(const std::string &path, const std::string &name, const std::string &value)
bool read_line(FILE *f, std::string *line)
Definition: platform_osx.h:242
struct dirent64 platform_dirent64