summaryrefslogtreecommitdiff
path: root/libfuse-lite/fuse_session.c (plain)
blob: c4e544d1974cba9003758a0fd8c116711e52cac9
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU LGPLv2.
6 See the file COPYING.LIB
7*/
8
9#include "config.h"
10#include "fuse_lowlevel.h"
11#include "fuse_lowlevel_compat.h"
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <assert.h>
17#include <errno.h>
18
19struct fuse_session {
20 struct fuse_session_ops op;
21
22 void *data;
23
24 volatile int exited;
25
26 struct fuse_chan *ch;
27};
28
29struct fuse_chan {
30 struct fuse_chan_ops op;
31
32 struct fuse_session *se;
33
34 int fd;
35
36 size_t bufsize;
37
38 void *data;
39};
40
41struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
42{
43 struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
44 if (se == NULL) {
45 fprintf(stderr, "fuse: failed to allocate session\n");
46 return NULL;
47 }
48
49 memset(se, 0, sizeof(*se));
50 se->op = *op;
51 se->data = data;
52
53 return se;
54}
55
56void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch)
57{
58 assert(se->ch == NULL);
59 assert(ch->se == NULL);
60 se->ch = ch;
61 ch->se = se;
62}
63
64void fuse_session_remove_chan(struct fuse_chan *ch)
65{
66 struct fuse_session *se = ch->se;
67 if (se) {
68 assert(se->ch == ch);
69 se->ch = NULL;
70 ch->se = NULL;
71 }
72}
73
74struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
75 struct fuse_chan *ch)
76{
77 assert(ch == NULL || ch == se->ch);
78 if (ch == NULL)
79 return se->ch;
80 else
81 return NULL;
82}
83
84void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,
85 struct fuse_chan *ch)
86{
87 se->op.process(se->data, buf, len, ch);
88}
89
90void fuse_session_destroy(struct fuse_session *se)
91{
92 if (se->op.destroy)
93 se->op.destroy(se->data);
94 if (se->ch != NULL)
95 fuse_chan_destroy(se->ch);
96 free(se);
97}
98
99void fuse_session_exit(struct fuse_session *se)
100{
101 if (se->op.exit)
102 se->op.exit(se->data, 1);
103 se->exited = 1;
104}
105
106void fuse_session_reset(struct fuse_session *se)
107{
108 if (se->op.exit)
109 se->op.exit(se->data, 0);
110 se->exited = 0;
111}
112
113int fuse_session_exited(struct fuse_session *se)
114{
115 if (se->op.exited)
116 return se->op.exited(se->data);
117 else
118 return se->exited;
119}
120
121static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd,
122 size_t bufsize, void *data)
123{
124 struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
125 if (ch == NULL) {
126 fprintf(stderr, "fuse: failed to allocate channel\n");
127 return NULL;
128 }
129
130 memset(ch, 0, sizeof(*ch));
131 ch->op = *op;
132 ch->fd = fd;
133 ch->bufsize = bufsize;
134 ch->data = data;
135
136 return ch;
137}
138
139struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
140 size_t bufsize, void *data)
141{
142 return fuse_chan_new_common(op, fd, bufsize, data);
143}
144
145int fuse_chan_fd(struct fuse_chan *ch)
146{
147 return ch->fd;
148}
149
150size_t fuse_chan_bufsize(struct fuse_chan *ch)
151{
152 return ch->bufsize;
153}
154
155void *fuse_chan_data(struct fuse_chan *ch)
156{
157 return ch->data;
158}
159
160struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
161{
162 return ch->se;
163}
164
165int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)
166{
167 struct fuse_chan *ch = *chp;
168 return ch->op.receive(chp, buf, size);
169}
170
171int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count)
172{
173 return ch->op.send(ch, iov, count);
174}
175
176void fuse_chan_destroy(struct fuse_chan *ch)
177{
178 fuse_session_remove_chan(ch);
179 if (ch->op.destroy)
180 ch->op.destroy(ch);
181 free(ch);
182}
183
184