[Python-bugs-list] [ python-Bugs-521723 ] fcntl.ioctl on openbsd

noreply@sourceforge.net noreply@sourceforge.net
Sun, 24 Feb 2002 06:58:52 -0800


Bugs item #521723, was opened at 2002-02-22 21:34
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=521723&group_id=5470

Category: Extension Modules
Group: Python 2.1.1
>Status: Open
Resolution: Invalid
Priority: 3
Submitted By: Jeremy Rossi (skin_pup)
Assigned to: Nobody/Anonymous (nobody)
Summary: fcntl.ioctl on openbsd

Initial Comment:
>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))
--


----------------------------------------------------------------------

>Comment By: Martin v. Löwis (loewis)
Date: 2002-02-24 06:58

Message:
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.

----------------------------------------------------------------------

Comment By: Jeremy Rossi (skin_pup)
Date: 2002-02-23 19:15

Message:
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





----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-02-23 15:05

Message:
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.

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=521723&group_id=5470