Как работает функция libc isatty ()? - PullRequest
4 голосов
/ 03 июня 2019

Я искал репозиторий linux и не смог найти для него определения, так что я думаю, это что-то, что идет с C или что-то в этом роде? Я пытаюсь понять, как isatty может сказать, является ли файловый дескриптор терминалом или нет, и что это даже означает "быть терминалом" на техническом языке.

Я не совсем уверен, где найти его реализацию, и если он в сборке, я не смогу очень легко следовать за ним.

Ответы [ 2 ]

1 голос
/ 03 июня 2019

isatty(3) - это библиотечная функция (вы ничего не найдете в ядре linux), которая обычно реализуется путем вызова tcgetattr(3) и проверки возвращаемого значения.

Например, в библиотеке GNU C (glibc):

/* Return 1 if FD is a terminal, 0 if not.  */
int
__isatty (int fd)
{
  struct termios term;

  return __tcgetattr (fd, &term) == 0;
}

tcgetattr(3) само разрешится в некоторый ioctl, такой как TCGETA или TCGETS.

Обратите внимание, что isatty(3) также вернет true для главной стороны псевдотерминала, что на самом деле не tty - большинство операций, связанных с tty, выполняемых на нем, на самом деле применяются к его подчиненной стороне.

В linux isatty(3) также возвращает true для /dev/console, что опять-таки не является действительным tty (его нельзя сделать контролирующим tty процесса).

В linux вы можете получить список всех драйверов tty в вашей системе с их старшими и младшими номерами через cat /proc/tty/drivers. Конечно, это отражает только те модули, которые были загружены.

1 голос
/ 03 июня 2019

Общая стратегия для реализации isatty состоит в том, чтобы выполнить tty-специфическую операцию ioctl над дескриптором файла и проверить на ENOTTY результат ошибки.Традиционно используется TCGETS, который является бэкэндом для функции tcgetattr, но это немного опасно, так как число ioctl для него в Linux конфликтует с устаревшими звуковыми устройствами OSS, и если дескриптор файла фактически ссылается наопределенный тип MIDI-устройства, он будет вносить изменения в устройство.В musl libc мы используем TIOCGWINSZ, операцию «получения размера окна», число которой случайно не использовалось для любых других типов устройств и которая надежно завершается ошибкой с ENOTTY для нетитовых устройств.

Теоретически, вы могли бы сделать это с помощью fstat и проверить поле st_rdev для основного номера устройства, но для этого потребовался бы жестко запрограммированный список всех основных устройств, которые являются ttys, и они были бы повреждены при добавлении новых типов.(например, устройства USB-serial / ACM, устройства uartlite и т. д.).

...