Package: inputattach Version: 1:1.4-1 Severity: important Tags: upstream patch
When booting, inputattach tries to hook up my serial port for some w8001 action but causes the CPU instead to spin at 100%. strace'ing shows it's spinning on read(3,NULL,0) and is returning EBUSY; /proc/$PID/fd/3 points to /dev/ttyS0. Looking at the source I found the following caused the problem: http://linuxconsole.svn.sourceforge.net/viewvc/linuxconsole?view=revision&revision=2422 http://linuxconsole.svn.sourceforge.net/viewvc/linuxconsole/trunk/utils/inputattach.c?r1=2412&r2=2422&pathrev=2422 We need to tell Kees Cook that errno does actually have more than two values (not just zero and EINTR) and reading manpages helps ;P Attached is a fix that seems to work after a suspend/resume cycle and of course on a fresh boot. Thanks though to Kee's on finding what the actual hiccup was in the first place though, it's removed another thing off my todo list. Cheers -- System Information: Debian Release: wheezy/sid APT prefers unstable APT policy: (900, 'unstable'), (500, 'experimental'), (500, 'stable') Architecture: amd64 (x86_64) Kernel: Linux 2.6.39-2-amd64 (SMP w/2 CPU cores) Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages inputattach depends on: ii libc6 2.13-7 Embedded GNU C Library: Shared lib inputattach recommends no packages. inputattach suggests no packages. -- no debconf information
--- joystick-1.4.orig/utils/inputattach.c 2011-05-16 22:05:56.000000000 +0100 +++ joystick-1.4/utils/inputattach.c 2011-06-25 10:49:00.000000000 +0100 @@ -607,6 +607,9 @@ puts(""); } +/* palmed wisdom from http://stackoverflow.com/questions/1674162/ */ +#define RETRY_ERROR(x) (x == EAGAIN || x == EWOULDBLOCK || x == EINTR) + int main(int argc, char **argv) { unsigned long devt; @@ -738,7 +741,13 @@ retval = EXIT_FAILURE; } - for (errno = 0; errno != EINTR; read(fd, NULL, 0)) ; + do { + i = read(fd, NULL, 0); + if (i == -1) { + if (RETRY_ERROR(errno)) + continue; + } + } while (!i); ldisc = 0; ioctl(fd, TIOCSETD, &ldisc);