mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
opt: cygfuse: rename cygfuse.cpp to cygfuse.c and fix fork problem
This commit is contained in:
parent
8c1c407b34
commit
f2a0eb544e
@ -1,8 +1,8 @@
|
|||||||
Version = $(shell sed -n '/^VERSION=/s/VERSION=\(.*\)/\1/p' fuse.cygport)
|
Version = $(shell sed -n '/^VERSION=/s/VERSION=\(.*\)/\1/p' fuse.cygport)
|
||||||
#Debug = -g
|
#Debug = -g
|
||||||
|
|
||||||
cygfuse-$(Version).dll libfuse-$(Version).dll.a fuse.pc: cygfuse.cpp fuse.pc.in
|
cygfuse-$(Version).dll libfuse-$(Version).dll.a fuse.pc: cygfuse.c fuse.pc.in
|
||||||
g++ $(Debug) -shared -o cygfuse-$(Version).dll -Wl,--out-implib=libfuse-$(Version).dll.a -I../../inc/fuse cygfuse.cpp
|
gcc $(Debug) -shared -o cygfuse-$(Version).dll -Wl,--out-implib=libfuse-$(Version).dll.a -I../../inc/fuse cygfuse.c
|
||||||
[ -n "$(Debug)" ] || strip cygfuse-$(Version).dll
|
[ -n "$(Debug)" ] || strip cygfuse-$(Version).dll
|
||||||
sed "s/@Version@/$(Version)/g" fuse.pc.in > fuse.pc
|
sed "s/@Version@/$(Version)/g" fuse.pc.in > fuse.pc
|
||||||
|
|
||||||
|
146
opt/cygfuse/cygfuse.c
Normal file
146
opt/cygfuse/cygfuse.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
* @file cygfuse/cygfuse.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Affero General Public License version 3 as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this file in
|
||||||
|
* accordance with the commercial license agreement provided with the
|
||||||
|
* software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/cygwin.h>
|
||||||
|
|
||||||
|
static void *cygfuse_init_winfsp();
|
||||||
|
static void *cygfuse_init_fail();
|
||||||
|
|
||||||
|
static pthread_mutex_t cygfuse_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static void *cygfuse_handle = 0;
|
||||||
|
|
||||||
|
static inline void cygfuse_init(int force)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&cygfuse_mutex);
|
||||||
|
if (force || 0 == cygfuse_handle)
|
||||||
|
cygfuse_handle = cygfuse_init_winfsp();
|
||||||
|
pthread_mutex_unlock(&cygfuse_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unfortunately Cygwin fork is very fragile and cannot even correctly
|
||||||
|
* handle dlopen'ed DLL's if they are native (rather than Cygwin ones).
|
||||||
|
*
|
||||||
|
* So we have this very nasty hack where we reset the dlopen'ed handle
|
||||||
|
* immediately after daemonization. This will force cygfuse_init() to
|
||||||
|
* reload the WinFsp DLL and reset all API pointers in the daemonized
|
||||||
|
* process.
|
||||||
|
*/
|
||||||
|
static inline int cygfuse_daemon(int nochdir, int noclose)
|
||||||
|
{
|
||||||
|
if (-1 == daemon(nochdir, noclose))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* force reload of WinFsp DLL to workaround fork() problems */
|
||||||
|
cygfuse_init(1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#define daemon cygfuse_daemon
|
||||||
|
|
||||||
|
#define FSP_FUSE_API static
|
||||||
|
#define FSP_FUSE_API_NAME(api) (* pfn_ ## api)
|
||||||
|
#define FSP_FUSE_API_CALL(api) (cygfuse_init(0), pfn_ ## api)
|
||||||
|
#define FSP_FUSE_SYM(proto, ...) __attribute__ ((visibility("default"))) proto { __VA_ARGS__ }
|
||||||
|
#include <fuse_common.h>
|
||||||
|
#include <fuse.h>
|
||||||
|
#include <fuse_opt.h>
|
||||||
|
|
||||||
|
#if defined(__LP64__)
|
||||||
|
#define CYGFUSE_WINFSP_NAME "winfsp-x64.dll"
|
||||||
|
#else
|
||||||
|
#define CYGFUSE_WINFSP_NAME "winfsp-x86.dll"
|
||||||
|
#endif
|
||||||
|
#define CYGFUSE_WINFSP_PATH "bin\\" CYGFUSE_WINFSP_NAME
|
||||||
|
#define CYGFUSE_GET_API(h, n) \
|
||||||
|
if (0 == (*(void **)&(pfn_ ## n) = dlsym(h, #n)))\
|
||||||
|
return cygfuse_init_fail();
|
||||||
|
|
||||||
|
static void *cygfuse_init_winfsp()
|
||||||
|
{
|
||||||
|
void *h;
|
||||||
|
|
||||||
|
h = dlopen(CYGFUSE_WINFSP_NAME, RTLD_NOW);
|
||||||
|
if (0 == h)
|
||||||
|
{
|
||||||
|
char winpath[260], *psxpath;
|
||||||
|
int regfd, bytes;
|
||||||
|
|
||||||
|
regfd = open("/proc/registry32/HKEY_LOCAL_MACHINE/Software/WinFsp/InstallDir", O_RDONLY);
|
||||||
|
if (-1 == regfd)
|
||||||
|
return cygfuse_init_fail();
|
||||||
|
|
||||||
|
bytes = read(regfd, winpath, sizeof winpath - sizeof CYGFUSE_WINFSP_PATH);
|
||||||
|
close(regfd);
|
||||||
|
if (-1 == bytes || 0 == bytes)
|
||||||
|
return cygfuse_init_fail();
|
||||||
|
|
||||||
|
if ('\0' == winpath[bytes - 1])
|
||||||
|
bytes--;
|
||||||
|
memcpy(winpath + bytes, CYGFUSE_WINFSP_PATH, sizeof CYGFUSE_WINFSP_PATH);
|
||||||
|
|
||||||
|
psxpath = (char *)cygwin_create_path(CCP_WIN_A_TO_POSIX | CCP_PROC_CYGDRIVE, winpath);
|
||||||
|
if (0 == psxpath)
|
||||||
|
return cygfuse_init_fail();
|
||||||
|
|
||||||
|
h = dlopen(psxpath, RTLD_NOW);
|
||||||
|
free(psxpath);
|
||||||
|
if (0 == h)
|
||||||
|
return cygfuse_init_fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* winfsp_fuse.h */
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_signal_handler);
|
||||||
|
|
||||||
|
/* fuse_common.h */
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_version);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_mount);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_unmount);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_parse_cmdline);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_ntstatus_from_errno);
|
||||||
|
|
||||||
|
/* fuse.h */
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_main_real);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_is_lib_option);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_new);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_destroy);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_loop);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_loop_mt);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_exit);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_get_context);
|
||||||
|
|
||||||
|
/* fuse_opt.h */
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_opt_parse);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_opt_add_arg);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_opt_insert_arg);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_opt_free_args);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_opt_add_opt);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_opt_add_opt_escaped);
|
||||||
|
CYGFUSE_GET_API(h, fsp_fuse_opt_match);
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *cygfuse_init_fail()
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,122 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file cygfuse/cygfuse.cpp
|
|
||||||
*
|
|
||||||
* @copyright 2015-2016 Bill Zissimopoulos
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of WinFsp.
|
|
||||||
*
|
|
||||||
* You can redistribute it and/or modify it under the terms of the
|
|
||||||
* GNU Affero General Public License version 3 as published by the
|
|
||||||
* Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Licensees holding a valid commercial license may use this file in
|
|
||||||
* accordance with the commercial license agreement provided with the
|
|
||||||
* software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#undef _WIN32
|
|
||||||
#undef _WIN64
|
|
||||||
|
|
||||||
static HANDLE cygfuse_init_winfsp();
|
|
||||||
static HANDLE cygfuse_init_fail(int err);
|
|
||||||
static inline void cygfuse_init()
|
|
||||||
{
|
|
||||||
static HANDLE Handle = cygfuse_init_winfsp();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FSP_FUSE_API static
|
|
||||||
#define FSP_FUSE_API_NAME(api) (* pfn_ ## api)
|
|
||||||
#define FSP_FUSE_API_CALL(api) (cygfuse_init(), pfn_ ## api)
|
|
||||||
#define FSP_FUSE_SYM(proto, ...) __attribute__ ((visibility("default"))) proto { __VA_ARGS__ }
|
|
||||||
#include <fuse_common.h>
|
|
||||||
#include <fuse.h>
|
|
||||||
#include <fuse_opt.h>
|
|
||||||
|
|
||||||
#if defined(__LP64__)
|
|
||||||
#define CYGFUSE_WINFSP_NAME "winfsp-x64.dll"
|
|
||||||
#else
|
|
||||||
#define CYGFUSE_WINFSP_NAME "winfsp-x86.dll"
|
|
||||||
#endif
|
|
||||||
#define CYGFUSE_WINFSP_PATH "bin\\" CYGFUSE_WINFSP_NAME
|
|
||||||
#define CYGFUSE_API_GET(h, n) \
|
|
||||||
if (0 == (*(FARPROC *)&(pfn_ ## n) = GetProcAddress((HMODULE)h, #n)))\
|
|
||||||
return cygfuse_init_fail(ERROR_PROC_NOT_FOUND);
|
|
||||||
|
|
||||||
static HANDLE cygfuse_init_fail(int err)
|
|
||||||
{
|
|
||||||
//RaiseException(ERROR_SEVERITY_ERROR | (109/*FACILITY_VISUALCPP*/ << 16) | err, 0, 0, 0);
|
|
||||||
abort();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HANDLE cygfuse_init_winfsp()
|
|
||||||
{
|
|
||||||
HANDLE Handle;
|
|
||||||
|
|
||||||
Handle = LoadLibraryW(L"" CYGFUSE_WINFSP_NAME);
|
|
||||||
if (0 == Handle)
|
|
||||||
{
|
|
||||||
HKEY RegKey;
|
|
||||||
DWORD RegResult, RegType;
|
|
||||||
WCHAR Path[MAX_PATH];
|
|
||||||
DWORD Size;
|
|
||||||
|
|
||||||
Size = sizeof(Path);
|
|
||||||
if (ERROR_SUCCESS == (RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
||||||
L"Software\\WinFsp", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &RegKey)))
|
|
||||||
{
|
|
||||||
RegResult = RegQueryValueExW(RegKey, L"InstallDir", 0, &RegType, (PBYTE)Path, &Size);
|
|
||||||
RegCloseKey(RegKey);
|
|
||||||
}
|
|
||||||
if (ERROR_SUCCESS != RegResult)
|
|
||||||
return cygfuse_init_fail(ERROR_MOD_NOT_FOUND);
|
|
||||||
|
|
||||||
Size /= sizeof(WCHAR);
|
|
||||||
if (Size >= MAX_PATH)
|
|
||||||
Size = MAX_PATH - 1;
|
|
||||||
Path[Size] = L'\0';
|
|
||||||
|
|
||||||
Size = lstrlenW(Path);
|
|
||||||
if (Size * sizeof(WCHAR) + sizeof L"" CYGFUSE_WINFSP_PATH > MAX_PATH * sizeof(WCHAR))
|
|
||||||
return cygfuse_init_fail(ERROR_MOD_NOT_FOUND);
|
|
||||||
|
|
||||||
memcpy(Path + Size, L"" CYGFUSE_WINFSP_PATH, sizeof L"" CYGFUSE_WINFSP_PATH);
|
|
||||||
|
|
||||||
Handle = LoadLibraryW(Path);
|
|
||||||
if (0 == Handle)
|
|
||||||
return cygfuse_init_fail(ERROR_MOD_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* winfsp_fuse.h */
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_signal_handler);
|
|
||||||
|
|
||||||
/* fuse_common.h */
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_version);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_mount);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_unmount);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_parse_cmdline);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_ntstatus_from_errno);
|
|
||||||
|
|
||||||
/* fuse.h */
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_main_real);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_is_lib_option);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_new);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_destroy);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_loop);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_loop_mt);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_exit);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_get_context);
|
|
||||||
|
|
||||||
/* fuse_opt.h */
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_opt_parse);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_opt_add_arg);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_opt_insert_arg);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_opt_free_args);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_opt_add_opt);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_opt_add_opt_escaped);
|
|
||||||
CYGFUSE_API_GET(Handle, fsp_fuse_opt_match);
|
|
||||||
|
|
||||||
return Handle;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user