lib/librefuse: Implement FUSE session API and its signal handling functionality
This commit is contained in:
parent
153b9c141b
commit
9f39150738
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: mi,v 1.1287 2022/01/10 10:02:30 martin Exp $
|
# $NetBSD: mi,v 1.1288 2022/01/22 07:53:05 pho Exp $
|
||||||
#
|
#
|
||||||
# Note: Don't delete entries from here - mark them as "obsolete" instead,
|
# Note: Don't delete entries from here - mark them as "obsolete" instead,
|
||||||
# unless otherwise stated below.
|
# unless otherwise stated below.
|
||||||
|
@ -1147,6 +1147,7 @@
|
||||||
./usr/include/protocols base-c-usr
|
./usr/include/protocols base-c-usr
|
||||||
./usr/include/quota base-obsolete obsolete
|
./usr/include/quota base-obsolete obsolete
|
||||||
./usr/include/readline base-c-usr
|
./usr/include/readline base-c-usr
|
||||||
|
./usr/include/refuse base-refuse-usr
|
||||||
./usr/include/rpc base-c-usr
|
./usr/include/rpc base-c-usr
|
||||||
./usr/include/rpcsvc base-c-usr
|
./usr/include/rpcsvc base-c-usr
|
||||||
./usr/include/rump base-c-usr
|
./usr/include/rump base-c-usr
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: mi,v 1.2404 2022/01/22 07:38:45 pho Exp $
|
# $NetBSD: mi,v 1.2405 2022/01/22 07:53:05 pho Exp $
|
||||||
#
|
#
|
||||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||||
./etc/mtree/set.comp comp-sys-root
|
./etc/mtree/set.comp comp-sys-root
|
||||||
|
@ -3092,6 +3092,7 @@
|
||||||
./usr/include/readline.h comp-obsolete obsolete
|
./usr/include/readline.h comp-obsolete obsolete
|
||||||
./usr/include/readline/history.h comp-c-include
|
./usr/include/readline/history.h comp-c-include
|
||||||
./usr/include/readline/readline.h comp-c-include
|
./usr/include/readline/readline.h comp-c-include
|
||||||
|
./usr/include/refuse/session.h comp-refuse-include
|
||||||
./usr/include/regex.h comp-c-include
|
./usr/include/regex.h comp-c-include
|
||||||
./usr/include/regexp.h comp-c-include
|
./usr/include/regexp.h comp-c-include
|
||||||
./usr/include/res_update.h comp-c-include
|
./usr/include/res_update.h comp-c-include
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: NetBSD.dist.base,v 1.240 2021/12/13 23:59:35 maya Exp $
|
# $NetBSD: NetBSD.dist.base,v 1.241 2022/01/22 07:53:06 pho Exp $
|
||||||
# @(#)4.4BSD.dist 8.1 (Berkeley) 6/13/93
|
# @(#)4.4BSD.dist 8.1 (Berkeley) 6/13/93
|
||||||
|
|
||||||
# Do not customize this file as it may be overwritten on upgrades.
|
# Do not customize this file as it may be overwritten on upgrades.
|
||||||
|
@ -326,6 +326,7 @@
|
||||||
./usr/include/prop
|
./usr/include/prop
|
||||||
./usr/include/protocols
|
./usr/include/protocols
|
||||||
./usr/include/readline
|
./usr/include/readline
|
||||||
|
./usr/include/refuse
|
||||||
./usr/include/rpc
|
./usr/include/rpc
|
||||||
./usr/include/rpcsvc
|
./usr/include/rpcsvc
|
||||||
./usr/include/rump
|
./usr/include/rump
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: Makefile,v 1.13 2022/01/22 07:38:45 pho Exp $
|
# $NetBSD: Makefile,v 1.14 2022/01/22 07:53:06 pho Exp $
|
||||||
|
|
||||||
USE_FORT?= yes # data driven bugs?
|
USE_FORT?= yes # data driven bugs?
|
||||||
|
|
||||||
|
@ -13,10 +13,12 @@ FUSE_OPT_DEBUG_FLAGS= -g -DFUSE_OPT_DEBUG
|
||||||
CFLAGS+= ${FUSE_OPT_DEBUG_FLAGS}
|
CFLAGS+= ${FUSE_OPT_DEBUG_FLAGS}
|
||||||
CPPFLAGS+= -I${.CURDIR}
|
CPPFLAGS+= -I${.CURDIR}
|
||||||
SRCS= refuse.c refuse_log.c refuse_lowlevel.c
|
SRCS= refuse.c refuse_log.c refuse_lowlevel.c
|
||||||
SRCS+= refuse_opt.c
|
SRCS+= refuse_opt.c refuse_signals.c
|
||||||
MAN= refuse.3
|
MAN= refuse.3
|
||||||
WARNS?= 5
|
WARNS?= 5
|
||||||
INCS= fuse.h fuse_opt.h fuse_log.h fuse_lowlevel.h
|
INCS= fuse.h fuse_opt.h fuse_log.h fuse_lowlevel.h
|
||||||
INCSDIR= /usr/include
|
INCSDIR= /usr/include
|
||||||
|
|
||||||
|
.include "${.CURDIR}/refuse/Makefile.inc"
|
||||||
|
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fuse.h,v 1.24 2021/12/04 06:42:39 pho Exp $ */
|
/* $NetBSD: fuse.h,v 1.25 2022/01/22 07:53:06 pho Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright © 2007 Alistair Crooks. All rights reserved.
|
* Copyright © 2007 Alistair Crooks. All rights reserved.
|
||||||
|
@ -30,9 +30,11 @@
|
||||||
#ifndef FUSE_H_
|
#ifndef FUSE_H_
|
||||||
#define FUSE_H_ 20211204
|
#define FUSE_H_ 20211204
|
||||||
|
|
||||||
|
#include <refuse/session.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <puffs.h>
|
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
|
|
||||||
/* The latest version of FUSE API currently provided by refuse. */
|
/* The latest version of FUSE API currently provided by refuse. */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fuse_internal.h,v 1.1 2021/12/04 06:42:39 pho Exp $ */
|
/* $NetBSD: fuse_internal.h,v 1.2 2022/01/22 07:53:06 pho Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 The NetBSD Foundation, Inc.
|
* Copyright (c) 2021 The NetBSD Foundation, Inc.
|
||||||
|
@ -38,5 +38,20 @@
|
||||||
|
|
||||||
#include <fuse.h>
|
#include <fuse.h>
|
||||||
#include <fuse_lowlevel.h>
|
#include <fuse_lowlevel.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Internal functions, hidden from users */
|
||||||
|
__BEGIN_HIDDEN_DECLS
|
||||||
|
int __fuse_set_signal_handlers(struct fuse* fuse);
|
||||||
|
int __fuse_remove_signal_handlers(struct fuse* fuse);
|
||||||
|
__END_HIDDEN_DECLS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: refuse.c,v 1.103 2021/12/04 06:42:39 pho Exp $ */
|
/* $NetBSD: refuse.c,v 1.104 2022/01/22 07:53:06 pho Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright © 2007 Alistair Crooks. All rights reserved.
|
* Copyright © 2007 Alistair Crooks. All rights reserved.
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#if !defined(lint)
|
#if !defined(lint)
|
||||||
__RCSID("$NetBSD: refuse.c,v 1.103 2021/12/04 06:42:39 pho Exp $");
|
__RCSID("$NetBSD: refuse.c,v 1.104 2022/01/22 07:53:06 pho Exp $");
|
||||||
#endif /* !lint */
|
#endif /* !lint */
|
||||||
|
|
||||||
/* We emit a compiler warning for anyone including <fuse.h> without
|
/* We emit a compiler warning for anyone including <fuse.h> without
|
||||||
|
@ -47,6 +47,8 @@ __RCSID("$NetBSD: refuse.c,v 1.103 2021/12/04 06:42:39 pho Exp $");
|
||||||
#include <fuse_internal.h>
|
#include <fuse_internal.h>
|
||||||
#include <fuse_opt.h>
|
#include <fuse_opt.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
|
#include <puffs.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# $NetBSD: Makefile.inc,v 1.1 2022/01/22 07:53:06 pho Exp $
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR}/refuse
|
||||||
|
|
||||||
|
SRCS+= session.c
|
||||||
|
|
||||||
|
INCS+= refuse/session.h
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* $NetBSD: session.c,v 1.1 2022/01/22 07:53:06 pho Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if !defined(lint)
|
||||||
|
__RCSID("$NetBSD: session.c,v 1.1 2022/01/22 07:53:06 pho Exp $");
|
||||||
|
#endif /* !lint */
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <fuse_internal.h>
|
||||||
|
#include <puffs.h>
|
||||||
|
|
||||||
|
/* The documentation for FUSE is not clear as to what "struct fuse_session" is,
|
||||||
|
* why it exists, or how it's different from "struct fuse". For now we leave it
|
||||||
|
* undefined (i.e. an incomplete type) and treat "struct fuse_session *" as
|
||||||
|
* being identical to "struct fuse *". */
|
||||||
|
|
||||||
|
struct fuse_session *
|
||||||
|
fuse_get_session(struct fuse *f) {
|
||||||
|
return (struct fuse_session*)f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_session_fd(struct fuse_session *se) {
|
||||||
|
struct fuse* fuse = (struct fuse*)se;
|
||||||
|
|
||||||
|
/* We don't want to expose this to users, but filesystems in the wild often
|
||||||
|
* wants to set FD_CLOEXEC on it. Hope they don't assume it's the real
|
||||||
|
* /dev/fuse, because it's actually /dev/puffs in our implementation. */
|
||||||
|
return puffs_getselectable(fuse->pu);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_set_signal_handlers(struct fuse_session *se) {
|
||||||
|
return __fuse_set_signal_handlers((struct fuse*)se);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fuse_remove_signal_handlers(struct fuse_session *se) {
|
||||||
|
if (__fuse_remove_signal_handlers((struct fuse*)se) == -1)
|
||||||
|
warn("%s: failed to remove signal handlers", __func__);
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* $NetBSD: session.h,v 1.1 2022/01/22 07:53:06 pho Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#if !defined(_FUSE_SESSION_H_)
|
||||||
|
#define _FUSE_SESSION_H_
|
||||||
|
|
||||||
|
/* FUSE session API
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(FUSE_H_)
|
||||||
|
# error Do not include this header directly. Include <fuse.h> instead.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
struct fuse;
|
||||||
|
|
||||||
|
/* A private structure appeared on FUSE 2.4. */
|
||||||
|
struct fuse_session;
|
||||||
|
|
||||||
|
/* Get a session from a fuse object. Appeared on FUSE 2.6. */
|
||||||
|
struct fuse_session *fuse_get_session(struct fuse *f);
|
||||||
|
|
||||||
|
/* Get the file descriptor for communicaiton with kernel. Appeared on
|
||||||
|
* FUSE 3.0. */
|
||||||
|
int fuse_session_fd(struct fuse_session *se);
|
||||||
|
|
||||||
|
/* Exit a session on SIGHUP, SIGTERM, and SIGINT and ignore
|
||||||
|
* SIGPIPE. Appeared on FUSE 2.5. */
|
||||||
|
int fuse_set_signal_handlers(struct fuse_session *se);
|
||||||
|
|
||||||
|
/* Restore default signal handlers. Appeared on FUSE 2.5. */
|
||||||
|
void fuse_remove_signal_handlers(struct fuse_session *se);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,331 @@
|
||||||
|
/* $NetBSD: refuse_signals.c,v 1.1 2022/01/22 07:53:06 pho Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if !defined(lint)
|
||||||
|
__RCSID("$NetBSD: refuse_signals.c,v 1.1 2022/01/22 07:53:06 pho Exp $");
|
||||||
|
#endif /* !lint */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fuse_internal.h>
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
# include <pthread.h>
|
||||||
|
#endif
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Signal handling routines
|
||||||
|
*
|
||||||
|
* FUSE only supports running a single filesystem per process. ReFUSE
|
||||||
|
* is going to allow a process to run a filesystem per thread. In
|
||||||
|
* order to support this, our implementation of
|
||||||
|
* fuse_set_signal_handlers() installs a set of signal handlers which,
|
||||||
|
* when invoked, terminates all the filesystems that called the
|
||||||
|
* function. This means our fuse_remove_signal_handlers() must not
|
||||||
|
* actually remove the signal handlers until the last thread calls the
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* FUSE installs a signal handler for a signal only if its sa_handler
|
||||||
|
* is set to SIG_DFL. This obviously has a bad consequence: if the
|
||||||
|
* caller process already has a non-default signal handler for SIGINT,
|
||||||
|
* Ctrl-C will not stop the main loop of FUSE. See
|
||||||
|
* https://stackoverflow.com/q/5044375/3571336
|
||||||
|
*
|
||||||
|
* Maybe we should do the same knowing it's bad, but it's probably
|
||||||
|
* better to call our handler along with the old one. We may change
|
||||||
|
* this behavior if this turns out to cause serious compatibility
|
||||||
|
* issues.
|
||||||
|
*
|
||||||
|
* Also note that it is tempting to use puffs_unmountonsignal(3) but
|
||||||
|
* we can't, because there is no way to revert its effect.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
/* A mutex to protect the global state regarding signal handlers. When
|
||||||
|
* a thread is going to lock this, it must block all the signals (with
|
||||||
|
* pthread_sigmask(3)) that we install a handler for, or otherwise it
|
||||||
|
* may deadlock for trying to acquire a lock that is already held by
|
||||||
|
* itself. */
|
||||||
|
static pthread_mutex_t signal_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Saved sigaction for each signal before we modify them. */
|
||||||
|
static struct sigaction* saved_actions[NSIG];
|
||||||
|
|
||||||
|
/* A linked list of "struct fuse*" which should be terminated upon
|
||||||
|
* receiving a signal. */
|
||||||
|
struct refuse_obj_elem {
|
||||||
|
struct fuse* fuse;
|
||||||
|
struct refuse_obj_elem* next;
|
||||||
|
};
|
||||||
|
static struct refuse_obj_elem* fuse_head;
|
||||||
|
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
static int
|
||||||
|
block_signals(sigset_t* oset) {
|
||||||
|
sigset_t set;
|
||||||
|
|
||||||
|
if (sigemptyset(&set) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sigaddset(&set, SIGHUP) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sigaddset(&set, SIGINT) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sigaddset(&set, SIGTERM) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return pthread_sigmask(SIG_BLOCK, &set, oset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
unblock_signals(const sigset_t* oset) {
|
||||||
|
return pthread_sigmask(SIG_SETMASK, oset, NULL);
|
||||||
|
}
|
||||||
|
#endif /* defined(MULTITHREADED_REFUSE) */
|
||||||
|
|
||||||
|
/* handler == NULL means the signal should be ignored. */
|
||||||
|
static int
|
||||||
|
set_signal_handler(int sig, void (*handler)(int, siginfo_t*, void*)) {
|
||||||
|
struct sigaction* saved;
|
||||||
|
struct sigaction act;
|
||||||
|
|
||||||
|
saved = malloc(sizeof(*saved));
|
||||||
|
if (!saved)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sigaction(sig, NULL, saved) != 0) {
|
||||||
|
free(saved);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
saved_actions[sig] = saved;
|
||||||
|
|
||||||
|
memset(&act, 0, sizeof(act));
|
||||||
|
if (handler) {
|
||||||
|
act.sa_sigaction = handler;
|
||||||
|
act.sa_flags = SA_SIGINFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Ignore the signal only if the signal doesn't have a
|
||||||
|
* handler. */
|
||||||
|
if (!(saved->sa_flags & SA_SIGINFO) && saved->sa_handler == SIG_DFL)
|
||||||
|
act.sa_handler = SIG_IGN;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigemptyset(&act.sa_mask) != 0) {
|
||||||
|
free(saved);
|
||||||
|
saved_actions[sig] = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sigaction(sig, &act, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
restore_signal_handler(int sig, void (*handler)(int, siginfo_t*, void*)) {
|
||||||
|
struct sigaction oact;
|
||||||
|
struct sigaction* saved;
|
||||||
|
|
||||||
|
saved = saved_actions[sig];
|
||||||
|
assert(saved != NULL);
|
||||||
|
|
||||||
|
if (sigaction(sig, NULL, &oact) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Has the sigaction changed since we installed our handler? Do
|
||||||
|
* nothing if so. */
|
||||||
|
if (handler) {
|
||||||
|
if (!(oact.sa_flags & SA_SIGINFO) || oact.sa_sigaction != handler)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (oact.sa_handler != SIG_IGN)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigaction(sig, saved, NULL) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
done:
|
||||||
|
free(saved);
|
||||||
|
saved_actions[sig] = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
exit_handler(int sig, siginfo_t* info, void* ctx) {
|
||||||
|
struct refuse_obj_elem* elem;
|
||||||
|
struct sigaction* saved;
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
/* pthread_mutex_lock(3) is NOT an async-signal-safe function. We
|
||||||
|
* assume it's okay, as the thread running this handler shouldn't
|
||||||
|
* be locking this mutex. */
|
||||||
|
rv = pthread_mutex_lock(&signal_mutex);
|
||||||
|
assert(rv == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (elem = fuse_head; elem != NULL; elem = elem->next)
|
||||||
|
fuse_exit(elem->fuse);
|
||||||
|
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
rv = pthread_mutex_unlock(&signal_mutex);
|
||||||
|
assert(rv == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
saved = saved_actions[sig];
|
||||||
|
assert(saved != NULL);
|
||||||
|
|
||||||
|
if (saved->sa_handler != SIG_DFL && saved->sa_handler != SIG_IGN) {
|
||||||
|
if (saved->sa_flags & SA_SIGINFO)
|
||||||
|
saved->sa_sigaction(sig, info, ctx);
|
||||||
|
else
|
||||||
|
saved->sa_handler(sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The original function appeared on FUSE 2.5 takes a pointer to
|
||||||
|
* "struct fuse_session" instead of "struct fuse". We have no such
|
||||||
|
* things as fuse sessions.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__fuse_set_signal_handlers(struct fuse* fuse) {
|
||||||
|
int ret = 0;
|
||||||
|
struct refuse_obj_elem* elem;
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
int rv;
|
||||||
|
sigset_t oset;
|
||||||
|
|
||||||
|
rv = block_signals(&oset);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
rv = pthread_mutex_lock(&signal_mutex);
|
||||||
|
assert(rv == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Have we already installed our signal handlers? If the list is
|
||||||
|
* empty, it means we have not. */
|
||||||
|
if (fuse_head == NULL) {
|
||||||
|
if (set_signal_handler(SIGHUP, exit_handler) != 0 ||
|
||||||
|
set_signal_handler(SIGINT, exit_handler) != 0 ||
|
||||||
|
set_signal_handler(SIGTERM, exit_handler) != 0 ||
|
||||||
|
set_signal_handler(SIGPIPE, NULL) != 0) {
|
||||||
|
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add ourselves to the list of filesystems that want to be
|
||||||
|
* terminated upon receiving a signal. But only if we aren't
|
||||||
|
* already in the list. */
|
||||||
|
for (elem = fuse_head; elem != NULL; elem = elem->next) {
|
||||||
|
if (elem->fuse == fuse)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem = malloc(sizeof(*elem));
|
||||||
|
if (!elem) {
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
elem->fuse = fuse;
|
||||||
|
elem->next = fuse_head;
|
||||||
|
fuse_head = elem;
|
||||||
|
done:
|
||||||
|
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
rv = pthread_mutex_unlock(&signal_mutex);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
rv = unblock_signals(&oset);
|
||||||
|
assert(rv == 0);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__fuse_remove_signal_handlers(struct fuse* fuse) {
|
||||||
|
int ret = 0;
|
||||||
|
struct refuse_obj_elem* prev;
|
||||||
|
struct refuse_obj_elem* elem;
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
int rv;
|
||||||
|
sigset_t oset;
|
||||||
|
|
||||||
|
rv = block_signals(&oset);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
rv = pthread_mutex_lock(&signal_mutex);
|
||||||
|
assert(rv == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Remove ourselves from the list. */
|
||||||
|
for (prev = NULL, elem = fuse_head;
|
||||||
|
elem != NULL;
|
||||||
|
prev = elem, elem = elem->next) {
|
||||||
|
|
||||||
|
if (elem->fuse == fuse) {
|
||||||
|
if (prev)
|
||||||
|
prev->next = elem->next;
|
||||||
|
else
|
||||||
|
fuse_head = elem->next;
|
||||||
|
free(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore handlers if we were the last one. */
|
||||||
|
if (fuse_head == NULL) {
|
||||||
|
if (restore_signal_handler(SIGHUP, exit_handler) == -1 ||
|
||||||
|
restore_signal_handler(SIGINT, exit_handler) == -1 ||
|
||||||
|
restore_signal_handler(SIGTERM, exit_handler) == -1 ||
|
||||||
|
restore_signal_handler(SIGPIPE, NULL) == -1) {
|
||||||
|
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MULTITHREADED_REFUSE)
|
||||||
|
rv = pthread_mutex_unlock(&signal_mutex);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
rv = unblock_signals(&oset);
|
||||||
|
assert(rv == 0);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fwcfg.c,v 1.6 2021/12/04 06:42:39 pho Exp $ */
|
/* $NetBSD: fwcfg.c,v 1.7 2022/01/22 07:53:06 pho Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -27,11 +27,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: fwcfg.c,v 1.6 2021/12/04 06:42:39 pho Exp $");
|
__RCSID("$NetBSD: fwcfg.c,v 1.7 2022/01/22 07:53:06 pho Exp $");
|
||||||
|
|
||||||
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(2, 6)
|
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(2, 6)
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
Loading…
Reference in New Issue