New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ioctl request argument broken on 64-bit OpenBSD or OS X #45812
Comments
The following lines of code work on Linux platforms (amd64), and 32-bit import fcntl,os,pty,termios,select,sys,struct,pwd,signal,os
pid,fd=pty.fork()
fcntl.ioctl(fd, termios.TIOCSWINSZ, struct.pack("HHHH",80,25,0,0)) This gives an "IOError: [Errno 25] Inappropriate ioctl for device" The python version in question on OpenBSD is: Python 2.5.1 (r251:54863, Nov 16 2007, 18:16:44) The winsize structure as dumped using sizeof(struct winsize) under |
The following C code, when compiled with -lutil runs without reporting #include <util.h>
#include <utmp.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <stdio.h>
int main(void)
{
int fd;
struct winsize w;
w.ws_row = 25;
w.ws_col = 80;
w.ws_xpixel = w.ws_ypixel = 0;
forkpty(&fd, NULL, NULL, NULL);
if (ioctl(fd,TIOCSWINSZ, &w) == -1)
perror("ioctl");
return 0;
} |
So what's the definition of struct winsize on these systems? Also, why do you think this is a bug in Python? AFAICT, the specific |
I can also reproduce this on OpenBSD/amd64 and was one of the people who
The definition of struct winsize on both 32-bit and 64-bit OpenBSD struct winsize {
unsigned short ws_row; /* rows, in characters */
unsigned short ws_col; /* columns, in characters */
unsigned short ws_xpixel; /* horizontal size, pixels */
unsigned short ws_ypixel; /* vertical size, pixels */
}; We have verified that (sizeof (struct winsize)) is 8 on all three
This Python code fails: fcntl.ioctl(fd, termios.TIOCSWINSZ, struct.pack("HHHH",80,25,0,0)) (Error: IOError: [Errno 25] Inappropriate ioctl for device) This code fcntl.ioctl(0, termios.TIOCSWINSZ, "") Corresponding test C code to call the ioctl (as listed in a previous The constant appears to be the correct ioctl number. (Python code: python2.5 -c 'import termios; print "%d" % (termios.TIOCSWINSZ)' matches C code: #include <termios.h>
int main(void) { printf("%ld\n", TIOCSWINSZ); } on all three platforms.) I am told it works on Linux. However, Linux declares ioctl as: int ioctl(int d, int request, ...); So 'request' is 32-bits, but on OpenBSD ioctl is declared as: int ioctl(int d, unsigned long request, ...); So on amd64 and sparc64, 'request' is 64-bits. Could this be a factor? -- Nicholas. |
Okay, looks like my guess was correct. The diff at the end of this mail fcntl_ioctl in fcntlmodule.c seems to have some other potential -- Nicholas. --- fcntlmodule.c.orig Tue Nov 20 09:39:12 2007
+++ fcntlmodule.c Tue Nov 20 09:59:50 2007
@@ -101,7 +101,7 @@
the signed int 'code' variable, because Python turns
0x8000000
into a large positive number (PyLong, or PyInt on 64-bit
platforms,) whereas C expects it to be a negative int */
- int code;
+ unsigned long code;
int arg;
int ret;
char *str;
@@ -109,7 +109,7 @@
int mutate_arg = 1;
char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
- if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
+ if (PyArg_ParseTuple(args, "O&Lw#|i:ioctl",
conv_descriptor, &fd, &code,
&str, &len, &mutate_arg)) {
char *arg;
@@ -160,7 +160,7 @@
}
PyErr_Clear();
- if (PyArg_ParseTuple(args, "O&Is#:ioctl",
+ if (PyArg_ParseTuple(args, "O&Ls#:ioctl",
conv_descriptor, &fd, &code, &str, &len))
{
if (len > IOCTL_BUFSZ) {
PyErr_SetString(PyExc_ValueError,
@@ -182,7 +182,7 @@
PyErr_Clear();
arg = 0;
if (!PyArg_ParseTuple(args,
- "O&I|i;ioctl requires a file or file descriptor,"
+ "O&L|i;ioctl requires a file or file descriptor,"
" an integer and optionally an integer or buffer argument",
conv_descriptor, &fd, &code, &arg)) {
return NULL; |
Similar issue seen in 64 bit OSX 10.5 File "./ajaxterm.py", line 418, in create $ python
Python 2.5.1 (r251:54863, Oct 5 2007, 21:08:09)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin |
I think this proposed change needs some research into what the standards |
It's not the return value, it's the request argument (second argument). http://www.opengroup.org/onlinepubs/009695399/functions/ioctl.html -- Nicholas |
i'd say the patch is fine. on linux ioctl takes an int. regardless, treating the parameter as either a long or unsigned long |
I am unable to reproduce this problem at all on Mac OS X 10.4 or 10.5 I have however checked in a fix that'll prevent negative code values A unittest for fcntl.ioctl behavior when passed both positive and trunk r61652 while the Linux man page describe's ioctl's code parameter as an int, However if that is done we -might- have a sign extension problem again fbvortex. Can you apply the change from svn to your python and test paste a note here once you have with the results. |
r61665 moves the test to test_ioctl instead of test_fcntl. it also |
Something else to do here? |
i believe this is fixed by the two changes mentioned above, i was these changes need backporting to release25-maint. |
I was going to test this on sparc64 (I no longer have access to amd64) |
committed to release25-maint as r65466. if testing on 64bit openbsd or |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: