From bef5ba7f3b65eeb34a95561ae9b6939e206ef68e Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 31 Jul 2018 21:02:46 -0700 Subject: [PATCH] dll: fuse: fix daemonization problem on Cygwin The new FUSE loop use a Windows event (LoopEvent) to signal loop exit. Prior to this commit the Windows event was created outside the FUSE loop and potentially before daemonization (on Cygwin). This means that the event was created in a different process and WaitForMultipleObjects was failing with ERROR_ACCESS_DENIED. This commit ensures that the LoopEvent is created inside the FUSE loop and therefore in the daemonized process. --- src/dll/fuse/fuse.c | 10 ++-------- src/dll/fuse/fuse_loop.c | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index 86ce2e48..6a08197b 100644 --- a/src/dll/fuse/fuse.c +++ b/src/dll/fuse/fuse.c @@ -430,10 +430,6 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, goto fail; memcpy(f->MountPoint, ch->MountPoint, Size); - f->LoopEvent = CreateEventW(0, TRUE, FALSE, 0); - if (0 == f->LoopEvent) - goto fail; - Result = FspFileSystemPreflight( f->VolumeParams.Prefix[0] ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME, '*' != f->MountPoint[0] || '\0' != f->MountPoint[1] ? f->MountPoint : 0); @@ -481,9 +477,6 @@ fail: FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env, struct fuse *f) { - if (0 != f->LoopEvent) - CloseHandle(f->LoopEvent); - fsp_fuse_obj_free(f->MountPoint); fsp_fuse_obj_free(f); @@ -492,7 +485,8 @@ FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env, FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env, struct fuse *f) { - SetEvent(f->LoopEvent); + if (0 != f->LoopEvent) + SetEvent(f->LoopEvent); f->exited = 1; } diff --git a/src/dll/fuse/fuse_loop.c b/src/dll/fuse/fuse_loop.c index 1dd13119..96ba3c7e 100644 --- a/src/dll/fuse/fuse_loop.c +++ b/src/dll/fuse/fuse_loop.c @@ -53,6 +53,10 @@ static NTSTATUS fsp_fuse_loop_start(struct fuse *f) struct fuse_conn_info conn; NTSTATUS Result; + f->LoopEvent = CreateEventW(0, TRUE, FALSE, 0); + if (0 == f->LoopEvent) + goto fail; + context = fsp_fuse_get_context(f->env); if (0 == context) { @@ -239,6 +243,12 @@ static void fsp_fuse_loop_cleanup(struct fuse *f) f->ops.destroy(f->data); f->fsinit = FALSE; } + + if (0 != f->LoopEvent) + { + CloseHandle(f->LoopEvent); + f->LoopEvent = 0; + } } static NTSTATUS fsp_fuse_loop_internal(struct fuse *f) @@ -264,11 +274,15 @@ static NTSTATUS fsp_fuse_loop_internal(struct fuse *f) } /* if either the service thread dies or our event gets signaled, stop the loop */ - WaitObjects[0] = fsp_fuse_svcthread; - WaitObjects[1] = f->LoopEvent; - WaitResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE); - if (WAIT_OBJECT_0 != WaitResult && WAIT_OBJECT_0 + 1 != WaitResult) - Result = FspNtStatusFromWin32(GetLastError()); + Result = STATUS_SUCCESS; + if (!f->exited) + { + WaitObjects[0] = fsp_fuse_svcthread; + WaitObjects[1] = f->LoopEvent; + WaitResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE); + if (WAIT_OBJECT_0 != WaitResult && WAIT_OBJECT_0 + 1 != WaitResult) + Result = FspNtStatusFromWin32(GetLastError()); + } fsp_fuse_loop_stop(f);