Issue521723
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2002-02-23 05:34 by skin_pup, last changed 2022-04-10 16:05 by admin. This issue is now closed.
Messages (7) | |||
---|---|---|---|
msg9360 - (view) | Author: Jeremy Rossi (skin_pup) | Date: 2002-02-23 05:34 | |
From the OpenBSD man page ------- #include <sys/ioctl.h> int ioctl(int d, unsigned long request, ...); -- On OpenBSD ioctl takes an unsigned long for the action to be preformed on d. The function fcntl_ioctl() in Modules/fcntlmodule.c will only accept an int for the second argument without rasing an error. On OpenBSD (maybe free/net also I have not checked) an unsigned long should be the largest allowed. From Modules/fcntlmodule.c ------- PyArg_ParseTuple(args, "iis#:ioctl", &fd, &code, &str, &len)) -- |
|||
msg9361 - (view) | Author: Martin v. Löwis (loewis) * | Date: 2002-02-23 23:05 | |
Logged In: YES user_id=21627 Can you give a practical example of an fcntl operation where this is a problem? For all practical purposes, a byte would be sufficient. Also, in POSIX, the argument to fcntl is of type int, see http://www.opengroup.org/onlinepubs/007904975/functions/fcntl.html So I can't see the bug. |
|||
msg9362 - (view) | Author: Jeremy Rossi (skin_pup) | Date: 2002-02-24 03:15 | |
Logged In: YES user_id=323435 From the current man pages of OpenBSD and FreeBSD. It stats that the second argument of ioctl is an unsigned int. http://www.openbsd.org/cgi-bin/man.cgi?query=ioctl http://www.freebsd.org/cgi-bin/man.cgi?query=ioctl Pythons fcntl.ioctl() does not allow the second argumnet to be anything other then a C int, this does not allow required operations to be preformed with ioctl on the two BSD systems. For a practical example. On the openbsd system the /dev/pf is the direct inteface to the firewall, the only things I am able to preform on this file in python are to turn the firewall on and off. This is allowed because the ioctl un_signed ints (536888321 in base 10) that prefrom this action happen to be small enough to fit in to an int. While the ioctl unsigned int (3229893651 in base 10) for reporting the status of connections is larger then a C int and python raises an exception before calling the system ioctl call. The following is the code in question. import fcntl import struct import os fd = os.open("/dev/pf",os.O_RDWR) null = '\0'*(struct.calcsize("LLLLIIII")) x = 3229893651 null = fcntl.ioctl(fd,x,null) print struct.unpack("LLLLIIII",null) ---output--- $ sudo python ./py-pfctl.py Traceback (most recent call last): File "./py-pfctl.py", line 8, in ? null = fcntl.ioctl(fd,x,null) OverflowError: long int too large to convert to int |
|||
msg9363 - (view) | Author: Martin v. Löwis (loewis) * | Date: 2002-02-24 14:58 | |
Logged In: YES user_id=21627 This won't be easy to change: If we declare the type of ioctl to be unsigned, then we break systems where it is signed (as it should be). As a work-around, try using 0xC0844413 (i.e. the hexadecimal version) as the value for the ioctl. Python will understand this as a negative value, but your system will likely still understand it as the right ioctl command. |
|||
msg9364 - (view) | Author: Tim Peters (tim.peters) * | Date: 2002-02-24 21:36 | |
Logged In: YES user_id=31435 Gotta love it <wink>. I don't believe ioctl is a POSIX Classic function. There's a good discussion of why the POSIX Realtime Extensions added a workalike posix_devctl() instead, in http://www.usenix.org/publications/login/standards/22.posix. html Martin, the URL you gave is actually for fcntl, not ioctl. You can s/fcntl/ioctl/ in your URL to get the Single UNIX Specification's ioctl page, though, which also says "int". I agree OpenBSD is out of line with best current practice because of that. It appears that Jeremy must be using Python 2.2, or running on a 64-bit machine, since his line x = 3229893651 raises OverflowError on 32-bit boxes before the 2.2 release. As Martin suggests, using a hex literal instead has always been the intended way to deal with cases "like this". The situation will get a lot worse if OpenBSD is ported to a 64- bit box with sizeof(long)==8, and some yahoo actually defines a ioctl arg that requires more than 32 bits. Before then, I suggest we leave this alone (by the time it may matter for real, OpenBSD should be feeling a lot more pressure to conform to the larger open standards). |
|||
msg9365 - (view) | Author: Jeremy Rossi (skin_pup) | Date: 2002-02-24 22:23 | |
Logged In: YES user_id=323435 Thank you Martin the 0xC0844413 does indeed work for me, but I am working on writing a thin wrapper that will accept un_signed long ints for ioctl. (Never done C before, but I guess this is as good as any to learn) But to looking forward I have done some checking and it seams to me that all the *BSD's including BSDi use unsigned longs for ioctl. I was not able to find documentation for darwin on the web, bit I think it is safe to assume that it also takes a unsigned long for ioctl. NetBSD also have been ported to 64bit systems. NetBSD: http://www.tac.eu.org/cgi-bin/man-cgi?ioctl++NetBSD-current -- BEGIN cut and paste from a BSDi systems. $ uname -a BSD/OS xxxx.xxxxxx.com 2.1 BSDI BSD/OS 2.1 Kernel #2: Mon Jan 27 16:12:45 MST 1997 web@xxxx.xxxxxx.com:/usr/src/sys/compile/USR i386 $ man ioctl | head IOCTL(2) BSD Programmer's Manual IOCTL(2) NAME ioctl - control device SYNOPSIS #include <sys/ioctl.h> int ioctl(int d, unsigned long request, char *argp); --END |
|||
msg9366 - (view) | Author: Martin v. Löwis (loewis) * | Date: 2002-02-25 17:36 | |
Logged In: YES user_id=21627 On your system, 'unsigned long' is the same type as 'unsigned int'. Furthermore, passing a negative number -n is the same as passing 2**32-n, atleast on a 32-bit architecture. So even if your driver processes unsigned ints, you will be able to pass the correct value using the corresponding negative number. Furthermore, if you use the hex notation, it will work even on 64-bit ports unmodified: unsigned long will be 64 bit, but so will be the Python int type, and the hex literal then indicates a positive integer, which is well in range. As for ioctl not being Posix: It actually is, in the latest revision of Posix (IEEE Std 1003.1-2001), which is identical to Single Unix (see the top of the ioctl page). In any case, I think this is not worth fixing, as I cannot see a problem arising from it that cannot be easily worked-around, hence closing the report. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-10 16:05:01 | admin | set | github: 36144 |
2002-02-23 05:34:25 | skin_pup | create |