[Tutor] IOError with fcntl.ioctl
python-tutor at richip.dhs.org
Wed Aug 17 05:55:22 CEST 2005
Crave pardon if that question of mine was too basic to merit a reply,
but I couldn't find anything by searching. Newbie Python user here. I
finally did find the answer and thought I'd post it in case someone
might come along with the same question.
The problem is with the way I was using fcntl.ioctl(). Actually, the
problem's even more fundamental than that. ioctl(2) is called the Swiss
Army Knife of I/O programming on Unix environments. That makes it hard
to abstract. Since it's uses is varied and complex, it's become more
difficult to escalate that abstraction to a higher layer (such as Python).
What I found in the source code for Python is that the programmer's made
a good attempt at keeping ioctl(2)'s abstraction, but not completely.
High-level language programmers will be forced to switch to low-level
when doing IO programming with Python on *nix.
It turns out that one needs to pass a 3rd parameter (and possibly a 4th)
if one expects a result value from calling ioctl. As documented in
fcntl.ioctl's pydoc, fcntl.ioctl() returns the result of calling ioctl()
which is just a 0 for success and -1 for error. Passing an immutable
sequence as the 3rd parameter will modify its behavior so that it
returns the expected arg value.
I've modified the code so now it looks like:
fd = os.open ("/dev/ttyS0", os.O_RDWR)
n = fcntl.ioctl (fd, termios.TIOCINQ, "XXXX")
y = 0
i = len(n)
y <<= 8
y |= ord (n[i-1])
i -= 1
# Result in y
Perhaps in the future someone will modify fcntlmodule.c to improve this.
> I'm trying to get the number of bytes available on an open serial device
> (on Linux). I try the following commands:
> >>> import os
> >>> import fcntl
> >>> import termios
> >>> fd = os.open ("/dev/ttyS0", os.O_RDWR)
> >>> fcntl.ioctl (fd, termios.TIOCINQ)
> and after the last line I get the following error:
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> IOError: [Errno 14] Bad address
> I've tried fcntl.ioctl (fd, termios.FIONREAD) (which is supposed to do
> the same thing, I think), and I still get the previous error. In fact,
> any ioctl() command I give to that file descriptor gives that result.
> I'd appreciate any help in getting this to work.
More information about the Tutor