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

noreply@sourceforge.net noreply@sourceforge.net
Sun, 24 Feb 2002 14:23:42 -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: Jeremy Rossi (skin_pup)
Date: 2002-02-24 14:23

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


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

Comment By: Tim Peters (tim_one)
Date: 2002-02-24 13:36

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

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

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