blob: f88d6e5fb2799fca3810ffe9bc6fb6c10f5d1fa4 [file] [log] [blame]
Miklos Szeredia1482422005-08-14 23:00:27 +00001/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU LGPL.
6 See the file COPYING.LIB
7*/
8
9#include "fuse_lowlevel.h"
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <assert.h>
15
16struct fuse_session {
17 struct fuse_session_ops op;
18
19 void *data;
Miklos Szeredi2bb750e2005-10-03 14:54:24 +000020
Miklos Szeredia1482422005-08-14 23:00:27 +000021 volatile int exited;
22
23 struct fuse_chan *ch;
24};
25
26struct fuse_chan {
27 struct fuse_chan_ops op;
28
29 struct fuse_session *se;
30
31 int fd;
32
33 size_t bufsize;
Miklos Szeredi2bb750e2005-10-03 14:54:24 +000034
Miklos Szeredia1482422005-08-14 23:00:27 +000035 void *data;
36};
37
38struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
39{
40 struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
41 if (se == NULL) {
42 fprintf(stderr, "fuse: failed to allocate session\n");
43 return NULL;
44 }
45
46 memset(se, 0, sizeof(*se));
47 se->op = *op;
48 se->data = data;
49
50 return se;
51}
52
53void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch)
54{
55 assert(se->ch == NULL);
56 assert(ch->se == NULL);
57 se->ch = ch;
58 ch->se = se;
59}
60
61struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
62 struct fuse_chan *ch)
63{
64 assert(ch == NULL || ch == se->ch);
65 if (ch == NULL)
66 return se->ch;
67 else
68 return NULL;
69}
70
71void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,
72 struct fuse_chan *ch)
73{
74 se->op.process(se->data, buf, len, ch);
75}
76
77void fuse_session_destroy(struct fuse_session *se)
78{
79 if (se->op.destroy)
80 se->op.destroy(se->data);
81 if (se->ch != NULL)
82 fuse_chan_destroy(se->ch);
83 free(se);
84}
85
86void fuse_session_exit(struct fuse_session *se)
87{
Miklos Szeredi178451d2005-08-15 13:19:07 +000088 if (se->op.exit)
89 se->op.exit(se->data, 1);
Miklos Szeredia1482422005-08-14 23:00:27 +000090 se->exited = 1;
91}
92
93void fuse_session_reset(struct fuse_session *se)
94{
Miklos Szeredi178451d2005-08-15 13:19:07 +000095 if (se->op.exit)
96 se->op.exit(se->data, 0);
Miklos Szeredia1482422005-08-14 23:00:27 +000097 se->exited = 0;
98}
99
100int fuse_session_exited(struct fuse_session *se)
101{
Miklos Szeredi178451d2005-08-15 13:19:07 +0000102 if (se->op.exited)
103 return se->op.exited(se->data);
104 else
105 return se->exited;
Miklos Szeredia1482422005-08-14 23:00:27 +0000106}
107
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000108struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
Miklos Szeredia1482422005-08-14 23:00:27 +0000109 size_t bufsize, void *data)
110{
111 struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
112 if (ch == NULL) {
113 fprintf(stderr, "fuse: failed to allocate channel\n");
114 return NULL;
115 }
116
117 memset(ch, 0, sizeof(*ch));
118 ch->op = *op;
119 ch->fd = fd;
120 ch->bufsize = bufsize;
121 ch->data = data;
122
123 return ch;
124}
125
126int fuse_chan_fd(struct fuse_chan *ch)
127{
128 return ch->fd;
129}
130
131size_t fuse_chan_bufsize(struct fuse_chan *ch)
132{
133 return ch->bufsize;
134}
135
136void *fuse_chan_data(struct fuse_chan *ch)
137{
138 return ch->data;
139}
140
141struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
142{
143 return ch->se;
144}
145
146int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
147{
148 return ch->op.receive(ch, buf, size);
149}
150
151int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count)
152{
153 return ch->op.send(ch, iov, count);
154}
155
156void fuse_chan_destroy(struct fuse_chan *ch)
157{
158 if (ch->op.destroy)
159 ch->op.destroy(ch);
160 free(ch);
161}