"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.10.4/doc/html/fuse-3_810_83_2example_2hello__ll_8c_source.html" (9 Jun 2021, 48655 Bytes) of package /linux/misc/fuse-3.10.4.tar.xz:


Caution: In this restricted "Fossies" environment the current HTML page may not be correctly presentated and may have some non-functional links. You can here alternatively try to browse the pure source code or just view or download the uninterpreted raw source code. If the rendering is insufficient you may try to find and view the page on the project site itself.

libfuse
hello_ll.c
Go to the documentation of this file.
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 GPLv2.
6  See the file COPYING.
7 */
8 
21 #define FUSE_USE_VERSION 34
22 
23 #include <fuse_lowlevel.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <assert.h>
31 
32 static const char *hello_str = "Hello World!\n";
33 static const char *hello_name = "hello";
34 
35 static int hello_stat(fuse_ino_t ino, struct stat *stbuf)
36 {
37  stbuf->st_ino = ino;
38  switch (ino) {
39  case 1:
40  stbuf->st_mode = S_IFDIR | 0755;
41  stbuf->st_nlink = 2;
42  break;
43 
44  case 2:
45  stbuf->st_mode = S_IFREG | 0444;
46  stbuf->st_nlink = 1;
47  stbuf->st_size = strlen(hello_str);
48  break;
49 
50  default:
51  return -1;
52  }
53  return 0;
54 }
55 
56 static void hello_ll_getattr(fuse_req_t req, fuse_ino_t ino,
57  struct fuse_file_info *fi)
58 {
59  struct stat stbuf;
60 
61  (void) fi;
62 
63  memset(&stbuf, 0, sizeof(stbuf));
64  if (hello_stat(ino, &stbuf) == -1)
65  fuse_reply_err(req, ENOENT);
66  else
67  fuse_reply_attr(req, &stbuf, 1.0);
68 }
69 
70 static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
71 {
72  struct fuse_entry_param e;
73 
74  if (parent != 1 || strcmp(name, hello_name) != 0)
75  fuse_reply_err(req, ENOENT);
76  else {
77  memset(&e, 0, sizeof(e));
78  e.ino = 2;
79  e.attr_timeout = 1.0;
80  e.entry_timeout = 1.0;
81  hello_stat(e.ino, &e.attr);
82 
83  fuse_reply_entry(req, &e);
84  }
85 }
86 
87 struct dirbuf {
88  char *p;
89  size_t size;
90 };
91 
92 static void dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name,
93  fuse_ino_t ino)
94 {
95  struct stat stbuf;
96  size_t oldsize = b->size;
97  b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
98  b->p = (char *) realloc(b->p, b->size);
99  memset(&stbuf, 0, sizeof(stbuf));
100  stbuf.st_ino = ino;
101  fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
102  b->size);
103 }
104 
105 #define min(x, y) ((x) < (y) ? (x) : (y))
106 
107 static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
108  off_t off, size_t maxsize)
109 {
110  if (off < bufsize)
111  return fuse_reply_buf(req, buf + off,
112  min(bufsize - off, maxsize));
113  else
114  return fuse_reply_buf(req, NULL, 0);
115 }
116 
117 static void hello_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
118  off_t off, struct fuse_file_info *fi)
119 {
120  (void) fi;
121 
122  if (ino != 1)
123  fuse_reply_err(req, ENOTDIR);
124  else {
125  struct dirbuf b;
126 
127  memset(&b, 0, sizeof(b));
128  dirbuf_add(req, &b, ".", 1);
129  dirbuf_add(req, &b, "..", 1);
130  dirbuf_add(req, &b, hello_name, 2);
131  reply_buf_limited(req, b.p, b.size, off, size);
132  free(b.p);
133  }
134 }
135 
136 static void hello_ll_open(fuse_req_t req, fuse_ino_t ino,
137  struct fuse_file_info *fi)
138 {
139  if (ino != 2)
140  fuse_reply_err(req, EISDIR);
141  else if ((fi->flags & O_ACCMODE) != O_RDONLY)
142  fuse_reply_err(req, EACCES);
143  else
144  fuse_reply_open(req, fi);
145 }
146 
147 static void hello_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
148  off_t off, struct fuse_file_info *fi)
149 {
150  (void) fi;
151 
152  assert(ino == 2);
153  reply_buf_limited(req, hello_str, strlen(hello_str), off, size);
154 }
155 
156 static const struct fuse_lowlevel_ops hello_ll_oper = {
157  .lookup = hello_ll_lookup,
158  .getattr = hello_ll_getattr,
159  .readdir = hello_ll_readdir,
160  .open = hello_ll_open,
161  .read = hello_ll_read,
162 };
163 
164 int main(int argc, char *argv[])
165 {
166  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
167  struct fuse_session *se;
168  struct fuse_cmdline_opts opts;
169  struct fuse_loop_config config;
170  int ret = -1;
171 
172  if (fuse_parse_cmdline(&args, &opts) != 0)
173  return 1;
174  if (opts.show_help) {
175  printf("usage: %s [options] <mountpoint>\n\n", argv[0]);
178  ret = 0;
179  goto err_out1;
180  } else if (opts.show_version) {
181  printf("FUSE library version %s\n", fuse_pkgversion());
183  ret = 0;
184  goto err_out1;
185  }
186 
187  if(opts.mountpoint == NULL) {
188  printf("usage: %s [options] <mountpoint>\n", argv[0]);
189  printf(" %s --help\n", argv[0]);
190  ret = 1;
191  goto err_out1;
192  }
193 
194  se = fuse_session_new(&args, &hello_ll_oper,
195  sizeof(hello_ll_oper), NULL);
196  if (se == NULL)
197  goto err_out1;
198 
199  if (fuse_set_signal_handlers(se) != 0)
200  goto err_out2;
201 
202  if (fuse_session_mount(se, opts.mountpoint) != 0)
203  goto err_out3;
204 
205  fuse_daemonize(opts.foreground);
206 
207  /* Block until ctrl+c or fusermount -u */
208  if (opts.singlethread)
209  ret = fuse_session_loop(se);
210  else {
211  config.clone_fd = opts.clone_fd;
212  config.max_idle_threads = opts.max_idle_threads;
213  ret = fuse_session_loop_mt(se, &config);
214  }
215 
217 err_out3:
219 err_out2:
221 err_out1:
222  free(opts.mountpoint);
223  fuse_opt_free_args(&args);
224 
225  return ret ? 1 : 0;
226 }
void(* lookup)(fuse_req_t req, fuse_ino_t parent, const char *name)
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
void fuse_lowlevel_help(void)
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
void fuse_lowlevel_version(void)
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
void fuse_session_destroy(struct fuse_session *se)
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
int fuse_daemonize(int foreground)
Definition: helper.c:225
Definition: fuse_lowlevel.h:59
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
int fuse_set_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:62
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
void fuse_cmdline_help(void)
Definition: helper.c:129
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:34
int fuse_reply_err(fuse_req_t req, int err)
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
Definition: helper.c:202
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
const char * fuse_pkgversion(void)
Definition: fuse.c:5117
void fuse_session_unmount(struct fuse_session *se)
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
void fuse_remove_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:79
int fuse_session_loop_mt(struct fuse_session *se, struct fuse_loop_config *config)