On Sat, Feb 28, 2009 at 12:53:10AM -0500, [email protected] wrote: > The component: xf86-input-keyboard > > The source file: src/lnx_kbd.c > > The function: GetKbdLeds > > The bug: > int real_leds, leds = 0; > > ioctl(pInfo->fd, KDGETLED, &real_leds); > > if (real_leds & LED_CAP) leds |= XLED1; > if (real_leds & LED_NUM) leds |= XLED2; > if (real_leds & LED_SCR) leds |= XLED3; > > The reason: > KDGETLED actually only stores a single byte at the address indicated by > &real_leds, which on big-endian systems means the kernel's led state is put > into the most-significant byte of real_leds. The LED_CAP LED_NUM LED_SCR > macros then extract some bits from the least-significant byte, which still > contains stack garbage since real_leds hasn't been initialized. > > Don't believe what the console_ioctl(4) man page says. It's wrong. Go read > drivers/char/vt_ioctl.c in the kernel source, or run this demo on a > big-endian machine: > > #include <stdio.h> > #include <sys/ioctl.h> > #include <linux/kd.h> > > int main(void) > { > int ioctlret; > long longval; > > longval = -1; > > ioctlret = ioctl(0, KDGETLED, &longval); > printf("ioctlret=%d longval=%08lx\n", ioctlret, longval); > > return 0; > } > > The fix is very simple: > > diff --git a/src/lnx_kbd.c b/src/lnx_kbd.c > index cfe35a3..9144464 100644 > --- a/src/lnx_kbd.c > +++ b/src/lnx_kbd.c > @@ -73,7 +73,8 @@ SetKbdLeds(InputInfoPtr pInfo, int leds) > static int > GetKbdLeds(InputInfoPtr pInfo) > { > - int real_leds, leds = 0; > + char real_leds; > + int leds = 0; > > ioctl(pInfo->fd, KDGETLED, &real_leds); >
Pushed, thanks for the patch. Cheers, Peter _______________________________________________ xorg-devel mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-devel
