From 0e1809aac9fe66fdee043236a869ba72d73103bf Mon Sep 17 00:00:00 2001 From: Pascal Manchon Date: Sun, 8 Jul 2012 08:28:49 +0200 Subject: [PATCH] Fix some ioctl calls on 64bit Mac OS X. On Mac OS X (and probably the other BSD's too), the ioctl() syscall takes an 'unsigned long' integer as the request parameter. On 64bit systems this is a 64bit type, while on 32bit systems it's a 32bit type. Some of the request constants are defined as 32 bit negative numbers. Casting it to a 64bit value will perform a sign extension operation to preserve the negative value. Because this results in a different request code when interpreted as an unsigned integer, the ioctl() call fails with ENOTTY. For example TIOCMBIS is defined as 0x8004746c and becomes 0xffffffff8004746 after the sign extension. Linux 64bit is unaffected by this problem. None of the request constants has the sign bit set, and thus the sign extension has no effect. For example TIOCMBIS is defined as 0x5416. By using an unsigned integer type, the sign extension can be avoided. We use the 'unsigned long' type in case one of the request constants happens to be defined as a 64bit number. --- src/serial_posix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/serial_posix.c b/src/serial_posix.c index 50f09e1..ad9712e 100644 --- a/src/serial_posix.c +++ b/src/serial_posix.c @@ -663,7 +663,7 @@ serial_set_break (serial_t *device, int level) if (device == NULL) return -1; // EINVAL (Invalid argument) - int action = (level ? TIOCSBRK : TIOCCBRK); + unsigned long action = (level ? TIOCSBRK : TIOCCBRK); if (ioctl (device->fd, action, NULL) != 0) { TRACE ("ioctl"); @@ -677,7 +677,7 @@ serial_set_break (serial_t *device, int level) static int serial_set_status (int fd, int value, int level) { - int action = (level ? TIOCMBIS : TIOCMBIC); + unsigned long action = (level ? TIOCMBIS : TIOCMBIC); if (ioctl (fd, action, &value) != 0) { TRACE ("ioctl");