source: trunk/dports/fuse/sshfs/files/patch-fuse4x-compat.diff @ 81150

Last change on this file since 81150 was 81150, checked in by dports@…, 6 years ago

sshfs: fuse4x compatibility

  • rewrite macfuse dependency to allow fuse4x to satisfy it
  • add patch that uses APPLE instead of (FreeBSD >= 10) to test whether we're on a Mac, and adds a semaphore emulation layer if we're using Fuse4X (MacFUSE provides one of its own)
File size: 15.9 KB
  • 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 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 */
  • a/sshfs.c

    diff --git a/sshfs.c b/sshfs.c
    index 8a8e858..9220b70 100644
    old new  
    1919#include <string.h>
    2020#include <stdint.h>
    2121#include <errno.h>
    22 #if !(__FreeBSD__ >= 10)
    23 #include <semaphore.h>
     22#ifdef __APPLE__
     23/* OS X does not support named semaphores; need some sort of emulation */
     24#if (__FreeBSD__ >= 10)
     25/* MacFUSE provides a semaphore emulation layer */
     26#include <fuse_darwin.h>
    2427#else
    25 #define MACFUSE_SSHFS_VERSION "2.2.0"
    26 #include "fuse_darwin.h"
    27 #endif
     28/* Fuse4X doesn't; use our own */
     29#include "darwin_semaphore.h"
     30#endif  /* (__FreeBSD__ >= 10) */
     31#else
     32#include <semaphore.h>
     33#endif  /* __APPLE__ */
    2834#include <pthread.h>
    2935#include <netdb.h>
    3036#include <signal.h>
     
    3945#include <netinet/in.h>
    4046#include <netinet/tcp.h>
    4147#include <glib.h>
    42 #if (__FreeBSD__ >= 10)
     48#ifdef __APPLE__
    4349#include <libgen.h>
    4450#include <strings.h>
    4551#endif
     
    129135
    130136#define SSHNODELAY_SO "sshnodelay.so"
    131137
    132 #if (__FreeBSD__ >= 10)
     138#ifdef __APPLE__
    133139
    134140#ifndef LIBDIR
    135141#define LIBDIR "/usr/local/lib"
     
    188194        int connver;
    189195        int modifver;
    190196        int refs;
    191 #if (__FreeBSD__ >= 10)
     197#ifdef __APPLE__
    192198        pthread_mutex_t file_lock;
    193199#endif
    194200};
     
    230236        int server_version;
    231237        unsigned remote_uid;
    232238        unsigned local_uid;
    233 #if (__FreeBSD__ >= 10)
     239#ifdef __APPLE__
    234240        unsigned remote_gid;
    235241        unsigned local_gid;
    236242#endif
     
    667673                }
    668674        }
    669675
    670 #if (__FreeBSD__ >= 10)
     676#ifdef __APPLE__
    671677        if (sshfs.remote_uid_detected) {
    672678                if (uid == sshfs.remote_uid)
    673679                        uid = sshfs.local_uid;
     
    780786#ifdef SSH_NODELAY_WORKAROUND
    781787static int do_ssh_nodelay_workaround(void)
    782788{
    783 #if (__FreeBSD__ >= 10)
     789#ifdef __APPLE__
    784790        char *oldpreload = getenv("DYLD_INSERT_LIBRARIES");
    785791#else
    786792        char *oldpreload = getenv("LD_PRELOAD");
     
    789795        char sopath[PATH_MAX];
    790796        int res;
    791797
    792 #if (__FreeBSD__ >= 10)
     798#ifdef __APPLE__
    793799        char *sshfs_program_path_base = NULL;
    794800        if (!sshfs_program_path[0]) {
    795801                goto nobundle;
     
    831837                        return -1;
    832838                }
    833839        }
    834 #if (__FreeBSD__ >= 10)
     840#ifdef __APPLE__
    835841pathok:
    836842#endif
    837843
     
    840846                                     oldpreload ? " " : "",
    841847                                     sopath);
    842848
    843 #if (__FreeBSD__ >= 10)
     849#ifdef __APPLE__
    844850        if (!newpreload || setenv("DYLD_INSERT_LIBRARIES", newpreload, 1) == -1)
    845851                fprintf(stderr, "warning: failed set DYLD_INSERT_LIBRARIES for ssh nodelay workaround\n");
    846852#else
     
    15411547
    15421548        sshfs.remote_uid = stbuf.st_uid;
    15431549        sshfs.local_uid = getuid();
    1544 #if (__FreeBSD__ >= 10)
     1550#ifdef __APPLE__
    15451551        sshfs.remote_gid = stbuf.st_gid;
    15461552        sshfs.local_gid = getgid();
    15471553#endif
     
    21392145        buf_init(&buf, 0);
    21402146        buf_add_path(&buf, path);
    21412147        buf_add_uint32(&buf, SSH_FILEXFER_ATTR_UIDGID);
    2142 #if (__FreeBSD__ >= 10)
     2148#ifdef __APPLE__
    21432149        if (sshfs.remote_uid_detected) {
    21442150                if (uid == sshfs.local_uid)
    21452151                        uid = sshfs.remote_uid;
     
    22302236        sf = g_new0(struct sshfs_file, 1);
    22312237        list_init(&sf->write_reqs);
    22322238        pthread_cond_init(&sf->write_finished, NULL);
    2233 #if (__FreeBSD__ >= 10)
     2239#ifdef __APPLE__
    22342240        pthread_mutex_init(&sf->file_lock, NULL);
    22352241#endif
    22362242        /* Assume random read after open */
     
    22662272        }
    22672273
    22682274        if (!err) {
    2269 #if (__FreeBSD__ >= 10)
     2275#ifdef __APPLE__
    22702276                if (cache_enabled)
    22712277                        cache_add_attr(path, &stbuf, wrctr);
    22722278#else
     
    22752281                buf_finish(&sf->handle);
    22762282                fi->fh = (unsigned long) sf;
    22772283        } else {
    2278 #if (__FreeBSD__ >= 10)
     2284#ifdef __APPLE__
    22792285                if (cache_enabled)
    22802286                        cache_invalidate(path);
    22812287#else
     
    23352341
    23362342static void sshfs_file_put(struct sshfs_file *sf)
    23372343{
    2338 #if (__FreeBSD__ >= 10)
     2344#ifdef __APPLE__
    23392345        pthread_mutex_lock(&sf->file_lock);
    23402346#endif
    23412347        sf->refs--;
    2342 #if (__FreeBSD__ >= 10)
     2348#ifdef __APPLE__
    23432349        if (!sf->refs) {
    23442350                pthread_mutex_unlock(&sf->file_lock);
    23452351                g_free(sf);
     
    23542360
    23552361static void sshfs_file_get(struct sshfs_file *sf)
    23562362{
    2357 #if (__FreeBSD__ >= 10)
     2363#ifdef __APPLE__
    23582364        pthread_mutex_lock(&sf->file_lock);
    23592365#endif
    23602366        sf->refs++;
    2361 #if (__FreeBSD__ >= 10)
     2367#ifdef __APPLE__
    23622368        pthread_mutex_unlock(&sf->file_lock);
    23632369#endif
    23642370}
     
    30503056                exit(1);
    30513057
    30523058        case KEY_VERSION:
    3053 #if (__FreeBSD__ >= 10)
    3054                 fprintf(stderr, "SSHFS version %s (MacFUSE SSHFS %s)\n",
    3055                         PACKAGE_VERSION, MACFUSE_SSHFS_VERSION);
    3056 #else
    30573059                fprintf(stderr, "SSHFS version %s\n", PACKAGE_VERSION);
    3058 #endif
    30593060#if FUSE_VERSION >= 25
    30603061                fuse_opt_add_arg(outargs, "--version");
    30613062                sshfs_fuse_main(outargs);
     
    31393140                perror("Failed to allocate locked page for password");
    31403141                return -1;
    31413142        }
    3142 #if (__FreeBSD__ >= 10)
     3143#ifdef __APPLE__
    31433144        if (mlock(sshfs.password, size) != 0) {
    31443145                memset(sshfs.password, 0, size);
    31453146                munmap(sshfs.password, size);
     
    31473148                perror("Failed to allocate locked page for password");
    31483149                return -1;
    31493150        }
    3150 #endif /* __FreeBSD__ >= 10 */
     3151#endif /* __APPLE__ */
    31513152
    31523153        /* Don't use fgets() because password might stay in memory */
    31533154        for (n = 0; n < max_password; n++) {
     
    32793280}
    32803281#endif
    32813282
    3282 #if (__FreeBSD__ >= 10)
     3283#ifdef __APPLE__
    32833284int main(int argc, char *argv[], __unused char *envp[], char **exec_path)
    32843285#else
    32853286int main(int argc, char *argv[])
    32863287#endif
    32873288{
    3288 #if (__FreeBSD__ >= 10)
     3289#ifdef __APPLE__
    32893290        if (!realpath(*exec_path, sshfs_program_path)) {
    32903291                memset(sshfs_program_path, 0, PATH_MAX);
    32913292        }
     
    32983299        const char *sftp_server;
    32993300        int libver;
    33003301
    3301 #if (__FreeBSD__ >= 10)
     3302#ifdef __APPLE__
    33023303        /* Until this gets fixed somewhere else. */
    33033304        g_slice_set_config(G_SLICE_CONFIG_ALWAYS_MALLOC, TRUE);
    3304 #endif /* __FreeBSD__ >= 10 */
     3305#endif /* __APPLE__ */
    33053306        g_thread_init(NULL);
    33063307
    33073308        sshfs.blksize = 4096;
     
    33093310        sshfs.max_write = 65536;
    33103311        sshfs.nodelay_workaround = 1;
    33113312        sshfs.nodelaysrv_workaround = 0;
    3312 #if (__FreeBSD__ >= 10)
     3313#ifdef __APPLE__
    33133314        sshfs.rename_workaround = 1;
    33143315#else
    33153316        sshfs.rename_workaround = 0;
    3316 #endif /* __FreeBSD__ >= 10 */
     3317#endif /* __APPLE__ */
    33173318        sshfs.truncate_workaround = 0;
    33183319        sshfs.buflimit_workaround = 1;
    33193320        sshfs.ssh_ver = 2;
     
    33263327        ssh_add_arg("-a");
    33273328        ssh_add_arg("-oClearAllForwardings=yes");
    33283329
    3329 #if (__FreeBSD__ >= 10)
     3330#ifdef __APPLE__
    33303331        sshfs.detect_uid = 1;
    33313332#endif
    33323333
  • sshfs-fuse-2.2/cache.h

    old new  
    2828void cache_invalidate(const char *path);
    2929uint64_t cache_get_write_ctr(void);
    3030
    31 #if (__FreeBSD__ >= 10)
     31#ifdef __APPLE__
    3232extern int cache_enabled;
    3333#endif
  • sshfs-fuse-2.2/cache.c

    old new  
    559559        cache.next_oper = oper;
    560560
    561561        cache_unity_fill(oper, &cache_oper);
    562 #if (__FreeBSD__ >= 10)
     562#ifdef __APPLE__
    563563        cache_enabled = cache.on;
    564564#endif
    565565        if (cache.on) {
     
    597597        return fuse_opt_parse(args, &cache, cache_opts, NULL);
    598598}
    599599
    600 #if (__FreeBSD__ >= 10)
     600#ifdef __APPLE__
    601601int cache_enabled;
    602602#endif
Note: See TracBrowser for help on using the repository browser.