Implement fuse_setup(), and fuse_teardown() - necessary for the python
bindings for refuse.
This commit is contained in:
parent
a2b7c5e9b3
commit
363bf2c052
|
@ -1,4 +1,4 @@
|
|||
$NetBSD: TODO,v 1.2 2007/02/11 18:32:02 pooka Exp $
|
||||
$NetBSD: TODO,v 1.3 2007/05/03 21:02:54 agc Exp $
|
||||
|
||||
To Do
|
||||
=====
|
||||
|
@ -21,3 +21,5 @@ WARNS=4
|
|||
address lint
|
||||
special directory handling in open()
|
||||
Finish off manual page
|
||||
fuse_setup
|
||||
fuse_teardown
|
||||
|
|
|
@ -157,6 +157,10 @@ void fuse_destroy(struct fuse *);
|
|||
|
||||
void fuse_unmount(const char *, struct fuse_chan *);
|
||||
|
||||
struct fuse *fuse_setup(int, char **, const struct fuse_operations *,
|
||||
size_t, char **, int *, int *);
|
||||
void fuse_teardown(struct fuse *, char *);
|
||||
|
||||
#if FUSE_USE_VERSION == 22
|
||||
#define fuse_unmount fuse_unmount_compat22
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: refuse.3,v 1.3 2007/02/17 08:40:36 wiz Exp $
|
||||
.\" $NetBSD: refuse.3,v 1.4 2007/05/03 21:02:54 agc Exp $
|
||||
.\"
|
||||
.\" Copyright © 2007 Alistair Crooks. All rights reserved.
|
||||
.\"
|
||||
|
@ -26,7 +26,7 @@
|
|||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 23, 2007
|
||||
.Dd April 30, 2007
|
||||
.Dt REFUSE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -50,6 +50,15 @@
|
|||
.Fa "const struct fuse_opt *descriptions" "fuse_opt_proc_t processingfunc"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo fuse_teardown
|
||||
.Fa "struct fuse *fuse" "char *mountpoint"
|
||||
.Fc
|
||||
.Ft struct fuse *
|
||||
.Fo fuse_setup
|
||||
.Fa "int argc" "char **argv" "const struct fuse_operations *ops"
|
||||
.Fa "size_t opssize" "char **mountpoint" "int *multithreaded" "int *fd"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo puffs_fuse_node_getattr
|
||||
.Fa "const char *path" "struct stat *attrs"
|
||||
.Fc
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: refuse.c,v 1.50 2007/05/02 18:05:54 pooka Exp $ */
|
||||
/* $NetBSD: refuse.c,v 1.51 2007/05/03 21:02:54 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright © 2007 Alistair Crooks. All rights reserved.
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(lint)
|
||||
__RCSID("$NetBSD: refuse.c,v 1.50 2007/05/02 18:05:54 pooka Exp $");
|
||||
__RCSID("$NetBSD: refuse.c,v 1.51 2007/05/03 21:02:54 agc Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -67,10 +67,9 @@ struct fuse_config {
|
|||
};
|
||||
|
||||
struct fuse_chan {
|
||||
const char *dir;
|
||||
struct fuse_args *args;
|
||||
|
||||
struct puffs_usermount *pu;
|
||||
const char *dir;
|
||||
struct fuse_args *args;
|
||||
struct puffs_usermount *pu;
|
||||
};
|
||||
|
||||
/* this is the private fuse structure */
|
||||
|
@ -221,6 +220,93 @@ puffs_fuse_dirfil(fuse_dirh_t h, const char *name, int type, ino_t ino)
|
|||
return fill_dirbuf(h, name, dino, dtype);
|
||||
}
|
||||
|
||||
static struct fuse_args *
|
||||
deep_copy_args(int argc, char **argv)
|
||||
{
|
||||
struct fuse_args *ap;
|
||||
int i;
|
||||
|
||||
NEW(struct fuse_args, ap, "deep_copy_args", return NULL);
|
||||
/* deep copy args structure into channel args */
|
||||
ap->allocated = ((argc / 10) + 1) * 10;
|
||||
NEWARRAY(char *, ap->argv, ap->allocated, "deep_copy_args",
|
||||
return NULL);
|
||||
for (i = 0 ; i < argc ; i++) {
|
||||
ap->argv[i] = strdup(argv[i]);
|
||||
}
|
||||
return ap;
|
||||
}
|
||||
|
||||
static void
|
||||
free_args(struct fuse_args *ap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < ap->argc ; i++) {
|
||||
free(ap->argv[i]);
|
||||
}
|
||||
free(ap);
|
||||
}
|
||||
|
||||
/* this function exposes struct fuse to userland */
|
||||
struct fuse *
|
||||
fuse_setup(int argc, char **argv, const struct fuse_operations *ops,
|
||||
size_t size, char **mountpoint, int *multithreaded, int *fd)
|
||||
{
|
||||
struct fuse_chan *fc;
|
||||
struct fuse_args *args;
|
||||
struct fuse *fuse;
|
||||
char name[64];
|
||||
char *slash;
|
||||
|
||||
/* whilst this (assigning the pu_privdata in the puffs
|
||||
* usermount struct to be the fuse struct) might seem like
|
||||
* we are chasing our tail here, the logic is as follows:
|
||||
+ the operation wrapper gets called with the puffs
|
||||
calling conventions
|
||||
+ we need to fix up args first
|
||||
+ then call the fuse user-supplied operation
|
||||
+ then we fix up any values on return that we need to
|
||||
+ and fix up any nodes, etc
|
||||
* so we need to be able to get at the fuse ops from within the
|
||||
* puffs_usermount struct
|
||||
*/
|
||||
if (argv == NULL || *argv == NULL) {
|
||||
(void) strlcpy(name, "refuse", sizeof(name));
|
||||
} else {
|
||||
if ((slash = strrchr(*argv, '/')) == NULL) {
|
||||
slash = *argv;
|
||||
} else {
|
||||
slash += 1;
|
||||
}
|
||||
(void) snprintf(name, sizeof(name), "refuse:%s", slash);
|
||||
}
|
||||
|
||||
/* stuff name into fuse_args */
|
||||
args = deep_copy_args(argc, argv);
|
||||
if (args->argc > 0) {
|
||||
FREE(args->argv[0]);
|
||||
}
|
||||
args->argv[0] = strdup(name);
|
||||
|
||||
fc = fuse_mount(*mountpoint = argv[argc - 1], args);
|
||||
fuse = fuse_new(fc, args, ops, size, NULL);
|
||||
|
||||
free_args(args);
|
||||
|
||||
/* XXX - wait for puffs to become multi-threaded */
|
||||
if (multithreaded) {
|
||||
*multithreaded = 0;
|
||||
}
|
||||
|
||||
/* XXX - this is unused */
|
||||
if (fd) {
|
||||
*fd = 0;
|
||||
}
|
||||
|
||||
return fuse;
|
||||
}
|
||||
|
||||
#define FUSE_ERR_UNLINK(fuse, file) if (fuse->op.unlink) fuse->op.unlink(file)
|
||||
#define FUSE_ERR_RMDIR(fuse, dir) if (fuse->op.rmdir) fuse->op.rmdir(dir)
|
||||
|
||||
|
@ -967,78 +1053,20 @@ puffs_fuse_fs_statvfs(struct puffs_cc *pcc, struct statvfs *svfsb, pid_t pid)
|
|||
|
||||
|
||||
/* End of puffs_fuse operations */
|
||||
|
||||
static struct fuse_args *
|
||||
deep_copy_args(int argc, char **argv)
|
||||
{
|
||||
struct fuse_args *ap;
|
||||
int i;
|
||||
|
||||
NEW(struct fuse_args, ap, "deep_copy_args", return NULL);
|
||||
/* deep copy args structure into channel args */
|
||||
ap->allocated = ((argc / 10) + 1) * 10;
|
||||
NEWARRAY(char *, ap->argv, ap->allocated, "fuse_mount", return NULL);
|
||||
for (i = 0 ; i < argc ; i++) {
|
||||
ap->argv[i] = strdup(argv[i]);
|
||||
}
|
||||
return ap;
|
||||
}
|
||||
|
||||
static void
|
||||
free_args(struct fuse_args *ap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < ap->argc ; i++) {
|
||||
free(ap->argv[i]);
|
||||
}
|
||||
free(ap);
|
||||
}
|
||||
|
||||
/* ARGSUSED3 */
|
||||
int
|
||||
fuse_main_real(int argc, char **argv, const struct fuse_operations *ops,
|
||||
size_t size, void *userdata)
|
||||
{
|
||||
struct fuse *fuse;
|
||||
struct fuse_chan *fc;
|
||||
struct fuse_args *args;
|
||||
char name[64];
|
||||
char *slash;
|
||||
int ret;
|
||||
struct fuse *fuse;
|
||||
char *mountpoint;
|
||||
int multithreaded;
|
||||
int fd;
|
||||
|
||||
/* whilst this (assigning the pu_privdata in the puffs
|
||||
* usermount struct to be the fuse struct) might seem like
|
||||
* we are chasing our tail here, the logic is as follows:
|
||||
+ the operation wrapper gets called with the puffs
|
||||
calling conventions
|
||||
+ we need to fix up args first
|
||||
+ then call the fuse user-supplied operation
|
||||
+ then we fix up any values on return that we need to
|
||||
+ and fix up any nodes, etc
|
||||
* so we need to be able to get at the fuse ops from within the
|
||||
* puffs_usermount struct
|
||||
*/
|
||||
if ((slash = strrchr(*argv, '/')) == NULL) {
|
||||
slash = *argv;
|
||||
} else {
|
||||
slash += 1;
|
||||
}
|
||||
(void) snprintf(name, sizeof(name), "refuse:%s", slash);
|
||||
fuse = fuse_setup(argc, argv, ops, size, &mountpoint, &multithreaded,
|
||||
&fd);
|
||||
|
||||
/* stuff name into fuse_args */
|
||||
args = deep_copy_args(argc, argv);
|
||||
FREE(args->argv[0]);
|
||||
args->argv[0] = strdup(name);
|
||||
|
||||
fc = fuse_mount(argv[argc - 1], args);
|
||||
fuse = fuse_new(fc, args, ops, size, userdata);
|
||||
|
||||
ret = fuse_loop(fuse);
|
||||
|
||||
free_args(args);
|
||||
|
||||
return ret;
|
||||
return fuse_loop(fuse);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1210,3 +1238,14 @@ fuse_unmount_compat22(const char *mp)
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
/* The next function "exposes" struct fuse to userland. Not much
|
||||
* that we can do about this, as we're conforming to a defined
|
||||
* interface. */
|
||||
|
||||
void
|
||||
fuse_teardown(struct fuse *fuse, char *mountpoint)
|
||||
{
|
||||
fuse_unmount(mountpoint, fuse->fc);
|
||||
fuse_destroy(fuse);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue