/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 dpavlin 4 //@+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