Каков правильный способ получить список всех доступных последовательных портов/устройств в системе Linux?
Другими словами, когда я перебираю все устройства в /dev/
, как я могу определить, какие из них являются последовательными портами классическим способом, то есть те, которые обычно поддерживают скорость передачи и RTS/CTS контроль потока?
Решение будет закодировано в C.
Я прошу, потому что я использую стороннюю библиотеку, которая делает это явно неправильным: она, кажется, перебирает только /dev/ttyS*
. Проблема в том, что есть, например, последовательные порты через USB (предоставляются адаптерами USB-RS232), и они перечислены в разделе /dev/ttyUSB *. И, прочитав Serial-HOWTO на Linux.org, я понял, что с появлением других пространств имен также будет время.
Поэтому мне нужно найти официальный способ обнаружения последовательных устройств. Проблема в том, что никто не документируется, или я не могу его найти.
Я предполагаю, что одним из способов было бы открыть все файлы из /dev/tty*
и вызвать для них конкретный ioctl()
, который доступен только на последовательных устройствах. Будет ли это хорошим решением?
Update
hrickards предложили посмотреть источник для "setserial". Его код делает именно то, что я имел в виду:
Сначала он открывает устройство с помощью:
fd = open (path, O_RDWR | O_NONBLOCK)
Затем он вызывает:
ioctl (fd, TIOCGSERIAL, &serinfo)
Если этот вызов не возвращает ошибку, значит, это последовательное устройство.
Я нашел аналогичный код в Serial Programming/termios, в котором также предлагается добавить параметр O_NOCTTY
.
Есть одна проблема с этим подходом:
Когда я протестировал этот код на BSD Unix (то есть Mac OS X), он также работал. Однако, последовательные устройства, которые предоставляются через Bluetooth, приводят к тому, что система (драйвер) пытается подключиться к устройству Bluetooth, что занимает некоторое время, прежде чем оно вернется с ошибкой таймаута. Это вызвано просто открытием устройства. И я могу себе представить, что подобные вещи могут произойти и в Linux - в идеале, мне не нужно открывать устройство, чтобы выяснить его тип. Интересно, есть ли способ вызвать функции ioctl
без открытого или открыть устройство таким образом, чтобы он не вызывал соединения?
Что мне делать?