[PATCH] Fix ioctl() wrappers for 64-bit systems

Tito farmatito at tiscali.it
Fri Apr 11 06:24:30 UTC 2008


On Friday 11 April 2008 01:17:03 Nate Case wrote:
> The ioctl_*() and bb_xioctl*() functions declare the second argument as
> "int request" rather than "unsigned long int request" which break the
> ioctl() calls on 64-bit systems.
> 
> This bug presented itself in the form of login failing during the
> termios TCSETS call on my ppc64 board:
> 
>     getty: /dev/ttyS0: TCSETS: Invalid argument
> 
> I verified that changing the "request" argument to "unsigned long int"
> fixes the problem. It should leave 32-bit systems unaffected.
> 
> I also reported this issue on the bug tracker and included patches:
> 
>     http://busybox.net/bugs/view.php?id=2884
> 
> ---
> Note: This patch is against the unstable trunk.  See bug report for
> patch against stable branch.
> 
> Index: libbb/xfuncs_printf.c
> ===================================================================
> --- libbb/xfuncs_printf.c	(revision 21697)
> +++ libbb/xfuncs_printf.c	(working copy)
> @@ -451,7 +451,7 @@
>  #endif
>  }
>  
> -int ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...)
> +int ioctl_or_perror_and_die(int fd, unsigned long int request, void *argp, const char *fmt,...)
>  {
>  	int ret;
>  	va_list p;
> @@ -467,7 +467,7 @@
>  	return ret;
>  }
>  
> -int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...)
> +int ioctl_or_perror(int fd, unsigned long int request, void *argp, const char *fmt,...)
>  {
>  	va_list p;
>  	int ret = ioctl(fd, request, argp);
> @@ -481,7 +481,7 @@
>  }
>  
>  #if ENABLE_IOCTL_HEX2STR_ERROR
> -int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name)
> +int bb_ioctl_or_warn(int fd, unsigned long int request, void *argp, const char *ioctl_name)
>  {
>  	int ret;
>  
> @@ -490,7 +490,7 @@
>  		bb_simple_perror_msg(ioctl_name);
>  	return ret;
>  }
> -int bb_xioctl(int fd, int request, void *argp, const char *ioctl_name)
> +int bb_xioctl(int fd, unsigned long int request, void *argp, const char *ioctl_name)
>  {
>  	int ret;
>  
> @@ -500,7 +500,7 @@
>  	return ret;
>  }
>  #else
> -int bb_ioctl_or_warn(int fd, int request, void *argp)
> +int bb_ioctl_or_warn(int fd, unsigned long int request, void *argp)
>  {
>  	int ret;
>  
> @@ -509,7 +509,7 @@
>  		bb_perror_msg("ioctl %#x failed", request);
>  	return ret;
>  }
> -int bb_xioctl(int fd, int request, void *argp)
> +int bb_xioctl(int fd, unsigned long int request, void *argp)
>  {
>  	int ret;
>  
> Index: include/libbb.h
> ===================================================================
> --- include/libbb.h	(revision 21697)
> +++ include/libbb.h	(working copy)
> @@ -1016,16 +1016,16 @@
>  /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */
>  int get_terminal_width_height(int fd, int *width, int *height);
>  
> -int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
> -int ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
> +int ioctl_or_perror(int fd, unsigned long int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
> +int ioctl_or_perror_and_die(int fd, unsigned long int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
>  #if ENABLE_IOCTL_HEX2STR_ERROR
> -int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name);
> -int bb_xioctl(int fd, int request, void *argp, const char *ioctl_name);
> +int bb_ioctl_or_warn(int fd, unsigned long int request, void *argp, const char *ioctl_name);
> +int bb_xioctl(int fd, unsigned long int request, void *argp, const char *ioctl_name);
>  #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request)
>  #define xioctl(fd,request,argp)        bb_xioctl(fd,request,argp,#request)
>  #else
> -int bb_ioctl_or_warn(int fd, int request, void *argp);
> -int bb_xioctl(int fd, int request, void *argp);
> +int bb_ioctl_or_warn(int fd, unsigned long int request, void *argp);
> +int bb_xioctl(int fd, unsigned long int request, void *argp);
>  #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp)
>  #define xioctl(fd,request,argp)        bb_xioctl(fd,request,argp)
>  #endif

Hi,
for 32-bit systems the man page says:

IOCTL(2)                   Linux Programmer’s Manual                  IOCTL(2)

NAME
       ioctl - control device

SYNOPSIS
       #include <sys/ioctl.h>

       int ioctl(int d, int request, ...);

Couldn't this changes be made platform dependent with some voodoo magic
at compile time?

Ciao,
Tito





More information about the busybox mailing list