Ticket #30440: diff_against_upstream_2.3.diff

File diff_against_upstream_2.3.diff, 30.3 KB (added by anatol (Anatol Pomozov), 13 years ago)

Diff against upstream sshfs 2.3

  • Makefile.am

    diff --git a/Makefile.am b/Makefile.am
    index a80788b..99e1dc8 100644
    a b  
    22
    33bin_PROGRAMS = sshfs
    44
    5 sshfs_SOURCES = sshfs.c cache.c cache.h
     5sshfs_SOURCES = sshfs.c cache.c cache.h compat/darwin_semaphore.h compat/darwin_semaphore.c
    66if FUSE_OPT_COMPAT
    77sshfs_SOURCES += compat/fuse_opt.c compat/fuse_opt.h
    88endif
    99
    1010sshfs_LDADD = $(SSHFS_LIBS)
    1111sshfs_CFLAGS = $(SSHFS_CFLAGS)
    12 sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\"
     12sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\" -Icompat
    1313
    1414EXTRA_DIST = sshnodelay.c FAQ.txt
    1515CLEANFILES = sshnodelay.so
  • new file uild.rb

    diff --git a/build.rb b/build.rb
    new file mode 100755
    index 0000000..b7a1d85
    - +  
     1#!/usr/bin/env ruby
     2# Possible flags are:
     3#   --debug       this builds distribuition with debug flags enabled
     4#   --root DIR    install the binary into this directory. If this flag is not set - the script
     5#                 redeploys kext to local machine and restarts it
     6#   --static      build static sshfs binary, it dynamically links only with fuse4x library
     7#   --clean       clean before build
     8
     9require 'fileutils'
     10
     11CWD = File.dirname(__FILE__)
     12KEXT_DIR = '/System/Library/Extensions/'
     13Dir.chdir(CWD)
     14
     15debug = ARGV.include?('--debug')
     16clean = ARGV.include?('--clean')
     17static = ARGV.include?('--static')
     18root_dir = ARGV.index('--root') ? ARGV[ARGV.index('--root') + 1] : nil
     19
     20abort("root directory #{root_dir} does not exist") if ARGV.index('--root') and not File.exists?(root_dir)
     21
     22system('git clean -xdf') if clean
     23
     24unless File.exists?('Makefile') then
     25  system("autoreconf -f -i -Wall,no-obsolete") or abort
     26  system("./configure") or abort
     27end
     28
     29tmp_dir = "/tmp/sshfsbuild-#{Process.pid}"
     30Dir.mkdir(tmp_dir)
     31
     32ld_flags = ''
     33dylibs = %w(iconv gthread-2.0 glib-2.0 intl)
     34if static
     35  # In case if we build the distribution we need statically link against
     36  # macports libraries from the 'dylibs' list above.
     37  # To do it - we trick the build system by adding temp path with static libraries.
     38  for lib in dylibs do
     39    `ln -s /opt/local/lib/lib#{lib}.a #{tmp_dir}/`
     40  end
     41
     42  ld_flags = "LDFLAGS='-L#{tmp_dir} -framework CoreFoundation -framework CoreServices'"
     43end
     44
     45system("make -s -j3 #{ld_flags}") or abort
     46
     47cmd = 'sudo make install'
     48if root_dir
     49  cmd = cmd + ' DESTDIR=' + root_dir
     50end
     51
     52system(cmd)
     53
     54FileUtils.rm_rf(tmp_dir)
  • cache.c

    diff --git a/cache.c b/cache.c
    index bb23f8f..5b635f2 100644
    a b struct fuse_operations *cache_init(struct fuse_cache_operations *oper) 
    559559        cache.next_oper = oper;
    560560
    561561        cache_unity_fill(oper, &cache_oper);
     562#ifdef __APPLE__
     563        cache_enabled = cache.on;
     564#endif
    562565        if (cache.on) {
    563566                cache_fill(oper, &cache_oper);
    564567                pthread_mutex_init(&cache.lock, NULL);
    int cache_parse_options(struct fuse_args *args) 
    593596
    594597        return fuse_opt_parse(args, &cache, cache_opts, NULL);
    595598}
     599
     600#ifdef __APPLE__
     601int cache_enabled;
     602#endif
  • cache.h

    diff --git a/cache.h b/cache.h
    index cec9ca4..8ca0989 100644
    a b int cache_parse_options(struct fuse_args *args); 
    2727void cache_add_attr(const char *path, const struct stat *stbuf, uint64_t wrctr);
    2828void cache_invalidate(const char *path);
    2929uint64_t cache_get_write_ctr(void);
     30
     31#ifdef __APPLE__
     32extern int cache_enabled;
     33#endif
  • new file compat/darwin_semaphore.c

    diff --git a/compat/darwin_semaphore.c b/compat/darwin_semaphore.c
    new file mode 100644
    index 0000000..e45fd9a
    - +  
     1/*
     2 * Copyright (C) 2000,02 Free Software Foundation, Inc.
     3 * This file is part of the GNU C Library.
     4 * Written by Ga<EB>l Le Mignot <address@hidden>
     5 *
     6 * The GNU C Library is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU Library General Public License as
     8 * published by the Free Software Foundation; either version 2 of the
     9 * License, or (at your option) any later version.
     10 *
     11 * The GNU C Library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Library General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Library General Public
     17 * License along with the GNU C Library; see the file COPYING.LIB.  If not,
     18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     19 * Boston, MA 02111-1307, USA.
     20 */
     21
     22#include "darwin_semaphore.h"
     23
     24#include <assert.h>
     25#include <errno.h>
     26#include <sys/types.h>
     27
     28#define __SEM_ID_NONE  0x0
     29#define __SEM_ID_LOCAL 0xcafef00d
     30
     31/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_init.html */
     32int
     33compat_sem_init(compat_sem_t *sem, int pshared, unsigned int value)
     34{
     35    if (pshared) {
     36        errno = ENOSYS;
     37        return -1;
     38    }
     39
     40    sem->id = __SEM_ID_NONE;
     41
     42    if (pthread_cond_init(&sem->__data.local.count_cond, NULL)) {
     43        goto cond_init_fail;
     44    }
     45
     46    if (pthread_mutex_init(&sem->__data.local.count_lock, NULL)) {
     47        goto mutex_init_fail;
     48    }
     49
     50    sem->__data.local.count = value;
     51    sem->id = __SEM_ID_LOCAL;
     52
     53    return 0;
     54
     55mutex_init_fail:
     56
     57    pthread_cond_destroy(&sem->__data.local.count_cond);
     58
     59cond_init_fail:
     60
     61    return -1;
     62}
     63
     64/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_destroy.html */
     65int
     66compat_sem_destroy(compat_sem_t *sem)
     67{
     68    int res = 0;
     69
     70    pthread_mutex_lock(&sem->__data.local.count_lock);
     71
     72    sem->id = __SEM_ID_NONE;
     73    pthread_cond_broadcast(&sem->__data.local.count_cond);
     74
     75    if (pthread_cond_destroy(&sem->__data.local.count_cond)) {
     76        res = -1;
     77    }
     78
     79    pthread_mutex_unlock(&sem->__data.local.count_lock);
     80
     81    if (pthread_mutex_destroy(&sem->__data.local.count_lock)) {
     82        res = -1;
     83    }
     84
     85    return res;
     86}
     87
     88int
     89compat_sem_getvalue(compat_sem_t *sem, unsigned int *sval)
     90{
     91    int res = 0;
     92
     93    pthread_mutex_lock(&sem->__data.local.count_lock);
     94
     95    if (sem->id != __SEM_ID_LOCAL) {
     96        res = -1;
     97        errno = EINVAL;
     98    } else {
     99        *sval = sem->__data.local.count;
     100    }
     101
     102    pthread_mutex_unlock(&sem->__data.local.count_lock);
     103
     104    return res;
     105}
     106
     107/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_post.html */
     108int
     109compat_sem_post(compat_sem_t *sem)
     110{
     111    int res = 0;
     112
     113    pthread_mutex_lock(&sem->__data.local.count_lock);
     114
     115    if (sem->id != __SEM_ID_LOCAL) {
     116        res = -1;
     117        errno = EINVAL;
     118    } else if (sem->__data.local.count < COMPAT_SEM_VALUE_MAX) {
     119        sem->__data.local.count++;
     120        if (sem->__data.local.count == 1) {
     121            pthread_cond_signal(&sem->__data.local.count_cond);
     122        }
     123    } else {
     124        errno = ERANGE;
     125        res = -1;
     126    }
     127
     128    pthread_mutex_unlock(&sem->__data.local.count_lock);
     129
     130    return res;
     131}
     132
     133/* http://www.opengroup.org/onlinepubs/009695399/functions/sem_timedwait.html */
     134int
     135compat_sem_timedwait(compat_sem_t *sem, const struct timespec *abs_timeout)
     136{
     137    int res = 0;
     138
     139    if (abs_timeout &&
     140        (abs_timeout->tv_nsec < 0 || abs_timeout->tv_nsec >= 1000000000)) {
     141       errno = EINVAL;
     142       return -1;
     143    }
     144
     145    pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock,
     146                         &sem->__data.local.count_lock);
     147
     148    pthread_mutex_lock(&sem->__data.local.count_lock);
     149
     150    if (sem->id != __SEM_ID_LOCAL) {
     151        errno = EINVAL;
     152        res = -1;
     153    } else {
     154        if (!sem->__data.local.count) {
     155            res = pthread_cond_timedwait(&sem->__data.local.count_cond,
     156                                         &sem->__data.local.count_lock,
     157                                         abs_timeout);
     158        }
     159        if (res) {
     160            assert(res == ETIMEDOUT);
     161            res = -1;
     162            errno = ETIMEDOUT;
     163        } else if (sem->id != __SEM_ID_LOCAL) {
     164            res = -1;
     165            errno = EINVAL;
     166        } else {
     167            sem->__data.local.count--;
     168        }
     169    }
     170
     171    pthread_cleanup_pop(1);
     172
     173    return res;
     174}
     175
     176/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_trywait.html */
     177int
     178compat_sem_trywait(compat_sem_t *sem)
     179{
     180    int res = 0;
     181
     182    pthread_mutex_lock(&sem->__data.local.count_lock);
     183
     184    if (sem->id != __SEM_ID_LOCAL) {
     185        res = -1;
     186        errno = EINVAL;
     187    } else if (sem->__data.local.count) {
     188        sem->__data.local.count--;
     189    } else {
     190        res = -1;
     191        errno = EAGAIN;
     192    }
     193
     194    pthread_mutex_unlock (&sem->__data.local.count_lock);
     195
     196    return res;
     197}
     198
     199/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_wait.html */
     200int
     201compat_sem_wait(compat_sem_t *sem)
     202{
     203    int res = 0;
     204
     205    pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock,
     206                          &sem->__data.local.count_lock);
     207
     208    pthread_mutex_lock(&sem->__data.local.count_lock);
     209
     210    if (sem->id != __SEM_ID_LOCAL) {
     211        errno = EINVAL;
     212        res = -1;
     213    } else {
     214        while (!sem->__data.local.count) {
     215            pthread_cond_wait(&sem->__data.local.count_cond,
     216                              &sem->__data.local.count_lock);
     217        }
     218        if (sem->id != __SEM_ID_LOCAL) {
     219            res = -1;
     220            errno = EINVAL;
     221        } else {
     222            sem->__data.local.count--;
     223        }
     224    }
     225
     226    pthread_cleanup_pop(1);
     227
     228    return res;
     229}
  • new file compat/darwin_semaphore.h

    diff --git a/compat/darwin_semaphore.h b/compat/darwin_semaphore.h
    new file mode 100644
    index 0000000..3f03e41
    - +  
     1/* Copyright (C) 2000,02 Free Software Foundation, Inc.
     2   This file is part of the GNU C Library.
     3   Written by Gaël Le Mignot <address@hidden>
     4
     5   The GNU C Library is free software; you can redistribute it and/or
     6   modify it under the terms of the GNU Library General Public License as
     7   published by the Free Software Foundation; either version 2 of the
     8   License, or (at your option) any later version.
     9
     10   The GNU C Library is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Library General Public License for more details.
     14
     15   You should have received a copy of the GNU Library General Public
     16   License along with the GNU C Library; see the file COPYING.LIB.  If not,
     17   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     18   Boston, MA 02111-1307, USA.  */
     19
     20// This implementation is based on libsem http://lists.debian.org/debian-devel/2004/08/msg00612.html
     21
     22#ifndef _SEMAPHORE_H_
     23#define _SEMAPHORE_H_
     24
     25/* Caller must not include <semaphore.h> */
     26
     27#include <pthread.h>
     28
     29struct __local_sem_t
     30{
     31    unsigned int    count;
     32    pthread_mutex_t count_lock;
     33    pthread_cond_t  count_cond;
     34};
     35
     36typedef struct compat_sem {
     37    unsigned int id;
     38    union {
     39        struct __local_sem_t local;
     40    } __data;
     41} compat_sem_t;
     42
     43#define COMPAT_SEM_VALUE_MAX ((int32_t)32767)
     44
     45int compat_sem_init(compat_sem_t *sem, int pshared, unsigned int value);
     46int compat_sem_destroy(compat_sem_t *sem);
     47int compat_sem_getvalue(compat_sem_t *sem, unsigned int *value);
     48int compat_sem_post(compat_sem_t *sem);
     49int compat_sem_timedwait(compat_sem_t *sem, const struct timespec *abs_timeout);
     50int compat_sem_trywait(compat_sem_t *sem);
     51int compat_sem_wait(compat_sem_t *sem);
     52
     53
     54/* Redefine semaphores. Caller must not include <semaphore.h> */
     55
     56typedef compat_sem_t sem_t;
     57
     58#define sem_init(s, p, v)   compat_sem_init(s, p, v)
     59#define sem_destroy(s)      compat_sem_destroy(s)
     60#define sem_getvalue(s, v)  compat_sem_getvalue(s, v)
     61#define sem_post(s)         compat_sem_post(s)
     62#define sem_timedwait(s, t) compat_sem_timedwait(s, t)
     63#define sem_trywait(s)      compat_sem_trywait(s)
     64#define sem_wait(s)         compat_sem_wait(s)
     65
     66#define SEM_VALUE_MAX       COMPAT_SEM_VALUE_MAX
     67
     68
     69#endif /* semaphore.h */
  • configure.ac

    diff --git a/configure.ac b/configure.ac
    index 1cf48b3..f737b41 100644
    a b  
    1 AC_INIT(sshfs-fuse, 2.3)
     1AC_INIT(sshfs-fuse, 2.3.0)
    22AM_INIT_AUTOMAKE
    33AM_CONFIG_HEADER(config.h)
    44
    55AC_PROG_CC
    66AM_PROG_CC_C_O
    7 CFLAGS="$CFLAGS -Wall -W"
     7CFLAGS="$CFLAGS -Wall -W -mmacosx-version-min=10.5"
    88LIBS=
    99AC_SEARCH_LIBS(dlsym, [dl])
    1010sshnodelay_libs=$LIBS
  • sshfs.c

    diff --git a/sshfs.c b/sshfs.c
    index 22bda6b..9698c74 100644
    a b  
    2020#include <string.h>
    2121#include <stdint.h>
    2222#include <errno.h>
     23#ifdef __APPLE__
     24#include <darwin_semaphore.h>
     25#else
    2326#include <semaphore.h>
     27#endif
    2428#include <pthread.h>
    2529#include <netdb.h>
    2630#include <signal.h>
     
    3539#include <netinet/in.h>
    3640#include <netinet/tcp.h>
    3741#include <glib.h>
     42#ifdef __APPLE__
     43#include <libgen.h>
     44#include <strings.h>
     45#endif
    3846
    3947#include "cache.h"
    4048
     
    118126
    119127#define SSHNODELAY_SO "sshnodelay.so"
    120128
     129#ifdef __APPLE__
     130
     131#ifndef LIBDIR
     132#define LIBDIR "/usr/local/lib"
     133#endif
     134
     135static char sshfs_program_path[PATH_MAX] = { 0 };
     136
     137#endif
     138
    121139struct buffer {
    122140        uint8_t *p;
    123141        size_t len;
    struct sshfs_file { 
    167185        int connver;
    168186        int modifver;
    169187        int refs;
     188#ifdef __APPLE__
     189        pthread_mutex_t file_lock;
     190#endif
    170191};
    171192
    172193struct sshfs {
    struct sshfs { 
    207228        int server_version;
    208229        unsigned remote_uid;
    209230        unsigned local_uid;
     231#ifdef __APPLE__
     232        unsigned remote_gid;
     233        unsigned local_gid;
     234#endif
    210235        int remote_uid_detected;
    211236        unsigned blksize;
    212237        char *progname;
    static int buf_get_attrs(struct buffer *buf, struct stat *stbuf, int *flagsp) 
    661686                }
    662687        }
    663688
     689#ifdef __APPLE__
     690        if (sshfs.remote_uid_detected) {
     691                if (uid == sshfs.remote_uid)
     692                        uid = sshfs.local_uid;
     693                if (gid == sshfs.remote_gid)
     694                        gid = sshfs.local_gid;
     695        }
     696#else
    664697        if (sshfs.remote_uid_detected && uid == sshfs.remote_uid)
    665698                uid = sshfs.local_uid;
     699#endif
    666700
    667701        memset(stbuf, 0, sizeof(struct stat));
    668702        stbuf->st_mode = mode;
    static void ssh_add_arg(const char *arg) 
    765799#ifdef SSH_NODELAY_WORKAROUND
    766800static int do_ssh_nodelay_workaround(void)
    767801{
     802#ifdef __APPLE__
     803        char *oldpreload = getenv("DYLD_INSERT_LIBRARIES");
     804#else
    768805        char *oldpreload = getenv("LD_PRELOAD");
     806#endif
    769807        char *newpreload;
    770808        char sopath[PATH_MAX];
    771809        int res;
    772810
     811#ifdef __APPLE__
     812        char *sshfs_program_path_base = NULL;
     813        if (!sshfs_program_path[0]) {
     814                goto nobundle;
     815        }
     816        sshfs_program_path_base = dirname(sshfs_program_path);
     817        if (!sshfs_program_path_base) {
     818                goto nobundle;
     819        }
     820        snprintf(sopath, sizeof(sopath), "%s/%s", sshfs_program_path_base,
     821                SSHNODELAY_SO);
     822        res = access(sopath, R_OK);
     823        if (res == -1) {
     824                goto nobundle;
     825        }
     826        goto pathok;
     827nobundle:
     828#endif
    773829        snprintf(sopath, sizeof(sopath), "%s/%s", LIBDIR, SSHNODELAY_SO);
    774830        res = access(sopath, R_OK);
    775831        if (res == -1) {
    static int do_ssh_nodelay_workaround(void) 
    794850                        return -1;
    795851                }
    796852        }
     853#ifdef __APPLE__
     854pathok:
     855#endif
    797856
    798857        newpreload = g_strdup_printf("%s%s%s",
    799858                                     oldpreload ? oldpreload : "",
    800859                                     oldpreload ? " " : "",
    801860                                     sopath);
    802861
     862#ifdef __APPLE__
     863        if (!newpreload || setenv("DYLD_INSERT_LIBRARIES", newpreload, 1) == -1)
     864                fprintf(stderr, "warning: failed set DYLD_INSERT_LIBRARIES for ssh nodelay workaround\n");
     865#else
    803866        if (!newpreload || setenv("LD_PRELOAD", newpreload, 1) == -1) {
    804867                fprintf(stderr, "warning: failed set LD_PRELOAD "
    805868                        "for ssh nodelay workaround\n");
    806869        }
     870#endif
    807871        g_free(newpreload);
    808872        return 0;
    809873}
    static void sftp_detect_uid() 
    15001564
    15011565        sshfs.remote_uid = stbuf.st_uid;
    15021566        sshfs.local_uid = getuid();
     1567#ifdef __APPLE__
     1568        sshfs.remote_gid = stbuf.st_gid;
     1569        sshfs.local_gid = getgid();
     1570#endif
    15031571        sshfs.remote_uid_detected = 1;
    15041572        DEBUG("remote_uid = %i\n", sshfs.remote_uid);
    15051573
    static int sshfs_chown(const char *path, uid_t uid, gid_t gid) 
    21202188        buf_init(&buf, 0);
    21212189        buf_add_path(&buf, path);
    21222190        buf_add_uint32(&buf, SSH_FILEXFER_ATTR_UIDGID);
     2191#ifdef __APPLE__
     2192        if (sshfs.remote_uid_detected) {
     2193                if (uid == sshfs.local_uid)
     2194                        uid = sshfs.remote_uid;
     2195                if (gid == sshfs.local_gid)
     2196                        gid = sshfs.remote_gid;
     2197        }
     2198#endif
    21232199        buf_add_uint32(&buf, uid);
    21242200        buf_add_uint32(&buf, gid);
    21252201        err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
    static int sshfs_open_common(const char *path, mode_t mode, 
    22032279        sf = g_new0(struct sshfs_file, 1);
    22042280        list_init(&sf->write_reqs);
    22052281        pthread_cond_init(&sf->write_finished, NULL);
     2282#ifdef __APPLE__
     2283        pthread_mutex_init(&sf->file_lock, NULL);
     2284#endif
    22062285        /* Assume random read after open */
    22072286        sf->is_seq = 0;
    22082287        sf->refs = 1;
    static int sshfs_open_common(const char *path, mode_t mode, 
    22362315        }
    22372316
    22382317        if (!err) {
     2318#ifdef __APPLE__
     2319                if (cache_enabled)
     2320                        cache_add_attr(path, &stbuf, wrctr);
     2321#else
    22392322                cache_add_attr(path, &stbuf, wrctr);
     2323#endif
    22402324                buf_finish(&sf->handle);
    22412325                fi->fh = (unsigned long) sf;
    22422326        } else {
     2327#ifdef __APPLE__
     2328                if (cache_enabled)
     2329                        cache_invalidate(path);
     2330#else
    22432331                cache_invalidate(path);
     2332#endif
    22442333                g_free(sf);
    22452334        }
    22462335        buf_free(&buf);
    static int sshfs_fsync(const char *path, int isdatasync, 
    22952384
    22962385static void sshfs_file_put(struct sshfs_file *sf)
    22972386{
     2387#ifdef __APPLE__
     2388        pthread_mutex_lock(&sf->file_lock);
     2389#endif
    22982390        sf->refs--;
     2391#ifdef __APPLE__
     2392        if (!sf->refs) {
     2393                pthread_mutex_unlock(&sf->file_lock);
     2394                g_free(sf);
     2395        } else {
     2396                pthread_mutex_unlock(&sf->file_lock);
     2397        }
     2398#else
    22992399        if (!sf->refs)
    23002400                g_free(sf);
     2401#endif
    23012402}
    23022403
    23032404static void sshfs_file_get(struct sshfs_file *sf)
    23042405{
     2406#ifdef __APPLE__
     2407        pthread_mutex_lock(&sf->file_lock);
     2408#endif
    23052409        sf->refs++;
     2410#ifdef __APPLE__
     2411        pthread_mutex_unlock(&sf->file_lock);
     2412#endif
    23062413}
    23072414
    23082415static int sshfs_release(const char *path, struct fuse_file_info *fi)
    static int read_password(void) 
    30763183                perror("Failed to allocate locked page for password");
    30773184                return -1;
    30783185        }
     3186#ifdef __APPLE__
     3187        if (mlock(sshfs.password, size) != 0) {
     3188                memset(sshfs.password, 0, size);
     3189                munmap(sshfs.password, size);
     3190                sshfs.password = NULL;
     3191                perror("Failed to allocate locked page for password");
     3192                return -1;
     3193        }
     3194#endif /* __APPLE__ */
    30793195
    30803196        /* Don't use fgets() because password might stay in memory */
    30813197        for (n = 0; n < max_password; n++) {
    static void set_ssh_command(void) 
    31233239                                replace_arg(&sshfs.ssh_args.argv[0],
    31243240                                            sshfs.ssh_command);
    31253241                        } else {
    3126                                 if (fuse_opt_insert_arg(&sshfs.ssh_args, i, 
     3242                                if (fuse_opt_insert_arg(&sshfs.ssh_args, i,
    31273243                                                sshfs.ssh_command) == -1)
    31283244                                        _exit(1);
    31293245                        }
    static int ssh_connect(void) 
    32273343        return 0;
    32283344}
    32293345
    3230 int main(int argc, char *argv[])
     3346int main(int argc, char *argv[], __unused char *envp[], char **exec_path)
    32313347{
     3348#ifdef __APPLE__
     3349        if (!realpath(*exec_path, sshfs_program_path)) {
     3350                memset(sshfs_program_path, 0, PATH_MAX);
     3351        }
     3352#endif
    32323353        int res;
    32333354        struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    32343355        char *tmp;
    int main(int argc, char *argv[]) 
    32363357        const char *sftp_server;
    32373358        int libver;
    32383359
     3360#ifdef __APPLE__
     3361        /* Until this gets fixed somewhere else. */
     3362        g_slice_set_config(G_SLICE_CONFIG_ALWAYS_MALLOC, TRUE);
     3363#endif /* __APPLE__ */
    32393364        g_thread_init(NULL);
    32403365
    32413366        sshfs.blksize = 4096;
    int main(int argc, char *argv[]) 
    32433368        sshfs.max_write = 65536;
    32443369        sshfs.nodelay_workaround = 1;
    32453370        sshfs.nodelaysrv_workaround = 0;
     3371#ifdef __APPLE__
     3372        sshfs.rename_workaround = 1;
     3373#else
    32463374        sshfs.rename_workaround = 0;
     3375#endif /* __APPLE__ */
    32473376        sshfs.truncate_workaround = 0;
    32483377        sshfs.buflimit_workaround = 1;
    32493378        sshfs.ssh_ver = 2;
    int main(int argc, char *argv[]) 
    32573386        ssh_add_arg("-a");
    32583387        ssh_add_arg("-oClearAllForwardings=yes");
    32593388
     3389#ifdef __APPLE__
     3390        sshfs.detect_uid = 1;
     3391#endif
     3392
    32603393        if (fuse_opt_parse(&args, &sshfs, sshfs_opts, sshfs_opt_proc) == -1 ||
    32613394            parse_workarounds() == -1)
    32623395                exit(1);
  • new file sshfs.xcodeproj/project.pbxproj

    diff --git a/sshfs.xcodeproj/project.pbxproj b/sshfs.xcodeproj/project.pbxproj
    new file mode 100644
    index 0000000..b114fe3
    - +  
     1// !$*UTF8*$!
     2{
     3        archiveVersion = 1;
     4        classes = {
     5        };
     6        objectVersion = 46;
     7        objects = {
     8
     9/* Begin PBXBuildFile section */
     10                DE0F21EB139A7AFF003CBAC9 /* sshfs.c in Sources */ = {isa = PBXBuildFile; fileRef = DE0F21EA139A7AFF003CBAC9 /* sshfs.c */; };
     11                DE0F21EF139A7B0A003CBAC9 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = DE0F21ED139A7B0A003CBAC9 /* cache.c */; };
     12                DE0F21F1139A7B11003CBAC9 /* sshnodelay.c in Sources */ = {isa = PBXBuildFile; fileRef = DE0F21F0139A7B11003CBAC9 /* sshnodelay.c */; };
     13                DE37D32813CF7B660027D6F9 /* darwin_semaphore.c in Sources */ = {isa = PBXBuildFile; fileRef = DE37D32413CF7B660027D6F9 /* darwin_semaphore.c */; };
     14                DE37D32913CF7B660027D6F9 /* fuse_opt.c in Sources */ = {isa = PBXBuildFile; fileRef = DE37D32613CF7B660027D6F9 /* fuse_opt.c */; };
     15/* End PBXBuildFile section */
     16
     17/* Begin PBXCopyFilesBuildPhase section */
     18                DE0F21D3139A7ABB003CBAC9 /* CopyFiles */ = {
     19                        isa = PBXCopyFilesBuildPhase;
     20                        buildActionMask = 2147483647;
     21                        dstPath = /usr/share/man/man1/;
     22                        dstSubfolderSpec = 0;
     23                        files = (
     24                        );
     25                        runOnlyForDeploymentPostprocessing = 1;
     26                };
     27/* End PBXCopyFilesBuildPhase section */
     28
     29/* Begin PBXFileReference section */
     30                DE0F21D5139A7ABB003CBAC9 /* sshfs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sshfs; sourceTree = BUILT_PRODUCTS_DIR; };
     31                DE0F21E9139A7AFF003CBAC9 /* sshfs.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = sshfs.1; sourceTree = "<group>"; };
     32                DE0F21EA139A7AFF003CBAC9 /* sshfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sshfs.c; sourceTree = "<group>"; };
     33                DE0F21ED139A7B0A003CBAC9 /* cache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cache.c; sourceTree = "<group>"; };
     34                DE0F21EE139A7B0A003CBAC9 /* cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cache.h; sourceTree = "<group>"; };
     35                DE0F21F0139A7B11003CBAC9 /* sshnodelay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sshnodelay.c; sourceTree = "<group>"; };
     36                DE0F21F2139A7B1D003CBAC9 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
     37                DE0F21FC139B1EC3003CBAC9 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = configure.ac; sourceTree = "<group>"; };
     38                DE0F21FE139B1ECB003CBAC9 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
     39                DE37D32413CF7B660027D6F9 /* darwin_semaphore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = darwin_semaphore.c; sourceTree = "<group>"; };
     40                DE37D32513CF7B660027D6F9 /* darwin_semaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = darwin_semaphore.h; sourceTree = "<group>"; };
     41                DE37D32613CF7B660027D6F9 /* fuse_opt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fuse_opt.c; sourceTree = "<group>"; };
     42                DE37D32713CF7B660027D6F9 /* fuse_opt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fuse_opt.h; sourceTree = "<group>"; };
     43/* End PBXFileReference section */
     44
     45/* Begin PBXFrameworksBuildPhase section */
     46                DE0F21D2139A7ABB003CBAC9 /* Frameworks */ = {
     47                        isa = PBXFrameworksBuildPhase;
     48                        buildActionMask = 2147483647;
     49                        files = (
     50                        );
     51                        runOnlyForDeploymentPostprocessing = 0;
     52                };
     53/* End PBXFrameworksBuildPhase section */
     54
     55/* Begin PBXGroup section */
     56                DE0F21CA139A7ABB003CBAC9 = {
     57                        isa = PBXGroup;
     58                        children = (
     59                                DE37D32313CF7B660027D6F9 /* compat */,
     60                                DE0F21FE139B1ECB003CBAC9 /* Makefile.am */,
     61                                DE0F21FC139B1EC3003CBAC9 /* configure.ac */,
     62                                DE0F21F2139A7B1D003CBAC9 /* config.h */,
     63                                DE0F21F0139A7B11003CBAC9 /* sshnodelay.c */,
     64                                DE0F21ED139A7B0A003CBAC9 /* cache.c */,
     65                                DE0F21EE139A7B0A003CBAC9 /* cache.h */,
     66                                DE0F21E9139A7AFF003CBAC9 /* sshfs.1 */,
     67                                DE0F21EA139A7AFF003CBAC9 /* sshfs.c */,
     68                                DE0F21D6139A7ABB003CBAC9 /* Products */,
     69                        );
     70                        sourceTree = "<group>";
     71                };
     72                DE0F21D6139A7ABB003CBAC9 /* Products */ = {
     73                        isa = PBXGroup;
     74                        children = (
     75                                DE0F21D5139A7ABB003CBAC9 /* sshfs */,
     76                        );
     77                        name = Products;
     78                        sourceTree = "<group>";
     79                };
     80                DE37D32313CF7B660027D6F9 /* compat */ = {
     81                        isa = PBXGroup;
     82                        children = (
     83                                DE37D32413CF7B660027D6F9 /* darwin_semaphore.c */,
     84                                DE37D32513CF7B660027D6F9 /* darwin_semaphore.h */,
     85                                DE37D32613CF7B660027D6F9 /* fuse_opt.c */,
     86                                DE37D32713CF7B660027D6F9 /* fuse_opt.h */,
     87                        );
     88                        path = compat;
     89                        sourceTree = "<group>";
     90                };
     91/* End PBXGroup section */
     92
     93/* Begin PBXNativeTarget section */
     94                DE0F21D4139A7ABB003CBAC9 /* sshfs */ = {
     95                        isa = PBXNativeTarget;
     96                        buildConfigurationList = DE0F21DE139A7ABB003CBAC9 /* Build configuration list for PBXNativeTarget "sshfs" */;
     97                        buildPhases = (
     98                                DE0F21D1139A7ABB003CBAC9 /* Sources */,
     99                                DE0F21D2139A7ABB003CBAC9 /* Frameworks */,
     100                                DE0F21D3139A7ABB003CBAC9 /* CopyFiles */,
     101                        );
     102                        buildRules = (
     103                        );
     104                        dependencies = (
     105                        );
     106                        name = sshfs;
     107                        productName = sshfs;
     108                        productReference = DE0F21D5139A7ABB003CBAC9 /* sshfs */;
     109                        productType = "com.apple.product-type.tool";
     110                };
     111/* End PBXNativeTarget section */
     112
     113/* Begin PBXProject section */
     114                DE0F21CC139A7ABB003CBAC9 /* Project object */ = {
     115                        isa = PBXProject;
     116                        buildConfigurationList = DE0F21CF139A7ABB003CBAC9 /* Build configuration list for PBXProject "sshfs" */;
     117                        compatibilityVersion = "Xcode 3.2";
     118                        developmentRegion = English;
     119                        hasScannedForEncodings = 0;
     120                        knownRegions = (
     121                                en,
     122                        );
     123                        mainGroup = DE0F21CA139A7ABB003CBAC9;
     124                        productRefGroup = DE0F21D6139A7ABB003CBAC9 /* Products */;
     125                        projectDirPath = "";
     126                        projectRoot = "";
     127                        targets = (
     128                                DE0F21D4139A7ABB003CBAC9 /* sshfs */,
     129                        );
     130                };
     131/* End PBXProject section */
     132
     133/* Begin PBXSourcesBuildPhase section */
     134                DE0F21D1139A7ABB003CBAC9 /* Sources */ = {
     135                        isa = PBXSourcesBuildPhase;
     136                        buildActionMask = 2147483647;
     137                        files = (
     138                                DE0F21EB139A7AFF003CBAC9 /* sshfs.c in Sources */,
     139                                DE0F21EF139A7B0A003CBAC9 /* cache.c in Sources */,
     140                                DE0F21F1139A7B11003CBAC9 /* sshnodelay.c in Sources */,
     141                                DE37D32813CF7B660027D6F9 /* darwin_semaphore.c in Sources */,
     142                                DE37D32913CF7B660027D6F9 /* fuse_opt.c in Sources */,
     143                        );
     144                        runOnlyForDeploymentPostprocessing = 0;
     145                };
     146/* End PBXSourcesBuildPhase section */
     147
     148/* Begin XCBuildConfiguration section */
     149                DE0F21DC139A7ABB003CBAC9 /* Debug */ = {
     150                        isa = XCBuildConfiguration;
     151                        buildSettings = {
     152                                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
     153                                GCC_C_LANGUAGE_STANDARD = gnu99;
     154                                GCC_OPTIMIZATION_LEVEL = 0;
     155                                GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
     156                                GCC_SYMBOLS_PRIVATE_EXTERN = NO;
     157                                GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
     158                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
     159                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
     160                                GCC_WARN_UNUSED_VARIABLE = YES;
     161                                MACOSX_DEPLOYMENT_TARGET = 10.6;
     162                                ONLY_ACTIVE_ARCH = YES;
     163                                SDKROOT = macosx;
     164                        };
     165                        name = Debug;
     166                };
     167                DE0F21DD139A7ABB003CBAC9 /* Release */ = {
     168                        isa = XCBuildConfiguration;
     169                        buildSettings = {
     170                                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
     171                                GCC_C_LANGUAGE_STANDARD = gnu99;
     172                                GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
     173                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
     174                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
     175                                GCC_WARN_UNUSED_VARIABLE = YES;
     176                                MACOSX_DEPLOYMENT_TARGET = 10.6;
     177                                SDKROOT = macosx;
     178                        };
     179                        name = Release;
     180                };
     181                DE0F21DF139A7ABB003CBAC9 /* Debug */ = {
     182                        isa = XCBuildConfiguration;
     183                        buildSettings = {
     184                                ALWAYS_SEARCH_USER_PATHS = NO;
     185                                COPY_PHASE_STRIP = NO;
     186                                GCC_DYNAMIC_NO_PIC = NO;
     187                                GCC_ENABLE_OBJC_EXCEPTIONS = YES;
     188                                MACOSX_DEPLOYMENT_TARGET = 10.5;
     189                                PRODUCT_NAME = "$(TARGET_NAME)";
     190                        };
     191                        name = Debug;
     192                };
     193                DE0F21E0139A7ABB003CBAC9 /* Release */ = {
     194                        isa = XCBuildConfiguration;
     195                        buildSettings = {
     196                                ALWAYS_SEARCH_USER_PATHS = NO;
     197                                COPY_PHASE_STRIP = YES;
     198                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
     199                                GCC_ENABLE_OBJC_EXCEPTIONS = YES;
     200                                MACOSX_DEPLOYMENT_TARGET = 10.5;
     201                                PRODUCT_NAME = "$(TARGET_NAME)";
     202                        };
     203                        name = Release;
     204                };
     205/* End XCBuildConfiguration section */
     206
     207/* Begin XCConfigurationList section */
     208                DE0F21CF139A7ABB003CBAC9 /* Build configuration list for PBXProject "sshfs" */ = {
     209                        isa = XCConfigurationList;
     210                        buildConfigurations = (
     211                                DE0F21DC139A7ABB003CBAC9 /* Debug */,
     212                                DE0F21DD139A7ABB003CBAC9 /* Release */,
     213                        );
     214                        defaultConfigurationIsVisible = 0;
     215                        defaultConfigurationName = Release;
     216                };
     217                DE0F21DE139A7ABB003CBAC9 /* Build configuration list for PBXNativeTarget "sshfs" */ = {
     218                        isa = XCConfigurationList;
     219                        buildConfigurations = (
     220                                DE0F21DF139A7ABB003CBAC9 /* Debug */,
     221                                DE0F21E0139A7ABB003CBAC9 /* Release */,
     222                        );
     223                        defaultConfigurationIsVisible = 0;
     224                        defaultConfigurationName = Release;
     225                };
     226/* End XCConfigurationList section */
     227        };
     228        rootObject = DE0F21CC139A7ABB003CBAC9 /* Project object */;
     229}
  • new file sshfs.xcodeproj/project.xcworkspace/contents.xcworkspacedata

    diff --git a/sshfs.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/sshfs.xcodeproj/project.xcworkspace/contents.xcworkspacedata
    new file mode 100644
    index 0000000..3adcdb4
    - +  
     1<?xml version="1.0" encoding="UTF-8"?>
     2<Workspace
     3   version = "1.0">
     4   <FileRef
     5      location = "self:sshfs.xcodeproj">
     6   </FileRef>
     7</Workspace>
  • sshnodelay.c

    diff --git a/sshnodelay.c b/sshnodelay.c
    index 7518089..efe393c 100644
    a b  
    55#include <netinet/in.h>
    66#include <netinet/tcp.h>
    77
     8#ifdef __APPLE__
     9
     10int custom_connect(int sock, const struct sockaddr *addr, socklen_t addrlen);
     11
     12typedef struct interpose_s {
     13        void *new_func;
     14        void *orig_func;
     15} interpose_t;
     16
     17static const interpose_t interposers[] \
     18        __attribute__ ((section("__DATA, __interpose"))) = {
     19        { (void *)custom_connect,  (void *)connect  },
     20};
     21
     22int custom_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
     23{
     24        int res = connect(sock, addr, addrlen);
     25        if (!res && addr->sa_family == AF_INET) {
     26                int opt = 1;
     27                setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
     28        }
     29        return res;
     30}
     31
     32#else
     33
    834int connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
    935{
    1036        int (*next_connect)(int, const struct sockaddr *, socklen_t) =
    int connect(int sock, const struct sockaddr *addr, socklen_t addrlen) 
    1642        }
    1743        return res;
    1844}
     45
     46#endif