2121 * with both PyInt_Check and PyLong_Check.
2222 */
2323
24+ #ifndef FUSE_USE_VERSION
25+ #define FUSE_USE_VERSION 26
26+ #endif
27+
28+ #include <Python.h>
29+ #include <fuse.h>
30+ #include <sys/ioctl.h>
31+
32+
2433#ifndef FUSE_VERSION
2534#ifndef FUSE_MAKE_VERSION
2635#define FUSE_MAKE_VERSION (maj , min ) ((maj) * 10 + (min))
2736#endif
2837#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
2938#endif
3039
31- #ifndef FUSE_USE_VERSION
32- #define FUSE_USE_VERSION 26
33- #endif
3440
35- #include <Python.h>
36- #include <fuse.h>
3741
3842#if PY_MAJOR_VERSION >= 3
3943 #define PyInt_FromLong PyLong_FromLong
@@ -54,7 +58,8 @@ static PyObject *getattr_cb=NULL, *readlink_cb=NULL, *readdir_cb=NULL,
5458 * releasedir_cb = NULL , * fsyncdir_cb = NULL , * flush_cb = NULL , * ftruncate_cb = NULL ,
5559 * fgetattr_cb = NULL , * getxattr_cb = NULL , * listxattr_cb = NULL , * setxattr_cb = NULL ,
5660 * removexattr_cb = NULL , * access_cb = NULL , * lock_cb = NULL , * utimens_cb = NULL ,
57- * bmap_cb = NULL , * fsinit_cb = NULL , * fsdestroy_cb = NULL ;
61+ * bmap_cb = NULL , * fsinit_cb = NULL , * fsdestroy_cb = NULL , * ioctl_cb = NULL ;
62+
5863
5964static PyObject * Py_FuseError ;
6065static PyInterpreterState * interp ;
@@ -930,6 +935,64 @@ bmap_func(const char *path, size_t blocksize, uint64_t *idx)
930935}
931936#endif
932937
938+ #if FUSE_VERSION >= 28
939+ static int
940+ ioctl_func (const char * path , int cmd , void * arg ,
941+ struct fuse_file_info * fi , unsigned int flags , void * data )
942+ {
943+ char * s ;
944+ char * input_data ;
945+ int input_data_size , output_data_size ;
946+
947+ input_data = (char * ) data ;
948+ input_data_size = _IOC_SIZE (cmd );
949+
950+ // If not a "write" ioctl, do not send input data
951+ if (!(_IOC_DIR (cmd ) & _IOC_WRITE )) {
952+ input_data = NULL ;
953+ input_data_size = 0 ;
954+ }
955+
956+ #if PY_MAJOR_VERSION >= 3
957+ PROLOGUE (PYO_CALLWITHFI (fi , ioctl_cb , sIy #I , path ,cmd ,(char * )input_data ,input_data_size ,flags ));
958+ #else
959+ PROLOGUE (PYO_CALLWITHFI (fi , ioctl_cb , sIs #I , path ,cmd ,(char * )input_data ,input_data_size ,flags ));
960+ #endif
961+
962+ // get returned value if this is a "read" ioctl
963+ if (_IOC_DIR (cmd ) & _IOC_READ ) {
964+
965+ #if PY_MAJOR_VERSION >= 3
966+ if (!PyBytes_Check (v )) {
967+ ret = - EINVAL ;
968+ goto OUT_DECREF ;
969+ }
970+
971+ output_data_size = PyBytes_Size (v );
972+
973+ s = PyBytes_AsString (v );
974+ #else
975+
976+ if (!PyString_Check (v )) {
977+ ret = - EINVAL ;
978+ goto OUT_DECREF ;
979+ }
980+
981+ output_data_size = PyString_Size (v );
982+
983+ s = PyString_AsString (v );
984+ #endif
985+
986+ if (output_data_size > _IOC_SIZE (cmd ))
987+ output_data_size = _IOC_SIZE (cmd );
988+
989+ memcpy (data ,s ,output_data_size );
990+ ret = 0 ;
991+ }
992+ EPILOGUE
993+ }
994+ #endif
995+
933996static int
934997pyfuse_loop_mt (struct fuse * f )
935998{
@@ -973,13 +1036,13 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
9731036 "create" , "opendir" , "releasedir" , "fsyncdir" , "flush" ,
9741037 "ftruncate" , "fgetattr" , "getxattr" , "listxattr" , "setxattr" ,
9751038 "removexattr" , "access" , "lock" , "utimens" , "bmap" ,
976- "fsinit" , "fsdestroy" , "fuse_args" , "multithreaded" , NULL
1039+ "fsinit" , "fsdestroy" , "ioctl" , " fuse_args" , "multithreaded" , NULL
9771040 };
978-
1041+
9791042 memset (& op , 0 , sizeof (op ));
9801043
9811044 if (!PyArg_ParseTupleAndKeywords (args , kw ,
982- "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOi" ,
1045+ "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOi" ,
9831046 kwlist , & getattr_cb , & readlink_cb ,
9841047 & readdir_cb , & mknod_cb , & mkdir_cb ,
9851048 & unlink_cb , & rmdir_cb , & symlink_cb ,
@@ -994,7 +1057,7 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
9941057 & listxattr_cb , & setxattr_cb ,
9951058 & removexattr_cb , & access_cb ,
9961059 & lock_cb , & utimens_cb , & bmap_cb ,
997- & fsinit_cb , & fsdestroy_cb ,
1060+ & fsinit_cb , & fsdestroy_cb , & ioctl_cb ,
9981061 & fargseq , & multithreaded ))
9991062 return NULL ;
10001063
@@ -1055,6 +1118,9 @@ Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
10551118 DO_ONE_ATTR_AS (init , fsinit );
10561119 DO_ONE_ATTR_AS (destroy , fsdestroy );
10571120#endif
1121+ #if FUSE_VERSION >= 28
1122+ DO_ONE_ATTR (ioctl );
1123+ #endif
10581124
10591125#undef DO_ONE_ATTR
10601126#undef DO_ONE_ATTR_AS
0 commit comments