"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.2.1/example/hello_ll.c" (14 Nov 2017, 4632 Bytes) of package /linux/misc/fuse-3.2.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "hello_ll.c": 3.2.0_vs_3.2.1.

    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 GPL.
    6   See the file COPYING.
    7 */
    8 
    9 /** @file
   10  *
   11  * minimal example filesystem using low-level API
   12  *
   13  * Compile with:
   14  *
   15  *     gcc -Wall hello_ll.c `pkg-config fuse3 --cflags --libs` -o hello_ll
   16  *
   17  * ## Source code ##
   18  * \include hello_ll.c
   19  */
   20 
   21 #define FUSE_USE_VERSION 31
   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 & 3) != 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 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     int ret = -1;
  170 
  171     if (fuse_parse_cmdline(&args, &opts) != 0)
  172         return 1;
  173     if (opts.show_help) {
  174         printf("usage: %s [options] <mountpoint>\n\n", argv[0]);
  175         fuse_cmdline_help();
  176         fuse_lowlevel_help();
  177         ret = 0;
  178         goto err_out1;
  179     } else if (opts.show_version) {
  180         printf("FUSE library version %s\n", fuse_pkgversion());
  181         fuse_lowlevel_version();
  182         ret = 0;
  183         goto err_out1;
  184     }
  185 
  186     se = fuse_session_new(&args, &hello_ll_oper,
  187                   sizeof(hello_ll_oper), NULL);
  188     if (se == NULL)
  189         goto err_out1;
  190 
  191     if (fuse_set_signal_handlers(se) != 0)
  192         goto err_out2;
  193 
  194     if (fuse_session_mount(se, opts.mountpoint) != 0)
  195         goto err_out3;
  196 
  197     fuse_daemonize(opts.foreground);
  198 
  199     /* Block until ctrl+c or fusermount -u */
  200     if (opts.singlethread)
  201         ret = fuse_session_loop(se);
  202     else
  203         ret = fuse_session_loop_mt(se, opts.clone_fd);
  204 
  205     fuse_session_unmount(se);
  206 err_out3:
  207     fuse_remove_signal_handlers(se);
  208 err_out2:
  209     fuse_session_destroy(se);
  210 err_out1:
  211     free(opts.mountpoint);
  212     fuse_opt_free_args(&args);
  213 
  214     return ret ? 1 : 0;
  215 }