]> sigrok.org Git - libserialport.git/commitdiff
Ignore non-existant serial8250 ports on Linux.
authorMartin Ling <redacted>
Sun, 27 Oct 2013 12:51:55 +0000 (12:51 +0000)
committerUwe Hermann <redacted>
Thu, 14 Nov 2013 23:42:37 +0000 (00:42 +0100)
serialport.c

index a8f410eea624b1879bfe01173738aba46430fe6e..2916914fc8cdc9c1c4d809b2674e1cfa845ca1e3 100644 (file)
@@ -39,6 +39,7 @@
 #endif
 #ifdef __linux__
 #include "libudev.h"
+#include "linux/serial.h"
 #endif
 
 #include "serialport.h"
@@ -178,6 +179,9 @@ out_release:
        const char *path;
        struct udev_device *ud_dev, *ud_parent;
        const char *name;
+       const char *driver;
+       int fd, ioctl_result;
+       struct serial_struct serial_info;
 
        ud = udev_new();
        ud_enumerate = udev_enumerate_new(ud);
@@ -198,7 +202,23 @@ out_release:
                        continue;
                }
                name = udev_device_get_devnode(ud_dev);
+               /* The serial8250 driver has a hardcoded number of ports.
+                * The only way to tell which actually exist on a given system
+                * is to try to open them and make an ioctl call. */
+               driver = udev_device_get_driver(ud_parent);
+               if (driver && !strcmp(driver, "serial8250"))
+               {
+                       if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0)
+                               goto skip;
+                       ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info);
+                       close(fd);
+                       if (ioctl_result != 0)
+                               goto skip;
+                       if (serial_info.type == PORT_UNKNOWN)
+                               goto skip;
+               }
                list = sp_list_append(list, (void *)name, strlen(name) + 1);
+skip:
                udev_device_unref(ud_dev);
                if (!list)
                        goto out;