"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.10.4/doc/html/ioctl_8c_source.html" (9 Jun 2021, 33648 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
ioctl.c
Go to the documentation of this file.
1 /*
2  FUSE fioc: FUSE ioctl example
3  Copyright (C) 2008 SUSE Linux Products GmbH
4  Copyright (C) 2008 Tejun Heo <teheo@suse.de>
5 
6  This program can be distributed under the terms of the GNU GPLv2.
7  See the file COPYING.
8 */
9 
25 #define FUSE_USE_VERSION 35
26 
27 #include <fuse.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <time.h>
33 #include <errno.h>
34 
35 #include "ioctl.h"
36 
37 #define FIOC_NAME "fioc"
38 
39 enum {
40  FIOC_NONE,
41  FIOC_ROOT,
42  FIOC_FILE,
43 };
44 
45 static void *fioc_buf;
46 static size_t fioc_size;
47 
48 static int fioc_resize(size_t new_size)
49 {
50  void *new_buf;
51 
52  if (new_size == fioc_size)
53  return 0;
54 
55  new_buf = realloc(fioc_buf, new_size);
56  if (!new_buf && new_size)
57  return -ENOMEM;
58 
59  if (new_size > fioc_size)
60  memset(new_buf + fioc_size, 0, new_size - fioc_size);
61 
62  fioc_buf = new_buf;
63  fioc_size = new_size;
64 
65  return 0;
66 }
67 
68 static int fioc_expand(size_t new_size)
69 {
70  if (new_size > fioc_size)
71  return fioc_resize(new_size);
72  return 0;
73 }
74 
75 static int fioc_file_type(const char *path)
76 {
77  if (strcmp(path, "/") == 0)
78  return FIOC_ROOT;
79  if (strcmp(path, "/" FIOC_NAME) == 0)
80  return FIOC_FILE;
81  return FIOC_NONE;
82 }
83 
84 static int fioc_getattr(const char *path, struct stat *stbuf,
85  struct fuse_file_info *fi)
86 {
87  (void) fi;
88  stbuf->st_uid = getuid();
89  stbuf->st_gid = getgid();
90  stbuf->st_atime = stbuf->st_mtime = time(NULL);
91 
92  switch (fioc_file_type(path)) {
93  case FIOC_ROOT:
94  stbuf->st_mode = S_IFDIR | 0755;
95  stbuf->st_nlink = 2;
96  break;
97  case FIOC_FILE:
98  stbuf->st_mode = S_IFREG | 0644;
99  stbuf->st_nlink = 1;
100  stbuf->st_size = fioc_size;
101  break;
102  case FIOC_NONE:
103  return -ENOENT;
104  }
105 
106  return 0;
107 }
108 
109 static int fioc_open(const char *path, struct fuse_file_info *fi)
110 {
111  (void) fi;
112 
113  if (fioc_file_type(path) != FIOC_NONE)
114  return 0;
115  return -ENOENT;
116 }
117 
118 static int fioc_do_read(char *buf, size_t size, off_t offset)
119 {
120  if (offset >= fioc_size)
121  return 0;
122 
123  if (size > fioc_size - offset)
124  size = fioc_size - offset;
125 
126  memcpy(buf, fioc_buf + offset, size);
127 
128  return size;
129 }
130 
131 static int fioc_read(const char *path, char *buf, size_t size,
132  off_t offset, struct fuse_file_info *fi)
133 {
134  (void) fi;
135 
136  if (fioc_file_type(path) != FIOC_FILE)
137  return -EINVAL;
138 
139  return fioc_do_read(buf, size, offset);
140 }
141 
142 static int fioc_do_write(const char *buf, size_t size, off_t offset)
143 {
144  if (fioc_expand(offset + size))
145  return -ENOMEM;
146 
147  memcpy(fioc_buf + offset, buf, size);
148 
149  return size;
150 }
151 
152 static int fioc_write(const char *path, const char *buf, size_t size,
153  off_t offset, struct fuse_file_info *fi)
154 {
155  (void) fi;
156 
157  if (fioc_file_type(path) != FIOC_FILE)
158  return -EINVAL;
159 
160  return fioc_do_write(buf, size, offset);
161 }
162 
163 static int fioc_truncate(const char *path, off_t size,
164  struct fuse_file_info *fi)
165 {
166  (void) fi;
167  if (fioc_file_type(path) != FIOC_FILE)
168  return -EINVAL;
169 
170  return fioc_resize(size);
171 }
172 
173 static int fioc_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
174  off_t offset, struct fuse_file_info *fi,
175  enum fuse_readdir_flags flags)
176 {
177  (void) fi;
178  (void) offset;
179  (void) flags;
180 
181  if (fioc_file_type(path) != FIOC_ROOT)
182  return -ENOENT;
183 
184  filler(buf, ".", NULL, 0, 0);
185  filler(buf, "..", NULL, 0, 0);
186  filler(buf, FIOC_NAME, NULL, 0, 0);
187 
188  return 0;
189 }
190 
191 static int fioc_ioctl(const char *path, unsigned int cmd, void *arg,
192  struct fuse_file_info *fi, unsigned int flags, void *data)
193 {
194  (void) arg;
195  (void) fi;
196  (void) flags;
197 
198  if (fioc_file_type(path) != FIOC_FILE)
199  return -EINVAL;
200 
201  if (flags & FUSE_IOCTL_COMPAT)
202  return -ENOSYS;
203 
204  switch (cmd) {
205  case FIOC_GET_SIZE:
206  *(size_t *)data = fioc_size;
207  return 0;
208 
209  case FIOC_SET_SIZE:
210  fioc_resize(*(size_t *)data);
211  return 0;
212  }
213 
214  return -EINVAL;
215 }
216 
217 static const struct fuse_operations fioc_oper = {
218  .getattr = fioc_getattr,
219  .readdir = fioc_readdir,
220  .truncate = fioc_truncate,
221  .open = fioc_open,
222  .read = fioc_read,
223  .write = fioc_write,
224  .ioctl = fioc_ioctl,
225 };
226 
227 int main(int argc, char *argv[])
228 {
229  return fuse_main(argc, argv, &fioc_oper, NULL);
230 }
fuse_readdir_flags
Definition: fuse.h:42
int(* getattr)(const char *, struct stat *, struct fuse_file_info *fi)
Definition: fuse.h:314
#define FUSE_IOCTL_COMPAT
Definition: fuse_common.h:407
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:85
#define fuse_main(argc, argv, op, private_data)
Definition: fuse.h:878