~james-w/+junk/fuse-ubuntu-upstream

« back to all changes in this revision

Viewing changes to example/fusexmp_fh.c

  • Committer: James Westby
  • Date: 2008-05-16 12:59:17 UTC
  • Revision ID: jw+debian@jameswestby.net-20080516125917-tp1sifyaxglg2kjk
Tags: upstream-debian-2.7.2, upstream-ubuntu-2.7.2
Import upstream from fuse_2.7.2.orig.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
    gcc -Wall `pkg-config fuse --cflags --libs` -lulockmgr fusexmp_fh.c -o fusexmp_fh
 
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
  gcc -Wall `pkg-config fuse --cflags --libs` -lulockmgr fusexmp_fh.c -o fusexmp_fh
9
9
*/
10
10
 
11
11
#define FUSE_USE_VERSION 26
31
31
 
32
32
static int xmp_getattr(const char *path, struct stat *stbuf)
33
33
{
34
 
    int res;
35
 
 
36
 
    res = lstat(path, stbuf);
37
 
    if (res == -1)
38
 
        return -errno;
39
 
 
40
 
    return 0;
 
34
        int res;
 
35
 
 
36
        res = lstat(path, stbuf);
 
37
        if (res == -1)
 
38
                return -errno;
 
39
 
 
40
        return 0;
41
41
}
42
42
 
43
43
static int xmp_fgetattr(const char *path, struct stat *stbuf,
44
 
                        struct fuse_file_info *fi)
 
44
                        struct fuse_file_info *fi)
45
45
{
46
 
    int res;
47
 
 
48
 
    (void) path;
49
 
 
50
 
    res = fstat(fi->fh, stbuf);
51
 
    if (res == -1)
52
 
        return -errno;
53
 
 
54
 
    return 0;
 
46
        int res;
 
47
 
 
48
        (void) path;
 
49
 
 
50
        res = fstat(fi->fh, stbuf);
 
51
        if (res == -1)
 
52
                return -errno;
 
53
 
 
54
        return 0;
55
55
}
56
56
 
57
57
static int xmp_access(const char *path, int mask)
58
58
{
59
 
    int res;
60
 
 
61
 
    res = access(path, mask);
62
 
    if (res == -1)
63
 
        return -errno;
64
 
 
65
 
    return 0;
 
59
        int res;
 
60
 
 
61
        res = access(path, mask);
 
62
        if (res == -1)
 
63
                return -errno;
 
64
 
 
65
        return 0;
66
66
}
67
67
 
68
68
static int xmp_readlink(const char *path, char *buf, size_t size)
69
69
{
70
 
    int res;
71
 
 
72
 
    res = readlink(path, buf, size - 1);
73
 
    if (res == -1)
74
 
        return -errno;
75
 
 
76
 
    buf[res] = '\0';
77
 
    return 0;
 
70
        int res;
 
71
 
 
72
        res = readlink(path, buf, size - 1);
 
73
        if (res == -1)
 
74
                return -errno;
 
75
 
 
76
        buf[res] = '\0';
 
77
        return 0;
78
78
}
79
79
 
80
80
static int xmp_opendir(const char *path, struct fuse_file_info *fi)
81
81
{
82
 
    DIR *dp = opendir(path);
83
 
    if (dp == NULL)
84
 
        return -errno;
 
82
        DIR *dp = opendir(path);
 
83
        if (dp == NULL)
 
84
                return -errno;
85
85
 
86
 
    fi->fh = (unsigned long) dp;
87
 
    return 0;
 
86
        fi->fh = (unsigned long) dp;
 
87
        return 0;
88
88
}
89
89
 
90
90
static inline DIR *get_dirp(struct fuse_file_info *fi)
91
91
{
92
 
    return (DIR *) (uintptr_t) fi->fh;
 
92
        return (DIR *) (uintptr_t) fi->fh;
93
93
}
94
94
 
95
95
static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
96
 
                       off_t offset, struct fuse_file_info *fi)
 
96
                       off_t offset, struct fuse_file_info *fi)
97
97
{
98
 
    DIR *dp = get_dirp(fi);
99
 
    struct dirent *de;
100
 
 
101
 
    (void) path;
102
 
    seekdir(dp, offset);
103
 
    while ((de = readdir(dp)) != NULL) {
104
 
        struct stat st;
105
 
        memset(&st, 0, sizeof(st));
106
 
        st.st_ino = de->d_ino;
107
 
        st.st_mode = de->d_type << 12;
108
 
        if (filler(buf, de->d_name, &st, telldir(dp)))
109
 
            break;
110
 
    }
111
 
 
112
 
    return 0;
 
98
        DIR *dp = get_dirp(fi);
 
99
        struct dirent *de;
 
100
 
 
101
        (void) path;
 
102
        seekdir(dp, offset);
 
103
        while ((de = readdir(dp)) != NULL) {
 
104
                struct stat st;
 
105
                memset(&st, 0, sizeof(st));
 
106
                st.st_ino = de->d_ino;
 
107
                st.st_mode = de->d_type << 12;
 
108
                if (filler(buf, de->d_name, &st, telldir(dp)))
 
109
                        break;
 
110
        }
 
111
 
 
112
        return 0;
113
113
}
114
114
 
115
115
static int xmp_releasedir(const char *path, struct fuse_file_info *fi)
116
116
{
117
 
    DIR *dp = get_dirp(fi);
118
 
    (void) path;
119
 
    closedir(dp);
120
 
    return 0;
 
117
        DIR *dp = get_dirp(fi);
 
118
        (void) path;
 
119
        closedir(dp);
 
120
        return 0;
121
121
}
122
122
 
123
123
static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
124
124
{
125
 
    int res;
126
 
 
127
 
    if (S_ISFIFO(mode))
128
 
        res = mkfifo(path, mode);
129
 
    else
130
 
        res = mknod(path, mode, rdev);
131
 
    if (res == -1)
132
 
        return -errno;
133
 
 
134
 
    return 0;
 
125
        int res;
 
126
 
 
127
        if (S_ISFIFO(mode))
 
128
                res = mkfifo(path, mode);
 
129
        else
 
130
                res = mknod(path, mode, rdev);
 
131
        if (res == -1)
 
132
                return -errno;
 
133
 
 
134
        return 0;
135
135
}
136
136
 
137
137
static int xmp_mkdir(const char *path, mode_t mode)
138
138
{
139
 
    int res;
140
 
 
141
 
    res = mkdir(path, mode);
142
 
    if (res == -1)
143
 
        return -errno;
144
 
 
145
 
    return 0;
 
139
        int res;
 
140
 
 
141
        res = mkdir(path, mode);
 
142
        if (res == -1)
 
143
                return -errno;
 
144
 
 
145
        return 0;
146
146
}
147
147
 
148
148
static int xmp_unlink(const char *path)
149
149
{
150
 
    int res;
151
 
 
152
 
    res = unlink(path);
153
 
    if (res == -1)
154
 
        return -errno;
155
 
 
156
 
    return 0;
 
150
        int res;
 
151
 
 
152
        res = unlink(path);
 
153
        if (res == -1)
 
154
                return -errno;
 
155
 
 
156
        return 0;
157
157
}
158
158
 
159
159
static int xmp_rmdir(const char *path)
160
160
{
161
 
    int res;
162
 
 
163
 
    res = rmdir(path);
164
 
    if (res == -1)
165
 
        return -errno;
166
 
 
167
 
    return 0;
 
161
        int res;
 
162
 
 
163
        res = rmdir(path);
 
164
        if (res == -1)
 
165
                return -errno;
 
166
 
 
167
        return 0;
168
168
}
169
169
 
170
170
static int xmp_symlink(const char *from, const char *to)
171
171
{
172
 
    int res;
173
 
 
174
 
    res = symlink(from, to);
175
 
    if (res == -1)
176
 
        return -errno;
177
 
 
178
 
    return 0;
 
172
        int res;
 
173
 
 
174
        res = symlink(from, to);
 
175
        if (res == -1)
 
176
                return -errno;
 
177
 
 
178
        return 0;
179
179
}
180
180
 
181
181
static int xmp_rename(const char *from, const char *to)
182
182
{
183
 
    int res;
184
 
 
185
 
    res = rename(from, to);
186
 
    if (res == -1)
187
 
        return -errno;
188
 
 
189
 
    return 0;
 
183
        int res;
 
184
 
 
185
        res = rename(from, to);
 
186
        if (res == -1)
 
187
                return -errno;
 
188
 
 
189
        return 0;
190
190
}
191
191
 
192
192
static int xmp_link(const char *from, const char *to)
193
193
{
194
 
    int res;
195
 
 
196
 
    res = link(from, to);
197
 
    if (res == -1)
198
 
        return -errno;
199
 
 
200
 
    return 0;
 
194
        int res;
 
195
 
 
196
        res = link(from, to);
 
197
        if (res == -1)
 
198
                return -errno;
 
199
 
 
200
        return 0;
201
201
}
202
202
 
203
203
static int xmp_chmod(const char *path, mode_t mode)
204
204
{
205
 
    int res;
206
 
 
207
 
    res = chmod(path, mode);
208
 
    if (res == -1)
209
 
        return -errno;
210
 
 
211
 
    return 0;
 
205
        int res;
 
206
 
 
207
        res = chmod(path, mode);
 
208
        if (res == -1)
 
209
                return -errno;
 
210
 
 
211
        return 0;
212
212
}
213
213
 
214
214
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
215
215
{
216
 
    int res;
217
 
 
218
 
    res = lchown(path, uid, gid);
219
 
    if (res == -1)
220
 
        return -errno;
221
 
 
222
 
    return 0;
 
216
        int res;
 
217
 
 
218
        res = lchown(path, uid, gid);
 
219
        if (res == -1)
 
220
                return -errno;
 
221
 
 
222
        return 0;
223
223
}
224
224
 
225
225
static int xmp_truncate(const char *path, off_t size)
226
226
{
227
 
    int res;
228
 
 
229
 
    res = truncate(path, size);
230
 
    if (res == -1)
231
 
        return -errno;
232
 
 
233
 
    return 0;
 
227
        int res;
 
228
 
 
229
        res = truncate(path, size);
 
230
        if (res == -1)
 
231
                return -errno;
 
232
 
 
233
        return 0;
234
234
}
235
235
 
236
236
static int xmp_ftruncate(const char *path, off_t size,
237
 
                         struct fuse_file_info *fi)
 
237
                         struct fuse_file_info *fi)
238
238
{
239
 
    int res;
240
 
 
241
 
    (void) path;
242
 
 
243
 
    res = ftruncate(fi->fh, size);
244
 
    if (res == -1)
245
 
        return -errno;
246
 
 
247
 
    return 0;
 
239
        int res;
 
240
 
 
241
        (void) path;
 
242
 
 
243
        res = ftruncate(fi->fh, size);
 
244
        if (res == -1)
 
245
                return -errno;
 
246
 
 
247
        return 0;
248
248
}
249
249
 
250
250
static int xmp_utimens(const char *path, const struct timespec ts[2])
251
251
{
252
 
    int res;
253
 
    struct timeval tv[2];
254
 
 
255
 
    tv[0].tv_sec = ts[0].tv_sec;
256
 
    tv[0].tv_usec = ts[0].tv_nsec / 1000;
257
 
    tv[1].tv_sec = ts[1].tv_sec;
258
 
    tv[1].tv_usec = ts[1].tv_nsec / 1000;
259
 
 
260
 
    res = utimes(path, tv);
261
 
    if (res == -1)
262
 
        return -errno;
263
 
 
264
 
    return 0;
 
252
        int res;
 
253
        struct timeval tv[2];
 
254
 
 
255
        tv[0].tv_sec = ts[0].tv_sec;
 
256
        tv[0].tv_usec = ts[0].tv_nsec / 1000;
 
257
        tv[1].tv_sec = ts[1].tv_sec;
 
258
        tv[1].tv_usec = ts[1].tv_nsec / 1000;
 
259
 
 
260
        res = utimes(path, tv);
 
261
        if (res == -1)
 
262
                return -errno;
 
263
 
 
264
        return 0;
265
265
}
266
266
 
267
267
static int xmp_create(const char *path, mode_t mode, struct fuse_file_info *fi)
268
268
{
269
 
    int fd;
270
 
 
271
 
    fd = open(path, fi->flags, mode);
272
 
    if (fd == -1)
273
 
        return -errno;
274
 
 
275
 
    fi->fh = fd;
276
 
    return 0;
 
269
        int fd;
 
270
 
 
271
        fd = open(path, fi->flags, mode);
 
272
        if (fd == -1)
 
273
                return -errno;
 
274
 
 
275
        fi->fh = fd;
 
276
        return 0;
277
277
}
278
278
 
279
279
static int xmp_open(const char *path, struct fuse_file_info *fi)
280
280
{
281
 
    int fd;
282
 
 
283
 
    fd = open(path, fi->flags);
284
 
    if (fd == -1)
285
 
        return -errno;
286
 
 
287
 
    fi->fh = fd;
288
 
    return 0;
 
281
        int fd;
 
282
 
 
283
        fd = open(path, fi->flags);
 
284
        if (fd == -1)
 
285
                return -errno;
 
286
 
 
287
        fi->fh = fd;
 
288
        return 0;
289
289
}
290
290
 
291
291
static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
292
 
                    struct fuse_file_info *fi)
 
292
                    struct fuse_file_info *fi)
293
293
{
294
 
    int res;
295
 
 
296
 
    (void) path;
297
 
    res = pread(fi->fh, buf, size, offset);
298
 
    if (res == -1)
299
 
        res = -errno;
300
 
 
301
 
    return res;
 
294
        int res;
 
295
 
 
296
        (void) path;
 
297
        res = pread(fi->fh, buf, size, offset);
 
298
        if (res == -1)
 
299
                res = -errno;
 
300
 
 
301
        return res;
302
302
}
303
303
 
304
304
static int xmp_write(const char *path, const char *buf, size_t size,
305
 
                     off_t offset, struct fuse_file_info *fi)
 
305
                     off_t offset, struct fuse_file_info *fi)
306
306
{
307
 
    int res;
308
 
 
309
 
    (void) path;
310
 
    res = pwrite(fi->fh, buf, size, offset);
311
 
    if (res == -1)
312
 
        res = -errno;
313
 
 
314
 
    return res;
 
307
        int res;
 
308
 
 
309
        (void) path;
 
310
        res = pwrite(fi->fh, buf, size, offset);
 
311
        if (res == -1)
 
312
                res = -errno;
 
313
 
 
314
        return res;
315
315
}
316
316
 
317
317
static int xmp_statfs(const char *path, struct statvfs *stbuf)
318
318
{
319
 
    int res;
320
 
 
321
 
    res = statvfs(path, stbuf);
322
 
    if (res == -1)
323
 
        return -errno;
324
 
 
325
 
    return 0;
 
319
        int res;
 
320
 
 
321
        res = statvfs(path, stbuf);
 
322
        if (res == -1)
 
323
                return -errno;
 
324
 
 
325
        return 0;
326
326
}
327
327
 
328
328
static int xmp_flush(const char *path, struct fuse_file_info *fi)
329
329
{
330
 
    int res;
331
 
 
332
 
    (void) path;
333
 
    /* This is called from every close on an open file, so call the
334
 
       close on the underlying filesystem.  But since flush may be
335
 
       called multiple times for an open file, this must not really
336
 
       close the file.  This is important if used on a network
337
 
       filesystem like NFS which flush the data/metadata on close() */
338
 
    res = close(dup(fi->fh));
339
 
    if (res == -1)
340
 
        return -errno;
341
 
 
342
 
    return 0;
 
330
        int res;
 
331
 
 
332
        (void) path;
 
333
        /* This is called from every close on an open file, so call the
 
334
           close on the underlying filesystem.  But since flush may be
 
335
           called multiple times for an open file, this must not really
 
336
           close the file.  This is important if used on a network
 
337
           filesystem like NFS which flush the data/metadata on close() */
 
338
        res = close(dup(fi->fh));
 
339
        if (res == -1)
 
340
                return -errno;
 
341
 
 
342
        return 0;
343
343
}
344
344
 
345
345
static int xmp_release(const char *path, struct fuse_file_info *fi)
346
346
{
347
 
    (void) path;
348
 
    close(fi->fh);
 
347
        (void) path;
 
348
        close(fi->fh);
349
349
 
350
 
    return 0;
 
350
        return 0;
351
351
}
352
352
 
353
353
static int xmp_fsync(const char *path, int isdatasync,
354
 
                     struct fuse_file_info *fi)
 
354
                     struct fuse_file_info *fi)
355
355
{
356
 
    int res;
357
 
    (void) path;
 
356
        int res;
 
357
        (void) path;
358
358
 
359
359
#ifndef HAVE_FDATASYNC
360
 
    (void) isdatasync;
 
360
        (void) isdatasync;
361
361
#else
362
 
    if (isdatasync)
363
 
        res = fdatasync(fi->fh);
364
 
    else
 
362
        if (isdatasync)
 
363
                res = fdatasync(fi->fh);
 
364
        else
365
365
#endif
366
 
        res = fsync(fi->fh);
367
 
    if (res == -1)
368
 
        return -errno;
 
366
                res = fsync(fi->fh);
 
367
        if (res == -1)
 
368
                return -errno;
369
369
 
370
 
    return 0;
 
370
        return 0;
371
371
}
372
372
 
373
373
#ifdef HAVE_SETXATTR
374
374
/* xattr operations are optional and can safely be left unimplemented */
375
375
static int xmp_setxattr(const char *path, const char *name, const char *value,
376
 
                        size_t size, int flags)
 
376
                        size_t size, int flags)
377
377
{
378
 
    int res = lsetxattr(path, name, value, size, flags);
379
 
    if (res == -1)
380
 
        return -errno;
381
 
    return 0;
 
378
        int res = lsetxattr(path, name, value, size, flags);
 
379
        if (res == -1)
 
380
                return -errno;
 
381
        return 0;
382
382
}
383
383
 
384
384
static int xmp_getxattr(const char *path, const char *name, char *value,
385
 
                    size_t size)
 
385
                        size_t size)
386
386
{
387
 
    int res = lgetxattr(path, name, value, size);
388
 
    if (res == -1)
389
 
        return -errno;
390
 
    return res;
 
387
        int res = lgetxattr(path, name, value, size);
 
388
        if (res == -1)
 
389
                return -errno;
 
390
        return res;
391
391
}
392
392
 
393
393
static int xmp_listxattr(const char *path, char *list, size_t size)
394
394
{
395
 
    int res = llistxattr(path, list, size);
396
 
    if (res == -1)
397
 
        return -errno;
398
 
    return res;
 
395
        int res = llistxattr(path, list, size);
 
396
        if (res == -1)
 
397
                return -errno;
 
398
        return res;
399
399
}
400
400
 
401
401
static int xmp_removexattr(const char *path, const char *name)
402
402
{
403
 
    int res = lremovexattr(path, name);
404
 
    if (res == -1)
405
 
        return -errno;
406
 
    return 0;
 
403
        int res = lremovexattr(path, name);
 
404
        if (res == -1)
 
405
                return -errno;
 
406
        return 0;
407
407
}
408
408
#endif /* HAVE_SETXATTR */
409
409
 
410
410
static int xmp_lock(const char *path, struct fuse_file_info *fi, int cmd,
411
 
                    struct flock *lock)
 
411
                    struct flock *lock)
412
412
{
413
 
    (void) path;
 
413
        (void) path;
414
414
 
415
 
    return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
416
 
                       sizeof(fi->lock_owner));
 
415
        return ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner,
 
416
                           sizeof(fi->lock_owner));
417
417
}
418
418
 
419
419
static struct fuse_operations xmp_oper = {
420
 
    .getattr    = xmp_getattr,
421
 
    .fgetattr   = xmp_fgetattr,
422
 
    .access     = xmp_access,
423
 
    .readlink   = xmp_readlink,
424
 
    .opendir    = xmp_opendir,
425
 
    .readdir    = xmp_readdir,
426
 
    .releasedir = xmp_releasedir,
427
 
    .mknod      = xmp_mknod,
428
 
    .mkdir      = xmp_mkdir,
429
 
    .symlink    = xmp_symlink,
430
 
    .unlink     = xmp_unlink,
431
 
    .rmdir      = xmp_rmdir,
432
 
    .rename     = xmp_rename,
433
 
    .link       = xmp_link,
434
 
    .chmod      = xmp_chmod,
435
 
    .chown      = xmp_chown,
436
 
    .truncate   = xmp_truncate,
437
 
    .ftruncate  = xmp_ftruncate,
438
 
    .utimens    = xmp_utimens,
439
 
    .create     = xmp_create,
440
 
    .open       = xmp_open,
441
 
    .read       = xmp_read,
442
 
    .write      = xmp_write,
443
 
    .statfs     = xmp_statfs,
444
 
    .flush      = xmp_flush,
445
 
    .release    = xmp_release,
446
 
    .fsync      = xmp_fsync,
 
420
        .getattr        = xmp_getattr,
 
421
        .fgetattr       = xmp_fgetattr,
 
422
        .access         = xmp_access,
 
423
        .readlink       = xmp_readlink,
 
424
        .opendir        = xmp_opendir,
 
425
        .readdir        = xmp_readdir,
 
426
        .releasedir     = xmp_releasedir,
 
427
        .mknod          = xmp_mknod,
 
428
        .mkdir          = xmp_mkdir,
 
429
        .symlink        = xmp_symlink,
 
430
        .unlink         = xmp_unlink,
 
431
        .rmdir          = xmp_rmdir,
 
432
        .rename         = xmp_rename,
 
433
        .link           = xmp_link,
 
434
        .chmod          = xmp_chmod,
 
435
        .chown          = xmp_chown,
 
436
        .truncate       = xmp_truncate,
 
437
        .ftruncate      = xmp_ftruncate,
 
438
        .utimens        = xmp_utimens,
 
439
        .create         = xmp_create,
 
440
        .open           = xmp_open,
 
441
        .read           = xmp_read,
 
442
        .write          = xmp_write,
 
443
        .statfs         = xmp_statfs,
 
444
        .flush          = xmp_flush,
 
445
        .release        = xmp_release,
 
446
        .fsync          = xmp_fsync,
447
447
#ifdef HAVE_SETXATTR
448
 
    .setxattr   = xmp_setxattr,
449
 
    .getxattr   = xmp_getxattr,
450
 
    .listxattr  = xmp_listxattr,
451
 
    .removexattr= xmp_removexattr,
 
448
        .setxattr       = xmp_setxattr,
 
449
        .getxattr       = xmp_getxattr,
 
450
        .listxattr      = xmp_listxattr,
 
451
        .removexattr    = xmp_removexattr,
452
452
#endif
453
 
    .lock       = xmp_lock,
 
453
        .lock           = xmp_lock,
454
454
};
455
455
 
456
456
int main(int argc, char *argv[])
457
457
{
458
 
    umask(0);
459
 
    return fuse_main(argc, argv, &xmp_oper, NULL);
 
458
        umask(0);
 
459
        return fuse_main(argc, argv, &xmp_oper, NULL);
460
460
}