/[fuse_dbi]/fuse/trunk/python/_fusemodule.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /fuse/trunk/python/_fusemodule.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Wed Aug 4 11:40:49 2004 UTC (19 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 11700 byte(s)
copy CVS to trunk

1 //@+leo-ver=4
2 //@+node:@file _fusemodule.c
3 //@@language c
4 /*
5 Copyright (C) 2001 Jeff Epler <jepler@unpythonic.dhs.org>
6
7 This program can be distributed under the terms of the GNU GPL.
8 See the file COPYING.
9 */
10
11 //@+others
12 //@+node:includes
13 #include <Python.h>
14 #include "fuse.h"
15 #include <time.h>
16 //@-node:includes
17 //@+node:globals
18
19 static PyObject *getattr_cb=NULL, *readlink_cb=NULL, *getdir_cb=NULL,
20 *mknod_cb=NULL, *mkdir_cb=NULL, *unlink_cb=NULL, *rmdir_cb=NULL,
21 *symlink_cb=NULL, *rename_cb=NULL, *link_cb=NULL, *chmod_cb=NULL,
22 *chown_cb=NULL, *truncate_cb=NULL, *utime_cb=NULL,
23 *open_cb=NULL, *read_cb=NULL, *write_cb=NULL, *release_cb=NULL,
24 *statfs_cb=NULL, *fsync_cb=NULL
25 ;
26 //@-node:globals
27 //@+node:PROLOGUE
28 #define PROLOGUE \
29 int ret = -EINVAL; \
30 if (!v) { PyErr_Print(); goto OUT; } \
31 if(v == Py_None) { ret = 0; goto OUT_DECREF; } \
32 if(PyInt_Check(v)) { ret = PyInt_AsLong(v); goto OUT_DECREF; }
33
34 //@-node:PROLOGUE
35 //@+node:EPILOGUE
36 #define EPILOGUE \
37 OUT_DECREF: \
38 Py_DECREF(v); \
39 OUT: \
40 return ret;
41 //@-node:EPILOGUE
42 //@+node:getattr_func
43
44 /*
45 * Local Variables:
46 * indent-tabs-mode: t
47 * c-basic-offset: 8
48 * End:
49 * Changed by David McNab (david@rebirthing.co.nz) to work with recent pythons.
50 * Namely, replacing PyTuple_* with PySequence_*, and checking numerical values
51 * with both PyInt_Check and PyLong_Check.
52 */
53
54 static int getattr_func(const char *path, struct stat *st)
55 {
56 int i;
57 PyObject *v = PyObject_CallFunction(getattr_cb, "s", path);
58 PROLOGUE
59
60 if(!PySequence_Check(v)) { goto OUT_DECREF; }
61 if(PySequence_Size(v) < 10) { goto OUT_DECREF; }
62 for(i=0; i<10; i++)
63 {
64 PyObject *tmp = PySequence_GetItem(v, i);
65 if (!(PyInt_Check(tmp) || PyLong_Check(tmp))) goto OUT_DECREF;
66 }
67
68 st->st_mode = PyInt_AsLong(PySequence_GetItem(v, 0));
69 st->st_ino = PyInt_AsLong(PySequence_GetItem(v, 1));
70 st->st_dev = PyInt_AsLong(PySequence_GetItem(v, 2));
71 st->st_nlink= PyInt_AsLong(PySequence_GetItem(v, 3));
72 st->st_uid = PyInt_AsLong(PySequence_GetItem(v, 4));
73 st->st_gid = PyInt_AsLong(PySequence_GetItem(v, 5));
74 st->st_size = PyInt_AsLong(PySequence_GetItem(v, 6));
75 st->st_atime= PyInt_AsLong(PySequence_GetItem(v, 7));
76 st->st_mtime= PyInt_AsLong(PySequence_GetItem(v, 8));
77 st->st_ctime= PyInt_AsLong(PySequence_GetItem(v, 9));
78
79 /* Fill in fields not provided by Python lstat() */
80 st->st_blksize= 4096;
81 st->st_blocks= (st->st_size + 511)/512;
82 st->st_ino = 0;
83
84 ret = 0;
85 EPILOGUE
86 }
87
88 //@-node:getattr_func
89 //@+node:readlink_func
90
91 static int readlink_func(const char *path, char *link, size_t size)
92 {
93 PyObject *v = PyObject_CallFunction(readlink_cb, "s", path);
94 char *s;
95 PROLOGUE
96
97 if(!PyString_Check(v)) { ret = -EINVAL; goto OUT_DECREF; }
98 s = PyString_AsString(v);
99 strncpy(link, s, size);
100 link[size-1] = '\0';
101 ret = 0;
102
103 EPILOGUE
104 }
105 //@-node:readlink_func
106 //@+node:getdir_add_entry
107
108 static int getdir_add_entry(PyObject *w, fuse_dirh_t dh, fuse_dirfil_t df)
109 {
110 PyObject *o0;
111 PyObject *o1;
112 int ret = -EINVAL;
113
114 if(!PySequence_Check(w)) {
115 printf("getdir item not sequence\n");
116 goto out;
117 }
118 if(PySequence_Length(w) != 2) {
119 printf("getdir item not len 2\n");
120 goto out;
121 }
122 o0 = PySequence_GetItem(w, 0);
123 o1 = PySequence_GetItem(w, 1);
124
125 if(!PyString_Check(o0)) {
126 printf("getdir item[0] not string\n");
127 goto out_decref;
128 }
129 if(!PyInt_Check(o1)) {
130 printf("getdir item[1] not int\n");
131 goto out_decref;
132 }
133
134 ret = df(dh, PyString_AsString(o0), PyInt_AsLong(o1));
135
136 out_decref:
137 Py_DECREF(o0);
138 Py_DECREF(o1);
139
140 out:
141 return ret;
142 }
143 //@-node:getdir_add_entry
144 //@+node:getdir_func
145
146 static int getdir_func(const char *path, fuse_dirh_t dh, fuse_dirfil_t df)
147 {
148 PyObject *v = PyObject_CallFunction(getdir_cb, "s", path);
149 int i;
150 PROLOGUE
151
152 if(!PySequence_Check(v)) {
153 printf("getdir_func not sequence\n");
154 goto OUT_DECREF;
155 }
156 for(i=0; i < PySequence_Length(v); i++) {
157 PyObject *w = PySequence_GetItem(v, i);
158 ret = getdir_add_entry(w, dh, df);
159 Py_DECREF(w);
160 if(ret != 0)
161 goto OUT_DECREF;
162 }
163 ret = 0;
164
165 EPILOGUE
166 }
167 //@-node:getdir_func
168 //@+node:mknod_func
169
170 static int mknod_func(const char *path, mode_t m, dev_t d)
171 {
172 PyObject *v = PyObject_CallFunction(mknod_cb, "sii", path, m, d);
173 PROLOGUE
174 EPILOGUE
175 }
176 //@-node:mknod_func
177 //@+node:mkdir_func
178
179 static int mkdir_func(const char *path, mode_t m)
180 {
181 PyObject *v = PyObject_CallFunction(mkdir_cb, "si", path, m);
182 PROLOGUE
183 EPILOGUE
184 }
185 //@-node:mkdir_func
186 //@+node:unlink_func
187
188 static int unlink_func(const char *path)
189 {
190 PyObject *v = PyObject_CallFunction(unlink_cb, "s", path);
191 PROLOGUE
192 EPILOGUE
193 }
194 //@-node:unlink_func
195 //@+node:rmdir_func
196
197 static int rmdir_func(const char *path)
198 {
199 PyObject *v = PyObject_CallFunction(rmdir_cb, "s", path);
200 PROLOGUE
201 EPILOGUE
202 }
203 //@-node:rmdir_func
204 //@+node:symlink_func
205
206 static int symlink_func(const char *path, const char *path1)
207 {
208 PyObject *v = PyObject_CallFunction(symlink_cb, "ss", path, path1);
209 PROLOGUE
210 EPILOGUE
211 }
212 //@-node:symlink_func
213 //@+node:rename_func
214
215 static int rename_func(const char *path, const char *path1)
216 {
217 PyObject *v = PyObject_CallFunction(rename_cb, "ss", path, path1);
218 PROLOGUE
219 EPILOGUE
220 }
221 //@-node:rename_func
222 //@+node:link_func
223
224 static int link_func(const char *path, const char *path1)
225 {
226 PyObject *v = PyObject_CallFunction(link_cb, "ss", path, path1);
227 PROLOGUE
228 EPILOGUE
229 }
230 //@-node:link_func
231 //@+node:chmod_func
232
233 static int chmod_func(const char *path, mode_t m)
234 {
235 PyObject *v = PyObject_CallFunction(chmod_cb, "si", path, m);
236 PROLOGUE
237 EPILOGUE
238 }
239 //@-node:chmod_func
240 //@+node:chown_func
241
242 static int chown_func(const char *path, uid_t u, gid_t g)
243 {
244 PyObject *v = PyObject_CallFunction(chown_cb, "sii", path, u, g);
245 PROLOGUE
246 EPILOGUE
247 }
248 //@-node:chown_func
249 //@+node:truncate_func
250
251 static int truncate_func(const char *path, off_t o)
252 {
253 PyObject *v = PyObject_CallFunction(truncate_cb, "si", path, o);
254 PROLOGUE
255 EPILOGUE
256 }
257 //@-node:truncate_func
258 //@+node:utime_func
259
260 static int utime_func(const char *path, struct utimbuf *u) {
261 int actime = u ? u->actime : time(NULL);
262 int modtime = u ? u->modtime : actime;
263 PyObject *v = PyObject_CallFunction(utime_cb, "s(ii)",
264 path, actime, modtime);
265 PROLOGUE
266 EPILOGUE
267 }
268 //@-node:utime_func
269 //@+node:read_func
270
271 static int read_func(const char *path, char *buf, size_t s, off_t off)
272 {
273 PyObject *v = PyObject_CallFunction(read_cb, "sii", path, s, off);
274 PROLOGUE
275 if(PyString_Check(v)) {
276 if(PyString_Size(v) > s) goto OUT_DECREF;
277 memcpy(buf, PyString_AsString(v), PyString_Size(v));
278 ret = PyString_Size(v);
279 }
280 EPILOGUE
281 }
282 //@-node:read_func
283 //@+node:write_func
284
285 static int write_func(const char *path, const char *buf, size_t t, off_t off)
286 {
287 PyObject *v = PyObject_CallFunction(write_cb,"ss#i", path, buf, t, off);
288 PROLOGUE
289 EPILOGUE
290 }
291 //@-node:write_func
292 //@+node:open_func
293
294 static int open_func(const char *path, int mode)
295 {
296 PyObject *v = PyObject_CallFunction(open_cb, "si", path, mode);
297 PROLOGUE
298 printf("open_func: path=%s\n", path);
299 EPILOGUE
300 }
301 //@-node:open_func
302 //@+node:release_func
303 static int release_func(const char *path, int flags)
304 {
305 PyObject *v = PyObject_CallFunction(release_cb, "si", path, flags);
306 PROLOGUE
307 //printf("release_func: path=%s flags=%d\n", path, flags);
308 EPILOGUE
309 }
310 //@-node:release_func
311 //@+node:statfs_func
312 static int statfs_func(struct fuse_statfs *fst)
313 {
314 int i;
315 long retvalues[6];
316 PyObject *v = PyObject_CallFunction(statfs_cb, "");
317 PROLOGUE
318
319 if (!PySequence_Check(v))
320 { goto OUT_DECREF; }
321 if (PySequence_Size(v) < 6)
322 { goto OUT_DECREF; }
323 for(i=0; i<6; i++)
324 {
325 PyObject *tmp = PySequence_GetItem(v, i);
326 retvalues[i] = PyInt_Check(tmp)
327 ? PyInt_AsLong(tmp)
328 : (PyLong_Check(tmp)
329 ? PyLong_AsLong(tmp)
330 : 0);
331 }
332
333 fst->block_size = retvalues[0];
334 fst->blocks = retvalues[1];
335 fst->blocks_free = retvalues[2];
336 fst->files = retvalues[3];
337 fst->files_free = retvalues[4];
338 fst->namelen = retvalues[5];
339 ret = 0;
340
341 #ifdef IGNORE_THIS
342 printf("block_size=%ld, blocks=%ld, blocks_free=%ld, files=%ld, files_free=%ld, namelen=%ld\n",
343 retvalues[0], retvalues[1], retvalues[2], retvalues[3], retvalues[4], retvalues[5]);
344 #endif
345
346 EPILOGUE
347
348 }
349
350 //@-node:statfs_func
351 //@+node:fsync_func
352 static int fsync_func(const char *path, int isfsyncfile)
353 {
354 PyObject *v = PyObject_CallFunction(fsync_cb, "si", path, isfsyncfile);
355 PROLOGUE
356 EPILOGUE
357 }
358
359 //@-node:fsync_func
360 //@+node:process_cmd
361
362 static void process_cmd(struct fuse *f, struct fuse_cmd *cmd, void *data)
363 {
364 PyInterpreterState *interp = (PyInterpreterState *) data;
365 PyThreadState *state;
366
367 PyEval_AcquireLock();
368 state = PyThreadState_New(interp);
369 PyThreadState_Swap(state);
370 __fuse_process_cmd(f, cmd);
371 PyThreadState_Clear(state);
372 PyThreadState_Swap(NULL);
373 PyThreadState_Delete(state);
374 PyEval_ReleaseLock();
375 }
376 //@-node:process_cmd
377 //@+node:pyfuse_loop_mt
378
379 static void pyfuse_loop_mt(struct fuse *f)
380 {
381 PyInterpreterState *interp;
382 PyThreadState *save;
383
384 PyEval_InitThreads();
385 interp = PyThreadState_Get()->interp;
386 save = PyEval_SaveThread();
387 __fuse_loop_mt(f, process_cmd, interp);
388 /* Not yet reached: */
389 PyEval_RestoreThread(save);
390 }
391 //@-node:pyfuse_loop_mt
392 //@+node:Fuse_main
393
394
395 static PyObject *
396 Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
397 {
398 int flags=0;
399 int multithreaded=0;
400 static struct fuse *fuse=NULL;
401
402 struct fuse_operations op;
403
404 static char *kwlist[] = {
405 "getattr", "readlink", "getdir", "mknod",
406 "mkdir", "unlink", "rmdir", "symlink", "rename",
407 "link", "chmod", "chown", "truncate", "utime",
408 "open", "read", "write", "release", "statfs", "fsync",
409 "flags", "multithreaded", NULL};
410
411 memset(&op, 0, sizeof(op));
412
413 if (!PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOOOOOOOOOOOOOOOii",
414 kwlist, &getattr_cb, &readlink_cb, &getdir_cb, &mknod_cb,
415 &mkdir_cb, &unlink_cb, &rmdir_cb, &symlink_cb, &rename_cb,
416 &link_cb, &chmod_cb, &chown_cb, &truncate_cb, &utime_cb,
417 &open_cb, &read_cb, &write_cb, &release_cb, &statfs_cb, &fsync_cb,
418 &flags, &multithreaded))
419 return NULL;
420
421 #define DO_ONE_ATTR(name) if(name ## _cb) { Py_INCREF(name ## _cb); op.name = name ## _func; } else { op.name = NULL; }
422
423 DO_ONE_ATTR(getattr);
424 DO_ONE_ATTR(readlink);
425 DO_ONE_ATTR(getdir);
426 DO_ONE_ATTR(mknod);
427 DO_ONE_ATTR(mkdir);
428 DO_ONE_ATTR(unlink);
429 DO_ONE_ATTR(rmdir);
430 DO_ONE_ATTR(symlink);
431 DO_ONE_ATTR(rename);
432 DO_ONE_ATTR(link);
433 DO_ONE_ATTR(chmod);
434 DO_ONE_ATTR(chown);
435 DO_ONE_ATTR(truncate);
436 DO_ONE_ATTR(utime);
437 DO_ONE_ATTR(open);
438 DO_ONE_ATTR(read);
439 DO_ONE_ATTR(write);
440 DO_ONE_ATTR(release);
441 DO_ONE_ATTR(statfs);
442 DO_ONE_ATTR(fsync);
443
444 fuse = fuse_new(0, flags, &op);
445 if(multithreaded)
446 pyfuse_loop_mt(fuse);
447 else
448 fuse_loop(fuse);
449
450 //printf("Fuse_main: called\n");
451
452 Py_INCREF(Py_None);
453 return Py_None;
454 }
455 //@-node:Fuse_main
456 //@+node:DL_EXPORT
457 //@+at
458 //@nonl
459 // List of functions defined in the module
460 //@-at
461 //@@c
462
463 static PyMethodDef Fuse_methods[] = {
464 {"main", (PyCFunction)Fuse_main, METH_VARARGS|METH_KEYWORDS},
465 {NULL, NULL} /* sentinel */
466 };
467
468
469 /* Initialization function for the module (*must* be called init_fuse) */
470
471 DL_EXPORT(void)
472 init_fuse(void)
473 {
474 PyObject *m, *d;
475 static PyObject *ErrorObject;
476
477 /* Create the module and add the functions */
478 m = Py_InitModule("_fuse", Fuse_methods);
479
480 /* Add some symbolic constants to the module */
481 d = PyModule_GetDict(m);
482 ErrorObject = PyErr_NewException("fuse.error", NULL, NULL);
483 PyDict_SetItemString(d, "error", ErrorObject);
484 PyDict_SetItemString(d, "DEBUG", PyInt_FromLong(FUSE_DEBUG));
485 }
486 //@-node:DL_EXPORT
487 //@-others
488
489 //@-node:@file _fusemodule.c
490 //@-leo

  ViewVC Help
Powered by ViewVC 1.1.26