fix
[fuse.git] / example / fusexmp.c
blob5f5466713ba65e932099e172c80f00d221f06fa2
1 /*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7 */
9 #include <config.h>
11 #ifdef linux
12 /* For pread()/pwrite() */
13 #define _XOPEN_SOURCE 500
14 #endif
16 #include <fuse.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <dirent.h>
22 #include <errno.h>
23 #include <sys/time.h>
24 #ifdef HAVE_SETXATTR
25 #include <sys/xattr.h>
26 #endif
28 static int xmp_getattr(const char *path, struct stat *stbuf)
30 int res;
32 res = lstat(path, stbuf);
33 if (res == -1)
34 return -errno;
36 return 0;
39 static int xmp_access(const char *path, int mask)
41 int res;
43 res = access(path, mask);
44 if (res == -1)
45 return -errno;
47 return 0;
50 static int xmp_readlink(const char *path, char *buf, size_t size)
52 int res;
54 res = readlink(path, buf, size - 1);
55 if (res == -1)
56 return -errno;
58 buf[res] = '\0';
59 return 0;
63 static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
64 off_t offset, struct fuse_file_info *fi)
66 DIR *dp;
67 struct dirent *de;
69 (void) offset;
70 (void) fi;
72 dp = opendir(path);
73 if (dp == NULL)
74 return -errno;
76 while ((de = readdir(dp)) != NULL) {
77 struct stat st;
78 memset(&st, 0, sizeof(st));
79 st.st_ino = de->d_ino;
80 st.st_mode = de->d_type << 12;
81 if (filler(buf, de->d_name, &st, 0))
82 break;
85 closedir(dp);
86 return 0;
89 static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
91 int res;
93 /* On Linux this could just be 'mknod(path, mode, rdev)' but this
94 is more portable */
95 if (S_ISREG(mode)) {
96 res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode);
97 if (res >= 0)
98 res = close(res);
99 } else if (S_ISFIFO(mode))
100 res = mkfifo(path, mode);
101 else
102 res = mknod(path, mode, rdev);
103 if (res == -1)
104 return -errno;
106 return 0;
109 static int xmp_mkdir(const char *path, mode_t mode)
111 int res;
113 res = mkdir(path, mode);
114 if (res == -1)
115 return -errno;
117 return 0;
120 static int xmp_unlink(const char *path)
122 int res;
124 res = unlink(path);
125 if (res == -1)
126 return -errno;
128 return 0;
131 static int xmp_rmdir(const char *path)
133 int res;
135 res = rmdir(path);
136 if (res == -1)
137 return -errno;
139 return 0;
142 static int xmp_symlink(const char *from, const char *to)
144 int res;
146 res = symlink(from, to);
147 if (res == -1)
148 return -errno;
150 return 0;
153 static int xmp_rename(const char *from, const char *to)
155 int res;
157 res = rename(from, to);
158 if (res == -1)
159 return -errno;
161 return 0;
164 static int xmp_link(const char *from, const char *to)
166 int res;
168 res = link(from, to);
169 if (res == -1)
170 return -errno;
172 return 0;
175 static int xmp_chmod(const char *path, mode_t mode)
177 int res;
179 res = chmod(path, mode);
180 if (res == -1)
181 return -errno;
183 return 0;
186 static int xmp_chown(const char *path, uid_t uid, gid_t gid)
188 int res;
190 res = lchown(path, uid, gid);
191 if (res == -1)
192 return -errno;
194 return 0;
197 static int xmp_truncate(const char *path, off_t size)
199 int res;
201 res = truncate(path, size);
202 if (res == -1)
203 return -errno;
205 return 0;
208 static int xmp_utimes(const char *path, const struct timespec ts[2])
210 int res;
211 struct timeval tv[2];
213 tv[0].tv_sec = ts[0].tv_sec;
214 tv[0].tv_usec = ts[0].tv_nsec / 1000;
215 tv[1].tv_sec = ts[1].tv_sec;
216 tv[1].tv_usec = ts[1].tv_nsec / 1000;
218 res = utimes(path, tv);
219 if (res == -1)
220 return -errno;
222 return 0;
225 static int xmp_open(const char *path, struct fuse_file_info *fi)
227 int res;
229 res = open(path, fi->flags);
230 if (res == -1)
231 return -errno;
233 close(res);
234 return 0;
237 static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
238 struct fuse_file_info *fi)
240 int fd;
241 int res;
243 (void) fi;
244 fd = open(path, O_RDONLY);
245 if (fd == -1)
246 return -errno;
248 res = pread(fd, buf, size, offset);
249 if (res == -1)
250 res = -errno;
252 close(fd);
253 return res;
256 static int xmp_write(const char *path, const char *buf, size_t size,
257 off_t offset, struct fuse_file_info *fi)
259 int fd;
260 int res;
262 (void) fi;
263 fd = open(path, O_WRONLY);
264 if (fd == -1)
265 return -errno;
267 res = pwrite(fd, buf, size, offset);
268 if (res == -1)
269 res = -errno;
271 close(fd);
272 return res;
275 static int xmp_statfs(const char *path, struct statvfs *stbuf)
277 int res;
279 res = statvfs(path, stbuf);
280 if (res == -1)
281 return -errno;
283 return 0;
286 static int xmp_release(const char *path, struct fuse_file_info *fi)
288 /* Just a stub. This method is optional and can safely be left
289 unimplemented */
291 (void) path;
292 (void) fi;
293 return 0;
296 static int xmp_fsync(const char *path, int isdatasync,
297 struct fuse_file_info *fi)
299 /* Just a stub. This method is optional and can safely be left
300 unimplemented */
302 (void) path;
303 (void) isdatasync;
304 (void) fi;
305 return 0;
308 #ifdef HAVE_SETXATTR
309 /* xattr operations are optional and can safely be left unimplemented */
310 static int xmp_setxattr(const char *path, const char *name, const char *value,
311 size_t size, int flags)
313 int res = lsetxattr(path, name, value, size, flags);
314 if (res == -1)
315 return -errno;
316 return 0;
319 static int xmp_getxattr(const char *path, const char *name, char *value,
320 size_t size)
322 int res = lgetxattr(path, name, value, size);
323 if (res == -1)
324 return -errno;
325 return res;
328 static int xmp_listxattr(const char *path, char *list, size_t size)
330 int res = llistxattr(path, list, size);
331 if (res == -1)
332 return -errno;
333 return res;
336 static int xmp_removexattr(const char *path, const char *name)
338 int res = lremovexattr(path, name);
339 if (res == -1)
340 return -errno;
341 return 0;
343 #endif /* HAVE_SETXATTR */
345 static struct fuse_operations xmp_oper = {
346 .getattr = xmp_getattr,
347 .access = xmp_access,
348 .readlink = xmp_readlink,
349 .readdir = xmp_readdir,
350 .mknod = xmp_mknod,
351 .mkdir = xmp_mkdir,
352 .symlink = xmp_symlink,
353 .unlink = xmp_unlink,
354 .rmdir = xmp_rmdir,
355 .rename = xmp_rename,
356 .link = xmp_link,
357 .chmod = xmp_chmod,
358 .chown = xmp_chown,
359 .truncate = xmp_truncate,
360 .utimes = xmp_utimes,
361 .open = xmp_open,
362 .read = xmp_read,
363 .write = xmp_write,
364 .statfs = xmp_statfs,
365 .release = xmp_release,
366 .fsync = xmp_fsync,
367 #ifdef HAVE_SETXATTR
368 .setxattr = xmp_setxattr,
369 .getxattr = xmp_getxattr,
370 .listxattr = xmp_listxattr,
371 .removexattr= xmp_removexattr,
372 #endif
375 int main(int argc, char *argv[])
377 umask(0);
378 return fuse_main(argc, argv, &xmp_oper, NULL);