diff options
author | Julio Merino <jmmv@google.com> | 2016-02-08 11:12:22 -0500 |
---|---|---|
committer | Julio Merino <jmmv@meroh.net> | 2016-02-08 20:46:37 -0500 |
commit | ddbe3bee444909420049a68f7891563f0e431669 (patch) | |
tree | 1273577a0fd0fa7ce54b426688938b785b442666 /compat | |
parent | b10d21db3185a2b25e3bd35579f57d3c7b8d882e (diff) | |
parent | 9bcb98945405db3d64cd8dca409aa18990ff1929 (diff) | |
download | sshfs-ddbe3bee444909420049a68f7891563f0e431669.tar sshfs-ddbe3bee444909420049a68f7891563f0e431669.tar.gz sshfs-ddbe3bee444909420049a68f7891563f0e431669.tar.bz2 sshfs-ddbe3bee444909420049a68f7891563f0e431669.zip |
Merge remote-tracking branch 'osxfuse/master' into merge-osxfuse
Pull in all changes from osxfuse's fork of sshfs into libfuse's sshfs.
There need not be two different copies of this codebase, particularly
because libfuse's version is already autoconf-ified and can support
multiple platforms.
The merge is mostly clean with just a few manual edits to resolve
conflicts.
Diffstat (limited to 'compat')
-rw-r--r-- | compat/darwin_compat.c | 246 | ||||
-rw-r--r-- | compat/darwin_compat.h | 49 |
2 files changed, 295 insertions, 0 deletions
diff --git a/compat/darwin_compat.c b/compat/darwin_compat.c new file mode 100644 index 0000000..9b23be2 --- /dev/null +++ b/compat/darwin_compat.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2006-2008 Amit Singh/Google Inc. + * Copyright (c) 2012 Anatol Pomozov + * Copyright (c) 2011-2013 Benjamin Fleischer + */ + +#include "darwin_compat.h" + +#include <assert.h> +#include <errno.h> +#include <sys/types.h> + +/* + * Semaphore implementation based on: + * + * Copyright (C) 2000,02 Free Software Foundation, Inc. + * This file is part of the GNU C Library. + * Written by Ga<EB>l Le Mignot <address@hidden> + * + * The GNU C Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The GNU C Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU C Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* Semaphores */ + +#define __SEM_ID_NONE ((int)0x0) +#define __SEM_ID_LOCAL ((int)0xcafef00d) + +/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_init.html */ +int +darwin_sem_init(darwin_sem_t *sem, int pshared, unsigned int value) +{ + if (pshared) { + errno = ENOSYS; + return -1; + } + + sem->id = __SEM_ID_NONE; + + if (pthread_cond_init(&sem->__data.local.count_cond, NULL)) { + goto cond_init_fail; + } + + if (pthread_mutex_init(&sem->__data.local.count_lock, NULL)) { + goto mutex_init_fail; + } + + sem->__data.local.count = value; + sem->id = __SEM_ID_LOCAL; + + return 0; + +mutex_init_fail: + + pthread_cond_destroy(&sem->__data.local.count_cond); + +cond_init_fail: + + return -1; +} + +/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_destroy.html */ +int +darwin_sem_destroy(darwin_sem_t *sem) +{ + int res = 0; + + pthread_mutex_lock(&sem->__data.local.count_lock); + + sem->id = __SEM_ID_NONE; + pthread_cond_broadcast(&sem->__data.local.count_cond); + + if (pthread_cond_destroy(&sem->__data.local.count_cond)) { + res = -1; + } + + pthread_mutex_unlock(&sem->__data.local.count_lock); + + if (pthread_mutex_destroy(&sem->__data.local.count_lock)) { + res = -1; + } + + return res; +} + +int +darwin_sem_getvalue(darwin_sem_t *sem, unsigned int *sval) +{ + int res = 0; + + pthread_mutex_lock(&sem->__data.local.count_lock); + + if (sem->id != __SEM_ID_LOCAL) { + res = -1; + errno = EINVAL; + } else { + *sval = sem->__data.local.count; + } + + pthread_mutex_unlock(&sem->__data.local.count_lock); + + return res; +} + +/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_post.html */ +int +darwin_sem_post(darwin_sem_t *sem) +{ + int res = 0; + + pthread_mutex_lock(&sem->__data.local.count_lock); + + if (sem->id != __SEM_ID_LOCAL) { + res = -1; + errno = EINVAL; + } else if (sem->__data.local.count < DARWIN_SEM_VALUE_MAX) { + sem->__data.local.count++; + if (sem->__data.local.count == 1) { + pthread_cond_signal(&sem->__data.local.count_cond); + } + } else { + errno = ERANGE; + res = -1; + } + + pthread_mutex_unlock(&sem->__data.local.count_lock); + + return res; +} + +/* http://www.opengroup.org/onlinepubs/009695399/functions/sem_timedwait.html */ +int +darwin_sem_timedwait(darwin_sem_t *sem, const struct timespec *abs_timeout) +{ + int res = 0; + + if (abs_timeout && + (abs_timeout->tv_nsec < 0 || abs_timeout->tv_nsec >= 1000000000)) { + errno = EINVAL; + return -1; + } + + pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock, + &sem->__data.local.count_lock); + + pthread_mutex_lock(&sem->__data.local.count_lock); + + if (sem->id != __SEM_ID_LOCAL) { + errno = EINVAL; + res = -1; + } else { + if (!sem->__data.local.count) { + res = pthread_cond_timedwait(&sem->__data.local.count_cond, + &sem->__data.local.count_lock, + abs_timeout); + } + if (res) { + assert(res == ETIMEDOUT); + res = -1; + errno = ETIMEDOUT; + } else if (sem->id != __SEM_ID_LOCAL) { + res = -1; + errno = EINVAL; + } else { + sem->__data.local.count--; + } + } + + pthread_cleanup_pop(1); + + return res; +} + +/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_trywait.html */ +int +darwin_sem_trywait(darwin_sem_t *sem) +{ + int res = 0; + + pthread_mutex_lock(&sem->__data.local.count_lock); + + if (sem->id != __SEM_ID_LOCAL) { + res = -1; + errno = EINVAL; + } else if (sem->__data.local.count) { + sem->__data.local.count--; + } else { + res = -1; + errno = EAGAIN; + } + + pthread_mutex_unlock (&sem->__data.local.count_lock); + + return res; +} + +/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_wait.html */ +int +darwin_sem_wait(darwin_sem_t *sem) +{ + int res = 0; + + pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock, + &sem->__data.local.count_lock); + + pthread_mutex_lock(&sem->__data.local.count_lock); + + if (sem->id != __SEM_ID_LOCAL) { + errno = EINVAL; + res = -1; + } else { + if (!sem->__data.local.count) { + pthread_cond_wait(&sem->__data.local.count_cond, + &sem->__data.local.count_lock); + if (!sem->__data.local.count) { + /* spurious wakeup, assume it is an interruption */ + res = -1; + errno = EINTR; + goto out; + } + } + if (sem->id != __SEM_ID_LOCAL) { + res = -1; + errno = EINVAL; + } else { + sem->__data.local.count--; + } + } + +out: + pthread_cleanup_pop(1); + + return res; +} diff --git a/compat/darwin_compat.h b/compat/darwin_compat.h new file mode 100644 index 0000000..0a16471 --- /dev/null +++ b/compat/darwin_compat.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2006-2008 Amit Singh/Google Inc. + * Copyright (c) 2011-2013 Benjamin Fleischer + */ + +#ifndef _DARWIN_COMPAT_ +#define _DARWIN_COMPAT_ + +#include <pthread.h> + +/* Semaphores */ + +typedef struct darwin_sem { + int id; + union { + struct + { + unsigned int count; + pthread_mutex_t count_lock; + pthread_cond_t count_cond; + } local; + } __data; +} darwin_sem_t; + +#define DARWIN_SEM_VALUE_MAX ((int32_t)32767) + +int darwin_sem_init(darwin_sem_t *sem, int pshared, unsigned int value); +int darwin_sem_destroy(darwin_sem_t *sem); +int darwin_sem_getvalue(darwin_sem_t *sem, unsigned int *value); +int darwin_sem_post(darwin_sem_t *sem); +int darwin_sem_timedwait(darwin_sem_t *sem, const struct timespec *abs_timeout); +int darwin_sem_trywait(darwin_sem_t *sem); +int darwin_sem_wait(darwin_sem_t *sem); + +/* Caller must not include <semaphore.h> */ + +typedef darwin_sem_t sem_t; + +#define sem_init(s, p, v) darwin_sem_init(s, p, v) +#define sem_destroy(s) darwin_sem_destroy(s) +#define sem_getvalue(s, v) darwin_sem_getvalue(s, v) +#define sem_post(s) darwin_sem_post(s) +#define sem_timedwait(s, t) darwin_sem_timedwait(s, t) +#define sem_trywait(s) darwin_sem_trywait(s) +#define sem_wait(s) darwin_sem_wait(s) + +#define SEM_VALUE_MAX DARWIN_SEM_VALUE_MAX + +#endif /* _DARWIN_COMPAT_ */ |