diff -ENwbur orig/Makefile.am new/Makefile.am
--- orig/Makefile.am	2014-01-08 12:35:19.000000000 +0100
+++ new/Makefile.am	2016-02-10 09:20:21.000000000 +0100
@@ -6,6 +6,9 @@
 if FUSE_OPT_COMPAT
 sshfs_SOURCES += compat/fuse_opt.c compat/fuse_opt.h
 endif
+if DARWIN_COMPAT
+sshfs_SOURCES += compat/darwin_compat.c compat/darwin_compat.h
+endif
 
 sshfs_LDADD = $(SSHFS_LIBS)
 sshfs_CFLAGS = $(SSHFS_CFLAGS)
diff -ENwbur orig/compat/darwin_compat.c new/compat/darwin_compat.c
--- orig/compat/darwin_compat.c	1970-01-01 01:00:00.000000000 +0100
+++ new/compat/darwin_compat.c	2016-02-10 09:19:15.000000000 +0100
@@ -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 -ENwbur orig/compat/darwin_compat.h new/compat/darwin_compat.h
--- orig/compat/darwin_compat.h	1970-01-01 01:00:00.000000000 +0100
+++ new/compat/darwin_compat.h	2016-02-10 09:19:28.000000000 +0100
@@ -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_ */
diff -ENwbur orig/configure.ac new/configure.ac
--- orig/configure.ac	2014-01-14 15:07:46.000000000 +0100
+++ new/configure.ac	2016-02-10 09:18:07.000000000 +0100
@@ -1,4 +1,5 @@
 AC_INIT(sshfs-fuse, 2.5)
+AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE
 AM_CONFIG_HEADER(config.h)
 
@@ -11,6 +12,14 @@
 AC_SUBST(sshnodelay_libs)
 LIBS=
 
+case $target_os in
+      *linux*)	arch=linux;;
+      *netbsd*) arch=netbsd;;
+      *bsd*)	arch=bsd;;
+      *darwin*)	arch=darwin;;
+      *)		arch=unknown;;
+esac
+
 AC_ARG_ENABLE(sshnodelay,
 	[  --disable-sshnodelay    Don't compile NODELAY workaround for ssh])
 
@@ -43,10 +52,11 @@
 LIBS="$LIBS $SSHFS_LIBS"
 AC_CHECK_FUNC([fuse_opt_parse], [have_fuse_opt_parse=yes])
 LIBS="$oldlibs"
-if test "$have_fuse_opt_parse" = no; then
+if test "$have_fuse_opt_parse" = no -o "$arch" = darwin; then
 	CFLAGS="$CFLAGS -Icompat"
 fi
 AM_CONDITIONAL(FUSE_OPT_COMPAT, test "$have_fuse_opt_parse" = no)
+AM_CONDITIONAL(DARWIN_COMPAT, test "$arch" = darwin)
 
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
diff -ENwbur orig/sshfs.c new/sshfs.c
--- orig/sshfs.c	2014-01-08 16:34:52.000000000 +0100
+++ new/sshfs.c	2016-02-10 09:55:50.000000000 +0100
@@ -20,7 +20,9 @@
 #include <string.h>
 #include <stdint.h>
 #include <errno.h>
+#ifndef __APPLE__
 #include <semaphore.h>
+#endif
 #include <pthread.h>
 #include <netdb.h>
 #include <signal.h>
@@ -38,6 +40,10 @@
 #include <pwd.h>
 #include <grp.h>
 #include <limits.h>
+#ifdef __APPLE__
+#  include <libgen.h>
+#  include <darwin_compat.h>
+#endif
 
 #include "cache.h"
 
