Skip to content

Commit

Permalink
Add support for MacFUSE filesystems
Browse files Browse the repository at this point in the history
Add wrapper libraries libmacfuse_i32 and libmacfuse_i64 for libosxfuse_i32 and
libosxfuse_i64, respectively. libmacfuse is binary compatible with the latest
official release of MacFUSE (MacFUSE 2.1.5).
  • Loading branch information
bfleischer committed Jul 16, 2011
1 parent 7e585c0 commit dbf53e0
Show file tree
Hide file tree
Showing 10 changed files with 594 additions and 89 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,13 @@ config.*
/osxfuse.pc
/.pc
/patches

*.mode1
*.mode1v3
*.mode2v3
*.perspective
*.perspectivev3
*.pbxuser
project.xcworkspace/
xcuserdata/
build/
2 changes: 1 addition & 1 deletion darwin_configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ OSXFUSE_SRCROOT=${OSXFUSE_SRCROOT:-$1}
OSXFUSE_SRCROOT=${OSXFUSE_SRCROOT:?}

./makeconf.sh && \
CFLAGS="-D__DARWIN_64_BIT_INO_T=0 -D__FreeBSD__=10 -D_POSIX_C_SOURCE=200112L -I$OSXFUSE_SRCROOT/common -O -gdwarf-2 -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.5" LDFLAGS="-arch i386 -arch x86_64 -framework CoreFoundation" ./configure --prefix=/usr/local --disable-dependency-tracking --disable-static
CFLAGS="-D__DARWIN_64_BIT_INO_T=0 -D__FreeBSD__=10 -DMACFUSE_MODE -D_POSIX_C_SOURCE=200112L -I$OSXFUSE_SRCROOT/common -O -gdwarf-2 -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.5" LDFLAGS="-arch i386 -arch x86_64 -framework CoreFoundation" ./configure --prefix=/usr/local --disable-dependency-tracking --disable-static
2 changes: 1 addition & 1 deletion darwin_configure_ino64.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ OSXFUSE_SRCROOT=${OSXFUSE_SRCROOT:-$1}
OSXFUSE_SRCROOT=${OSXFUSE_SRCROOT:?}

./makeconf.sh && \
CFLAGS="-D__DARWIN_64_BIT_INO_T=1 -D__FreeBSD__=10 -D_POSIX_C_SOURCE=200112L -I$OSXFUSE_SRCROOT/common -O -gdwarf-2 -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.6" LDFLAGS="-arch i386 -arch x86_64 -framework CoreFoundation" ./configure --prefix=/usr/local --disable-dependency-tracking --disable-static
CFLAGS="-D__DARWIN_64_BIT_INO_T=1 -D__FreeBSD__=10 -DMACFUSE_MODE -D_POSIX_C_SOURCE=200112L -I$OSXFUSE_SRCROOT/common -O -gdwarf-2 -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.6" LDFLAGS="-arch i386 -arch x86_64 -framework CoreFoundation" ./configure --prefix=/usr/local --disable-dependency-tracking --disable-static
19 changes: 0 additions & 19 deletions include/fuse_darwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,6 @@ typedef fuse_sem_t sem_t;

#endif /* DARWIN_SEMAPHORE_COMPAT */

/* Notifications */

#define LIBOSXFUSE_BUNDLE_IDENTIFIER "com.github.osxfuse.libosxfuse"

#define LIBOSXFUSE_UNOTIFICATIONS_OBJECT \
LIBOSXFUSE_BUNDLE_IDENTIFIER ".unotifications"

#define LIBOSXFUSE_UNOTIFICATIONS_NOTIFY_OSISTOONEW \
LIBOSXFUSE_BUNDLE_IDENTIFIER ".osistoonew"

#define LIBOSXFUSE_UNOTIFICATIONS_NOTIFY_OSISTOOOLD \
LIBOSXFUSE_BUNDLE_IDENTIFIER ".osistooold"

#define LIBOSXFUSE_UNOTIFICATIONS_NOTIFY_RUNTIMEVERSIONMISMATCH \
LIBOSXFUSE_BUNDLE_IDENTIFIER ".runtimeversionmismatch"

#define LIBOSXFUSE_UNOTIFICATIONS_NOTIFY_VERSIONMISMATCH \
LIBOSXFUSE_BUNDLE_IDENTIFIER ".versionmismatch"

/* Versioning */
const char *osxfuse_version(void);
long fuse_os_version_major_np(void);
Expand Down
6 changes: 6 additions & 0 deletions include/fuse_darwin_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern "C" {
#include <fuse_version.h>
#include <pthread.h>
#include <strhash.h>
#include <stdbool.h>

#ifdef __cplusplus
}
Expand All @@ -43,6 +44,11 @@ void fuse_set_fuse_internal_np(int fd, struct fuse *f);

void fuse_unset_fuse_internal_np(struct fuse *f);

#ifdef MACFUSE_MODE
void osxfuse_enable_macfuse_mode(bool arg);
bool osxfuse_is_macfuse_mode_enabled();
#endif

/*
* The mount_hash maps char* mountpoint -> struct mount_info. It is protected
* by the mount_lock mutex, which is held across a mount operation.
Expand Down
21 changes: 13 additions & 8 deletions lib/fuse_darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdbool.h>

#include <fuse_lowlevel.h>
#include "fuse_darwin_private.h"
Expand Down Expand Up @@ -322,19 +323,11 @@ fuse_unset_fuse_internal_np(struct fuse *f)
pthread_mutex_unlock(&mount_lock);
}

#ifdef MACFUSE
const char *
macfuse_version(void)
{
return OSXFUSE_VERSION;
}
#else /* !MACFUSE */
const char *
osxfuse_version(void)
{
return OSXFUSE_VERSION;
}
#endif /* !MACFUSE */

int
fuse_device_fd_np(const char *mountpoint)
Expand Down Expand Up @@ -423,6 +416,18 @@ fuse_knote_np(const char *mountpoint, const char *path, uint32_t note)

/********************/

#ifdef MACFUSE_MODE
static bool osxfuse_macfuse_mode = false;

void osxfuse_enable_macfuse_mode(bool arg) {
osxfuse_macfuse_mode = arg;
}

bool osxfuse_is_macfuse_mode_enabled() {
return osxfuse_macfuse_mode;
}
#endif

pthread_mutex_t mount_lock;
hash_table *mount_hash;
int mount_count;
Expand Down
166 changes: 106 additions & 60 deletions lib/mount_darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <errno.h>
#include <string.h>
#include <paths.h>
#include <stdbool.h>

#include <libproc.h>
#include <sys/utsname.h>
Expand Down Expand Up @@ -116,70 +117,110 @@ loadkmod(void)
return result;
}

static int
post_notification(char *name,
char *udata_keys[],
char *udata_values[],
CFIndex nf_num)
{
CFIndex i;
CFStringRef nf_name = NULL;
CFStringRef nf_object = NULL;
CFMutableDictionaryRef nf_udata = NULL;
/* OSXFUSE notifications */

CFNotificationCenterRef distributedCenter;
CFStringEncoding encoding = kCFStringEncodingUTF8;
enum osxfuse_notification {
NOTIFICATION_OS_IS_TOO_NEW,
NOTIFICATION_OS_IS_TOO_OLD,
NOTIFICATION_RUNTIME_VERSION_MISMATCH,
NOTIFICATION_VERSION_MISMATCH
};

distributedCenter = CFNotificationCenterGetDistributedCenter();
typedef enum osxfuse_notification osxfuse_notification_t;

if (!distributedCenter) {
return -1;
}
const char * const osxfuse_notification_names[] = {
"kOSXFUSEOSIsTooNew", // NOTIFICATION_OS_IS_TOO_NEW
"kOSXFUSEOSIsTooOld", // NOTIFICATION_OS_IS_TOO_OLD
"kOSXFUSERuntimeVersionMismatch", // NOTIFICATION_RUNTIME_VERSION_MISMATCH
"kOSXFUSEVersionMismatch" // NOTIFICATION_VERSION_MISMATCH
};

nf_name = CFStringCreateWithCString(kCFAllocatorDefault, name, encoding);

nf_object = CFStringCreateWithCString(kCFAllocatorDefault,
LIBOSXFUSE_UNOTIFICATIONS_OBJECT,
encoding);

nf_udata = CFDictionaryCreateMutable(kCFAllocatorDefault,
nf_num,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
const char * const osxfuse_notification_object = OSXFUSE_IDENTIFIER;

if (!nf_name || !nf_object || !nf_udata) {
goto out;
}
#ifdef MACFUSE_MODE
#define OSXFUSE_MACFUSE_MODE_ENV "OSXFUSE_MACFUSE_MODE"

for (i = 0; i < nf_num; i++) {
CFStringRef a_key = CFStringCreateWithCString(kCFAllocatorDefault,
udata_keys[i],
kCFStringEncodingUTF8);
CFStringRef a_value = CFStringCreateWithCString(kCFAllocatorDefault,
udata_values[i],
kCFStringEncodingUTF8);
CFDictionarySetValue(nf_udata, a_key, a_value);
CFRelease(a_key);
CFRelease(a_value);
}

CFNotificationCenterPostNotification(distributedCenter,
nf_name, nf_object, nf_udata, false);
#define MACFUSE_NOTIFICATION_PREFIX "com.google.filesystems.libfuse"
#define MACFUSE_NOTIFICATION_OBJECT \
MACFUSE_NOTIFICATION_PREFIX ".unotifications"

out:
if (nf_name) {
CFRelease(nf_name);
}
const char * const macfuse_notification_names[] = {
MACFUSE_NOTIFICATION_PREFIX ".osistoonew", // NOTIFICATION_OS_IS_TOO_NEW
MACFUSE_NOTIFICATION_PREFIX ".osistooold", // NOTIFICATION_OS_IS_TOO_OLD
MACFUSE_NOTIFICATION_PREFIX ".runtimeversionmismatch", // NOTIFICATION_RUNTIME_VERSION_MISMATCH
MACFUSE_NOTIFICATION_PREFIX ".versionmismatch" // NOTIFICATION_VERSION_MISMATCH
};

if (nf_object) {
CFRelease(nf_object);
}
const char * const macfuse_notification_object = MACFUSE_NOTIFICATION_OBJECT;
#endif /* MACFUSE_MODE */

if (nf_udata) {
CFRelease(nf_udata);
static void
post_notification(const osxfuse_notification_t notification,
const char *dict[][2],
const int dict_count)
{
CFNotificationCenterRef notification_center =
CFNotificationCenterGetDistributedCenter();

CFStringRef name = NULL;
CFStringRef object = NULL;
CFMutableDictionaryRef user_info = NULL;

#ifdef MACFUSE_MODE
if (osxfuse_is_macfuse_mode_enabled()) {
name = CFStringCreateWithCString(kCFAllocatorDefault,
macfuse_notification_names[notification],
kCFStringEncodingUTF8);
object = CFStringCreateWithCString(kCFAllocatorDefault,
macfuse_notification_object,
kCFStringEncodingUTF8);
} else {
#endif
name = CFStringCreateWithCString(kCFAllocatorDefault,
osxfuse_notification_names[notification],
kCFStringEncodingUTF8);
object = CFStringCreateWithCString(kCFAllocatorDefault,
osxfuse_notification_object,
kCFStringEncodingUTF8);
#ifdef MACFUSE_MODE
}
#endif

if (!name || !object) goto out;
if (dict_count == 0) goto post;

user_info = CFDictionaryCreateMutable(kCFAllocatorDefault, dict_count,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);

CFStringRef key;
CFStringRef value;
int i;
for (i = 0; i < dict_count; i++) {
key = CFStringCreateWithCString(kCFAllocatorDefault, dict[i][0],
kCFStringEncodingUTF8);
value = CFStringCreateWithCString(kCFAllocatorDefault, dict[i][1],
kCFStringEncodingUTF8);

if (!key || !value) {
if (key) CFRelease(key);
if (value) CFRelease(value);
goto out;
}

CFDictionarySetValue(user_info, key, value);
CFRelease(key); key = NULL;
CFRelease(value); value = NULL;
}

return 0;

post:
CFNotificationCenterPostNotification(notification_center, name, object,
user_info, false);

out:
if (name) CFRelease(name);
if (object) CFRelease(object);
if (user_info) CFRelease(user_info);
}

enum {
Expand Down Expand Up @@ -502,8 +543,7 @@ fuse_mount_core(const char *mountpoint, const char *opts)
CFSTR("OK")
);
}
post_notification(
LIBOSXFUSE_UNOTIFICATIONS_NOTIFY_OSISTOOOLD, NULL, NULL, 0);
post_notification(NOTIFICATION_OS_IS_TOO_OLD, NULL, 0);
} else if (result == EBUSY) {
if (!quiet_mode) {
CFUserNotificationDisplayNotice(
Expand All @@ -517,8 +557,8 @@ fuse_mount_core(const char *mountpoint, const char *opts)
CFSTR("OK")
);
}
post_notification(LIBOSXFUSE_UNOTIFICATIONS_NOTIFY_VERSIONMISMATCH,
NULL, NULL, 0);
post_notification(NOTIFICATION_VERSION_MISMATCH,
NULL, 0);
}
fprintf(stderr, "the OSXFUSE file system is not available (%d)\n",
result);
Expand Down Expand Up @@ -557,8 +597,8 @@ fuse_mount_core(const char *mountpoint, const char *opts)
CFSTR("OK")
);
}
post_notification(LIBOSXFUSE_UNOTIFICATIONS_NOTIFY_RUNTIMEVERSIONMISMATCH,
NULL, NULL, 0);
post_notification(NOTIFICATION_RUNTIME_VERSION_MISMATCH,
NULL, 0);
fprintf(stderr,
"this OSXFUSE library version is incompatible with "
"the OSXFUSE kernel extension\n");
Expand Down Expand Up @@ -684,6 +724,12 @@ fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
/* to notify mount_fusefs it's called from lib */
setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);

#ifdef MACFUSE_MODE
if (osxfuse_is_macfuse_mode_enabled()) {
setenv(OSXFUSE_MACFUSE_MODE_ENV, "1", 1);
}
#endif

if (args &&
fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1) {
return -1;
Expand Down

0 comments on commit dbf53e0

Please sign in to comment.