Port-sparc64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ioctl question



On Mon, Jun 09, 2008 at 02:18:53PM +0100, raymond.meyer%rambler.ru@localhost 
wrote:
> On Monday 09 June 2008 13:37:32 raymond.meyer%rambler.ru@localhost wrote:
> > Does anyone know why on 64-bit NetBSD sparc64 the following code works:
> >
> > ioctl(fd, SNDCTL_DSP_CHANNELS, &channels);
> >
> > but the following code returns -1 from ioctl
> >
> > unsigned long dsp_ch = SNDCTL_DSP_CHANNELS;
> > ioctl(fd, dsp_ch, &channels)
> >
> > /usr/include/soundcard.h has:
> >
> > #define SNDCTL_DSP_CHANNELS             _IOWR('P', 6, int)
> 
> OK, a few corrections, I think both of the above work.
> The following code does not work
> 
> int call_ioctl(int fd, int request, void *argp)
> {
>       int val = *argp;
> 
>       if (ioctl(fd, request, &val) != 0)
>               return -1;
> }
> 
> call_ioctl(some_fd, SNDCTL_DSP_CHANNELS, &some_arg);

It all tends to work because the int parameters get implicitly extended
to long because the first 6 parameters are passed in registers.

However the defintiion for ioctl() is currently:
    int ioctl(int, int, ...)
This is portable since the '...' arg is usually a pointer, but could be
an int (or long) but the calling convention is assumed to be that for
'void *'.  With that definition the libc stub should hav code to deternime
what the arg type is (dependant on the ioct code and driver) and use va_arg()
to collect the correct value!

One possibility is to replace the defn with:
int ioctl(int, int. void *);
#define ioctl(fd, rq, arg) ioctl(fd, rd, (void *)(intptr_t)(arg));

        David

-- 
David Laight: david%l8s.co.uk@localhost


Home | Main Index | Thread Index | Old Index