diff -r 44e5b48998ef Modules/fcntlmodule.c --- a/Modules/fcntlmodule.c Sun Nov 11 00:08:45 2012 -0800 +++ b/Modules/fcntlmodule.c Sun Nov 11 04:23:05 2012 -0800 @@ -97,20 +97,7 @@ { #define IOCTL_BUFSZ 1024 int fd; - /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I' - format for the 'code' parameter because Python turns 0x8000000 - into either a large positive number (PyLong or PyInt on 64-bit - platforms) or a negative number on others (32-bit PyInt) - whereas the system expects it to be a 32bit bit field value - regardless of it being passed as an int or unsigned long on - various platforms. See the termios.TIOCSWINSZ constant across - platforms for an example of thise. - - If any of the 64bit platforms ever decide to use more than 32bits - in their unsigned long ioctl codes this will break and need - special casing based on the platform being built on. - */ - unsigned int code; + IOCTL_CODE_TYPE code; int arg; int ret; Py_buffer pstr; @@ -119,7 +106,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&" IOCTL_CODE_FTYPE "w*|i:ioctl", conv_descriptor, &fd, &code, &pstr, &mutate_arg)) { char *arg; @@ -174,7 +161,7 @@ } PyErr_Clear(); - if (PyArg_ParseTuple(args, "O&Is*:ioctl", + if (PyArg_ParseTuple(args, "O&" IOCTL_CODE_FTYPE "s*:ioctl", conv_descriptor, &fd, &code, &pstr)) { str = pstr.buf; len = pstr.len; @@ -201,8 +188,9 @@ PyErr_Clear(); arg = 0; if (!PyArg_ParseTuple(args, - "O&I|i;ioctl requires a file or file descriptor," - " an integer and optionally an integer or buffer argument", + "O&" IOCTL_CODE_FTYPE "|i;ioctl requires a file or file " + "descriptor, an integer and optionally an integer or buffer " + "argument", conv_descriptor, &fd, &code, &arg)) { return NULL; } diff -r 44e5b48998ef configure.ac --- a/configure.ac Sun Nov 11 00:08:45 2012 -0800 +++ b/configure.ac Sun Nov 11 04:23:05 2012 -0800 @@ -4612,6 +4612,34 @@ esac fi +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wall -Werror" +AC_MSG_CHECKING(ioctl code argument type is unsigned long) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include +int main() { + typedef int (*ioctl_fn_t)(int, unsigned long, ...); + ioctl_fn_t _ioctl = ioctl; + return _ioctl(0, 0, 0); +} +]])],[ioctl_code_type="unsigned long"]) +CFLAGS="$save_CFLAGS" + +if test "$ioctl_code_type" = "unsigned long"; then + # Probably *BSD. + AC_MSG_RESULT(yes) + ioctl_code_ftype="K" +else + # Fall back to "sane" POSIX value. + AC_MSG_RESULT(no) + ioctl_code_type="int" + ioctl_code_ftype="I" +fi +AC_DEFINE_UNQUOTED(IOCTL_CODE_TYPE,$ioctl_code_type, + [Type for code argument in fcntl.ioctl]) +AC_DEFINE_UNQUOTED(IOCTL_CODE_FTYPE,"$ioctl_code_ftype", + [Format string qualifier for code argument in fcntl.ioctl]) + # generate output files AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc) AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) diff -r 44e5b48998ef pyconfig.h.in --- a/pyconfig.h.in Sun Nov 11 00:08:45 2012 -0800 +++ b/pyconfig.h.in Sun Nov 11 04:23:05 2012 -0800 @@ -1116,6 +1116,12 @@ /* Define to 1 if you have the `_getpty' function. */ #undef HAVE__GETPTY +/* Format string qualifier for code argument in fcntl.ioctl */ +#undef IOCTL_CODE_FTYPE + +/* Type for code argument in fcntl.ioctl */ +#undef IOCTL_CODE_TYPE + /* Define if log1p(-0.) is 0. rather than -0. */ #undef LOG1P_DROPS_ZERO_SIGN