27 | 27 |
#include <Python.h>
|
28 | 28 |
#include <fuse.h>
|
29 | 29 |
#include <sys/ioctl.h>
|
|
30 |
#ifndef _UAPI_ASM_GENERIC_IOCTL_H
|
|
31 |
/* Essential IOCTL definitions from Linux /include/uapi/asm-generic/ioctl.h
|
|
32 |
to fix compilation errors on FreeBSD
|
|
33 |
Mikhail Zakharov <zmey20000@thoo.com> 2018.10.22 */
|
|
34 |
|
|
35 |
#define _IOC_NRBITS 8
|
|
36 |
#define _IOC_TYPEBITS 8
|
|
37 |
|
|
38 |
#ifndef _IOC_SIZEBITS
|
|
39 |
# define _IOC_SIZEBITS 14
|
|
40 |
#endif
|
|
41 |
|
|
42 |
#ifndef _IOC_DIRBITS
|
|
43 |
# define _IOC_DIRBITS 2
|
|
44 |
#endif
|
|
45 |
|
|
46 |
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
|
|
47 |
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
|
|
48 |
|
|
49 |
#define _IOC_NRSHIFT 0
|
|
50 |
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
|
|
51 |
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
|
|
52 |
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
|
|
53 |
|
|
54 |
#ifndef _IOC_NONE
|
|
55 |
# define _IOC_NONE 0U
|
|
56 |
#endif
|
|
57 |
|
|
58 |
#ifndef _IOC_WRITE
|
|
59 |
# define _IOC_WRITE 1U
|
|
60 |
#endif
|
|
61 |
|
|
62 |
#ifndef _IOC_READ
|
|
63 |
# define _IOC_READ 2U
|
|
64 |
#endif
|
|
65 |
|
|
66 |
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
|
|
67 |
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
|
|
68 |
#endif
|
30 | 69 |
|
31 | 70 |
|
32 | 71 |
#ifndef FUSE_VERSION
|
|
57 | 96 |
*releasedir_cb=NULL, *fsyncdir_cb=NULL, *flush_cb=NULL, *ftruncate_cb=NULL,
|
58 | 97 |
*fgetattr_cb=NULL, *getxattr_cb=NULL, *listxattr_cb=NULL, *setxattr_cb=NULL,
|
59 | 98 |
*removexattr_cb=NULL, *access_cb=NULL, *lock_cb = NULL, *utimens_cb = NULL,
|
60 | |
*bmap_cb = NULL, *fsinit_cb=NULL, *fsdestroy_cb = NULL, *ioctl_cb = NULL;
|
|
99 |
*bmap_cb = NULL, *fsinit_cb=NULL, *fsdestroy_cb = NULL, *ioctl_cb = NULL,
|
|
100 |
*poll_cb = NULL;
|
61 | 101 |
|
62 | 102 |
|
63 | 103 |
static PyObject *Py_FuseError;
|
|
516 | 556 |
PROLOGUE( PYO_CALLWITHFI(fi, read_cb, snK, path, s, off) )
|
517 | 557 |
#endif
|
518 | 558 |
|
|
559 |
|
|
560 |
#if PY_MAJOR_VERSION >= 3
|
|
561 |
if(PyBytes_Check(v)) {
|
|
562 |
if(PyBytes_Size(v) > s)
|
|
563 |
goto OUT_DECREF;
|
|
564 |
memcpy(buf, PyBytes_AsString(v), PyBytes_Size(v));
|
|
565 |
ret = PyBytes_Size(v);
|
|
566 |
}
|
|
567 |
#else
|
519 | 568 |
if(PyString_Check(v)) {
|
520 | 569 |
if(PyString_Size(v) > s)
|
521 | 570 |
goto OUT_DECREF;
|
522 | 571 |
memcpy(buf, PyString_AsString(v), PyString_Size(v));
|
523 | 572 |
ret = PyString_Size(v);
|
524 | 573 |
}
|
|
574 |
#endif
|
525 | 575 |
|
526 | 576 |
EPILOGUE
|
527 | 577 |
}
|
|
535 | 585 |
write_func(const char *path, const char *buf, size_t t, off_t off)
|
536 | 586 |
#endif
|
537 | 587 |
{
|
|
588 |
#if PY_MAJOR_VERSION >= 3
|
|
589 |
PROLOGUE( PYO_CALLWITHFI(fi, write_cb, sy#K, path, buf, t, off) )
|
|
590 |
#else
|
538 | 591 |
PROLOGUE( PYO_CALLWITHFI(fi, write_cb, ss#K, path, buf, t, off) )
|
|
592 |
#endif
|
539 | 593 |
EPILOGUE
|
540 | 594 |
}
|
541 | 595 |
|
|
990 | 1044 |
}
|
991 | 1045 |
EPILOGUE
|
992 | 1046 |
}
|
|
1047 |
|
|
1048 |
static const char pollhandle_name[] = "pollhandle";
|
|
1049 |
|
|
1050 |
static void
|
|
1051 |
pollhandle_destructor(PyObject *p)
|
|
1052 |
{
|
|
1053 |
struct fuse_pollhandle *ph;
|
|
1054 |
|
|
1055 |
ph = PyCapsule_GetPointer(p, pollhandle_name);
|
|
1056 |
fuse_pollhandle_destroy(ph);
|
|
1057 |
}
|
|
1058 |
|
|
1059 |
static int
|
|
1060 |
poll_func(const char *path, struct fuse_file_info *fi,
|
|
1061 |
struct fuse_pollhandle *ph, unsigned *reventsp)
|
|
1062 |
{
|
|
1063 |
PyObject *pollhandle = Py_None;
|
|
1064 |
|
|
1065 |
if (ph)
|
|
1066 |
pollhandle = PyCapsule_New(ph, pollhandle_name, pollhandle_destructor);
|
|
1067 |
|
|
1068 |
PROLOGUE(PYO_CALLWITHFI(fi, poll_cb, sO, path, pollhandle));
|
|
1069 |
|
|
1070 |
OUT_DECREF:
|
|
1071 |
Py_DECREF(v);
|
|
1072 |
OUT:
|
|
1073 |
if (ph)
|
|
1074 |
Py_DECREF(pollhandle);
|
|
1075 |
|
|
1076 |
PYUNLOCK();
|
|
1077 |
|
|
1078 |
if (ret > 0) {
|
|
1079 |
*reventsp = ret;
|
|
1080 |
ret = 0;
|
|
1081 |
}
|
|
1082 |
|
|
1083 |
return ret;
|
|
1084 |
}
|
993 | 1085 |
#endif
|
994 | 1086 |
|
995 | 1087 |
static int
|
|
1035 | 1127 |
"create", "opendir", "releasedir", "fsyncdir", "flush",
|
1036 | 1128 |
"ftruncate", "fgetattr", "getxattr", "listxattr", "setxattr",
|
1037 | 1129 |
"removexattr", "access", "lock", "utimens", "bmap",
|
1038 | |
"fsinit", "fsdestroy", "ioctl", "fuse_args", "multithreaded", NULL
|
|
1130 |
"fsinit", "fsdestroy", "ioctl", "poll", "fuse_args",
|
|
1131 |
"multithreaded", NULL
|
1039 | 1132 |
};
|
1040 | 1133 |
|
1041 | 1134 |
memset(&op, 0, sizeof(op));
|
1042 | 1135 |
|
1043 | 1136 |
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
1044 | |
"|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOi",
|
|
1137 |
"|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOi",
|
1045 | 1138 |
kwlist, &getattr_cb, &readlink_cb,
|
1046 | 1139 |
&readdir_cb, &mknod_cb, &mkdir_cb,
|
1047 | 1140 |
&unlink_cb, &rmdir_cb, &symlink_cb,
|
|
1057 | 1150 |
&removexattr_cb, &access_cb,
|
1058 | 1151 |
&lock_cb, &utimens_cb, &bmap_cb,
|
1059 | 1152 |
&fsinit_cb, &fsdestroy_cb, &ioctl_cb,
|
1060 | |
&fargseq, &multithreaded))
|
|
1153 |
&poll_cb, &fargseq, &multithreaded))
|
1061 | 1154 |
return NULL;
|
1062 | 1155 |
|
1063 | 1156 |
#define DO_ONE_ATTR_AS(fname, pyname) \
|
|
1119 | 1212 |
#endif
|
1120 | 1213 |
#if FUSE_VERSION >= 28
|
1121 | 1214 |
DO_ONE_ATTR(ioctl);
|
|
1215 |
DO_ONE_ATTR(poll);
|
1122 | 1216 |
#endif
|
1123 | 1217 |
|
1124 | 1218 |
#undef DO_ONE_ATTR
|
|
1281 | 1375 |
return favers;
|
1282 | 1376 |
}
|
1283 | 1377 |
|
|
1378 |
static const char FuseNotifyPoll__doc__[] = "Notify IO readiness event.";
|
|
1379 |
|
|
1380 |
static PyObject *
|
|
1381 |
FuseNotifyPoll(PyObject *self, PyObject *arg)
|
|
1382 |
{
|
|
1383 |
struct fuse_pollhandle *ph;
|
|
1384 |
int ret;
|
|
1385 |
|
|
1386 |
ph = PyCapsule_GetPointer(arg, pollhandle_name);
|
|
1387 |
if (!ph) {
|
|
1388 |
PyErr_SetString(PyExc_TypeError,
|
|
1389 |
"pollhandle is not a FUSE poll handle");
|
|
1390 |
return NULL;
|
|
1391 |
}
|
|
1392 |
|
|
1393 |
ret = fuse_notify_poll(ph);
|
|
1394 |
|
|
1395 |
return PyInt_FromLong(ret);
|
|
1396 |
}
|
|
1397 |
|
1284 | 1398 |
static PyMethodDef Fuse_methods[] = {
|
1285 | 1399 |
{"main", (PyCFunction)Fuse_main, METH_VARARGS|METH_KEYWORDS},
|
1286 | 1400 |
{"FuseGetContext", (PyCFunction)FuseGetContext, METH_VARARGS, FuseGetContext__doc__},
|
1287 | 1401 |
{"FuseInvalidate", (PyCFunction)FuseInvalidate, METH_VARARGS, FuseInvalidate__doc__},
|
1288 | 1402 |
{"FuseAPIVersion", (PyCFunction)FuseAPIVersion, METH_NOARGS, FuseAPIVersion__doc__},
|
|
1403 |
{"FuseNotifyPoll", (PyCFunction)FuseNotifyPoll, METH_O, FuseNotifyPoll__doc__},
|
1289 | 1404 |
{NULL, NULL} /* sentinel */
|
1290 | 1405 |
};
|
1291 | 1406 |
|