1/* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2017 Nikolaus Rath <Nikolaus@rath.org> 4 5 This program can be distributed under the terms of the GNU GPLv2. 6 See the file COPYING. 7*/ 8 9/** @file 10 * 11 * minimal example filesystem that prints out all capabilities 12 * supported by the kernel and then exits. 13 * 14 * Compile with: 15 * 16 * gcc -Wall printcap.c `pkg-config fuse3 --cflags --libs` -o printcap 17 * 18 * ## Source code ## 19 * \include printcap.c 20 */ 21 22#define FUSE_USE_VERSION 31 23 24#include <fuse_lowlevel.h> 25#include <stdio.h> 26#include <unistd.h> 27#include <string.h> 28#include <stdlib.h> 29 30struct fuse_session *se; 31 32static void pc_init(void *userdata, 33 struct fuse_conn_info *conn) 34{ 35 (void) userdata; 36 37 printf("Protocol version: %d.%d\n", conn->proto_major, 38 conn->proto_minor); 39 printf("Capabilities:\n"); 40 if(conn->capable & FUSE_CAP_ASYNC_READ) 41 printf("\tFUSE_CAP_ASYNC_READ\n"); 42 if(conn->capable & FUSE_CAP_POSIX_LOCKS) 43 printf("\tFUSE_CAP_POSIX_LOCKS\n"); 44 if(conn->capable & FUSE_CAP_ATOMIC_O_TRUNC) 45 printf("\tFUSE_CAP_ATOMIC_O_TRUNC\n"); 46 if(conn->capable & FUSE_CAP_EXPORT_SUPPORT) 47 printf("\tFUSE_CAP_EXPORT_SUPPORT\n"); 48 if(conn->capable & FUSE_CAP_DONT_MASK) 49 printf("\tFUSE_CAP_DONT_MASK\n"); 50 if(conn->capable & FUSE_CAP_SPLICE_MOVE) 51 printf("\tFUSE_CAP_SPLICE_MOVE\n"); 52 if(conn->capable & FUSE_CAP_SPLICE_READ) 53 printf("\tFUSE_CAP_SPLICE_READ\n"); 54 if(conn->capable & FUSE_CAP_SPLICE_WRITE) 55 printf("\tFUSE_CAP_SPLICE_WRITE\n"); 56 if(conn->capable & FUSE_CAP_FLOCK_LOCKS) 57 printf("\tFUSE_CAP_FLOCK_LOCKS\n"); 58 if(conn->capable & FUSE_CAP_IOCTL_DIR) 59 printf("\tFUSE_CAP_IOCTL_DIR\n"); 60 if(conn->capable & FUSE_CAP_AUTO_INVAL_DATA) 61 printf("\tFUSE_CAP_AUTO_INVAL_DATA\n"); 62 if(conn->capable & FUSE_CAP_READDIRPLUS) 63 printf("\tFUSE_CAP_READDIRPLUS\n"); 64 if(conn->capable & FUSE_CAP_READDIRPLUS_AUTO) 65 printf("\tFUSE_CAP_READDIRPLUS_AUTO\n"); 66 if(conn->capable & FUSE_CAP_ASYNC_DIO) 67 printf("\tFUSE_CAP_ASYNC_DIO\n"); 68 if(conn->capable & FUSE_CAP_WRITEBACK_CACHE) 69 printf("\tFUSE_CAP_WRITEBACK_CACHE\n"); 70 if(conn->capable & FUSE_CAP_NO_OPEN_SUPPORT) 71 printf("\tFUSE_CAP_NO_OPEN_SUPPORT\n"); 72 if(conn->capable & FUSE_CAP_PARALLEL_DIROPS) 73 printf("\tFUSE_CAP_PARALLEL_DIROPS\n"); 74 if(conn->capable & FUSE_CAP_POSIX_ACL) 75 printf("\tFUSE_CAP_POSIX_ACL\n"); 76 if(conn->capable & FUSE_CAP_CACHE_SYMLINKS) 77 printf("\tFUSE_CAP_CACHE_SYMLINKS\n"); 78 if(conn->capable & FUSE_CAP_NO_OPENDIR_SUPPORT) 79 printf("\tFUSE_CAP_NO_OPENDIR_SUPPORT\n"); 80 if(conn->capable & FUSE_CAP_EXPLICIT_INVAL_DATA) 81 printf("\tFUSE_CAP_EXPLICIT_INVAL_DATA\n"); 82 if(conn->capable & FUSE_CAP_EXPIRE_ONLY) 83 printf("\tFUSE_CAP_EXPIRE_ONLY\n"); 84 fuse_session_exit(se); 85} 86 87 88static const struct fuse_lowlevel_ops pc_oper = { 89 .init = pc_init, 90}; 91 92int main(int argc, char **argv) 93{ 94 struct fuse_args args = FUSE_ARGS_INIT(argc, argv); 95 char *mountpoint; 96 int ret = -1; 97 98 mountpoint = strdup("/tmp/fuse_printcap_XXXXXX"); 99 if(mkdtemp(mountpoint) == NULL) { 100 perror("mkdtemp"); 101 return 1; 102 } 103 104 printf("FUSE library version %s\n", fuse_pkgversion()); 105 fuse_lowlevel_version(); 106 107 se = fuse_session_new(&args, &pc_oper, 108 sizeof(pc_oper), NULL); 109 if (se == NULL) 110 goto err_out1; 111 112 if (fuse_set_signal_handlers(se) != 0) 113 goto err_out2; 114 115 if (fuse_session_mount(se, mountpoint) != 0) 116 goto err_out3; 117 118 ret = fuse_session_loop(se); 119 120 fuse_session_unmount(se); 121err_out3: 122 fuse_remove_signal_handlers(se); 123err_out2: 124 fuse_session_destroy(se); 125err_out1: 126 rmdir(mountpoint); 127 free(mountpoint); 128 fuse_opt_free_args(&args); 129 130 return ret ? 1 : 0; 131} 132