
I'm trying to make a module to support inotify (linux). I put together a module using boost::python. Problem is, inotify uses a file descriptor. If I call python os.fdopen on it, I get an error: Python 2.4.1 (#1, May 16 2005, 15:15:14) [GCC 4.0.0 20050512 (Red Hat 4.0.0-5)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
from inotify import * import os i=inotify() i.fileno() 4 os.fdopen (i.fileno()) Traceback (most recent call last): File "<stdin>", line 1, in ? IOError: [Errno 21] Is a directory
Any ideas? I'd rather not have to trace through python if I could avoid it (I don't even have source installed here).

Neal Becker wrote:
Any ideas? I'd rather not have to trace through python if I could avoid it (I don't even have source installed here).
Use strace, then. Find out what precise system call gives you this error. If this is not enough clue, post the relevant fragment of the trace output. Usage would be strace -o muell python test_notify.py (look into the file muell afterwards) Regards, Martin

"Martin v. Löwis" wrote:
Neal Becker wrote:
Any ideas? I'd rather not have to trace through python if I could avoid it (I don't even have source installed here).
Use strace, then. Find out what precise system call gives you this error. If this is not enough clue, post the relevant fragment of the trace output. Usage would be
strace -o muell python test_notify.py (look into the file muell afterwards)
Yes, tried that- learned nothing. I suspect what's happening is that python's fdopen is using some stat call to determine whether the file descriptor refers to a directory, and is getting an answer that the inotify fd does. Don't know what to do about it. Can I build a python file object in "C" from the fd? Here's strace. The write of '4' is where my code writes the value of fileno() to stdout, which is '4', which is correct - notice that open("test-inotify.py") returned '3': ... open("test-inotify.py", O_RDONLY) = 3 write(2, " File \"test-inotify.py\", line 6"..., 39) = 39 fstat(3, {st_mode=S_IFREG|0664, st_size=87, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaadc13000 read(3, "from inotify import *\nimport os\n"..., 4096) = 87 write(2, " ", 4) = 4 write(2, "os.fdopen (i.fileno())\n", 23) = 23 close(3) = 0 munmap(0x2aaaadc13000, 4096) = 0 write(2, "IOError", 7) = 7 write(2, ": ", 2) = 2 write(2, "[Errno 21] Is a directory", 25) = 25

Neal Becker wrote:
Yes, tried that- learned nothing.
Please go back further in the trace file. There must be a return value of -1 (EISDIR) somewhere in the file, try to locate that.
Here's strace. The write of '4' is where my code writes the value of fileno() to stdout, which is '4', which is correct - notice that open("test-inotify.py") returned '3':
The fragment you quote only refers to the part where it tries to format the traceback. The value '4' is never written, instead, it writes 4 spaces (the second argument is the bytes, the third is the number of bytes). Regards, Martin

"Martin v. Löwis" wrote:
Neal Becker wrote:
Yes, tried that- learned nothing.
Please go back further in the trace file. There must be a return value of -1 (EISDIR) somewhere in the file, try to locate that.
Here's strace. The write of '4' is where my code writes the value of fileno() to stdout, which is '4', which is correct - notice that open("test-inotify.py") returned '3':
The fragment you quote only refers to the part where it tries to format the traceback. The value '4' is never written, instead, it writes 4 spaces (the second argument is the bytes, the third is the number of bytes).
This 1st line is the syscall for inotify: SYS_253(0, 0x7fffff88f0f0, 0x2aaaadda3f00, 0x2aaaaab4611b, 0x7) = 4 close(3) = 0 futex(0x502530, FUTEX_WAKE, 1) = 0 futex(0x502530, FUTEX_WAKE, 1) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaadc12000 write(1, "4\n", 2) = 2 fcntl(4, F_GETFL) = 0 (flags O_RDONLY) fstat(4, {st_mode=S_IFDIR|0600, st_size=0, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaadc13000 lseek(4, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) fstat(4, {st_mode=S_IFDIR|0600, st_size=0, ...}) = 0 close(4) = 0 munmap(0x2aaaadc13000, 4096) = 0 write(2, "Traceback (most recent call last"..., 35) = 35 open("test-inotify.py", O_RDONLY) = 3 write(2, " File \"test-inotify.py\", line 6"..., 39) = 39 ...

Neal Becker wrote:
SYS_253(0, 0x7fffff88f0f0, 0x2aaaadda3f00, 0x2aaaaab4611b, 0x7) = 4 close(3) = 0 futex(0x502530, FUTEX_WAKE, 1) = 0 futex(0x502530, FUTEX_WAKE, 1) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaadc12000 write(1, "4\n", 2) = 2 fcntl(4, F_GETFL) = 0 (flags O_RDONLY) fstat(4, {st_mode=S_IFDIR|0600, st_size=0, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaadc13000 lseek(4, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) fstat(4, {st_mode=S_IFDIR|0600, st_size=0, ...}) = 0 close(4) = 0 munmap(0x2aaaadc13000, 4096) = 0 write(2, "Traceback (most recent call last"..., 35) = 35
I see. Python is making up the EISDIR, looking at the stat result. In Objects/fileobject.c:dircheck generates the EISDIR error, which apparently comes from posix_fdopen, PyFile_FromFile, fill_file_fields. Python simply does not support file objects which stat(2) as directories. Regards, Martin

"Martin v. Löwis" wrote:
I see. Python is making up the EISDIR, looking at the stat result. In Objects/fileobject.c:dircheck generates the EISDIR error, which apparently comes from posix_fdopen, PyFile_FromFile, fill_file_fields.
Python simply does not support file objects which stat(2) as directories.
OK, does python have a C API that would allow me to create a python file object from my C (C++) code? Then instead of using python's fdopen I could just do it myself.

On Oct 27, 2005, at 4:32 PM, Neal Becker wrote:
"Martin v. Löwis" wrote:
I see. Python is making up the EISDIR, looking at the stat result. In Objects/fileobject.c:dircheck generates the EISDIR error, which apparently comes from posix_fdopen, PyFile_FromFile, fill_file_fields.
Python simply does not support file objects which stat(2) as directories.
OK, does python have a C API that would allow me to create a python file object from my C (C++) code? Then instead of using python's fdopen I could just do it myself.
Why do you need a file object for something that is not a file anyway? select.select doesn't require file objects for example, just objects that have a fileno() method. -bob

Bob Ippolito wrote:
On Oct 27, 2005, at 4:32 PM, Neal Becker wrote:
"Martin v. Löwis" wrote:
I see. Python is making up the EISDIR, looking at the stat result. In Objects/fileobject.c:dircheck generates the EISDIR error, which apparently comes from posix_fdopen, PyFile_FromFile, fill_file_fields.
Python simply does not support file objects which stat(2) as directories.
OK, does python have a C API that would allow me to create a python file object from my C (C++) code? Then instead of using python's fdopen I could just do it myself.
Why do you need a file object for something that is not a file anyway? select.select doesn't require file objects for example, just objects that have a fileno() method.
Yes, that's a good point - the reason is I didn't want to restrict the interface to only work with select. Maybe I should rethink the interface.

On Oct 27, 2005, at 4:58 PM, Neal Becker wrote:
Bob Ippolito wrote:
On Oct 27, 2005, at 4:32 PM, Neal Becker wrote:
"Martin v. Löwis" wrote:
I see. Python is making up the EISDIR, looking at the stat result. In Objects/fileobject.c:dircheck generates the EISDIR error, which apparently comes from posix_fdopen, PyFile_FromFile, fill_file_fields.
Python simply does not support file objects which stat(2) as directories.
OK, does python have a C API that would allow me to create a python file object from my C (C++) code? Then instead of using python's fdopen I could just do it myself.
Why do you need a file object for something that is not a file anyway? select.select doesn't require file objects for example, just objects that have a fileno() method.
Yes, that's a good point - the reason is I didn't want to restrict the interface to only work with select. Maybe I should rethink the interface.
Well what would the interface do if you had a file object? Are you supposed to be able to read/write/seek/tell/etc.? I don't understand why you're trying to do what you're doing. select.select was just an example, select.poll's register/unregister takes any object with a fileno also. Note that socket isn't a file and it has a fileno also. Since what you have isn't a file, chances are returning a file object is a bug not a feature. -bob

Bob Ippolito wrote:
On Oct 27, 2005, at 4:58 PM, Neal Becker wrote:
Bob Ippolito wrote:
On Oct 27, 2005, at 4:32 PM, Neal Becker wrote:
"Martin v. Löwis" wrote:
I see. Python is making up the EISDIR, looking at the stat result. In Objects/fileobject.c:dircheck generates the EISDIR error, which apparently comes from posix_fdopen, PyFile_FromFile, fill_file_fields.
Python simply does not support file objects which stat(2) as directories.
OK, does python have a C API that would allow me to create a python file object from my C (C++) code? Then instead of using python's fdopen I could just do it myself.
Why do you need a file object for something that is not a file anyway? select.select doesn't require file objects for example, just objects that have a fileno() method.
Yes, that's a good point - the reason is I didn't want to restrict the interface to only work with select. Maybe I should rethink the interface.
Well what would the interface do if you had a file object? Are you supposed to be able to read/write/seek/tell/etc.? I don't understand why you're trying to do what you're doing. select.select was just an example, select.poll's register/unregister takes any object with a fileno also.
Yes, you are supposed to be able to read and get information. However, I have implemented fileno for it, so you can use select.select on it if you just want to wait for something to happen - which is probably all that's really needed. I also implemented select as a method of my inotify object, in case you prefer that. Here's an excerpt from documentation/filesystems/inotify.txt: ----------------- Events are provided in the form of an inotify_event structure that is read(2) from a given inotify instance. The filename is of dynamic length and follows the struct. It is of size len. The filename is padded with null bytes to ensure proper alignment. This padding is reflected in len. You can slurp multiple events by passing a large buffer, for example size_t len = read (fd, buf, BUF_LEN); Where "buf" is a pointer to an array of "inotify_event" structures at least BUF_LEN bytes in size. The above example will return as many events as are available and fit in BUF_LEN. Each inotify instance fd is also select()- and poll()-able. -----------------

Neal Becker wrote:
OK, does python have a C API that would allow me to create a python file object from my C (C++) code? Then instead of using python's fdopen I could just do it myself.
I don't know - you will have to read the python source to find out (this is actually not a pythondev question anymore). Regards, Martin
participants (3)
-
"Martin v. Löwis"
-
Bob Ippolito
-
Neal Becker