Почему функция cfsetospeed находится в glibc, а не в кодовой базе termios ядра или не обрабатывается вызывающей стороной?

Вопрос или проблема

Функция cfsetospeed в musl и glibc просто устанавливает скорость для поля c_cflag структуры termios, хотя и после некоторых проверок битов и операций с использованием CBAUD.

Вот реализация musl

    int cfsetospeed(struct termios *tio, speed_t speed)
    {
      if (speed & ~CBAUD) {
        errno = EINVAL;
        return -1;
      }
      tio->c_cflag &= ~CBAUD;
      tio->c_cflag |= speed;
      return 0;
    }

Почему это не может сделать ядро? Или вызывающая сторона, если на то пошло?

Является ли CBAUD специфичным для платформы? “Зависит от реализации”?
Какое-то специальное значение, о котором знают только поставщики libc?

Поиск CBAUD дал ответ.
Довольно интересно.

Похоже, CBAUD — это всего лишь одна из множества возможностей, используемых при установке поля c_cflag

Никогда не инициализируйте поле c_cflag (или любое другое поле) напрямую; вы всегда должны использовать побитовые операторы AND, OR и NOT, чтобы устанавливать или очищать биты в полях. Разные версии операционных систем (и даже патчи) могут и используют биты по-разному…

Функции cfsetospeed(3) и cfsetispeed(3) предоставляются для установки
скорости передачи в структуре termios независимо от интерфейса операционной
системы.

Полный текст и таблица констант для поля c_cflag находятся здесь
https://wiki.control.fel.cvut.cz/pos/cv5/doc/serial.html

Ответ или решение

Функция cfsetospeed, присутствующая в библиотеках C, таких как glibc и musl, отвечает за установку скорости передачи данных в структуре termios. Несмотря на её наличие в библиотеках стандартной библиотеки C, а не в кодовой базе ядра Linux, это решение продиктовано несколькими важными факторами, связанными с архитектурой операционной системы, гибкостью и портируемостью.

Почему cfsetospeed находится в glibc и не обрабатывается в ядре

  1. Абстракция аппаратных деталей: Ядро операционной системы отвечает за управление аппаратными ресурсами и выполнение низкоуровневых операций. Однако конкретные реализации настройки параметров, таких как скорости передачи данных, могут существенно различаться в зависимости от конкретного аппаратного обеспечения и его возможностей. Функция cfsetospeed выступает в роли абстракции, позволяющей разработчикам инкапсулировать логику установки скорости без необходимости углубляться в детали работы с различными аппаратными решениями.

  2. Гибкость и стандартность: Использование стандартной библиотеки для таких операций упрощает создание переносимых приложений, работающих на различных операционных системах и архитектурах. Это позволяет разработчикам полагаться на однородный интерфейс для доступа к функциональности, вместо того чтобы писать уникальный код для каждой целевой платформы.

  3. Проверка корректности данных: В приведенном выражении кода реализуется проверка входного значения speed с использованием макроса CBAUD, который ограничивает возможные значения, которые может принимать скорость передачи. Это позволяет предотвратить ошибки, связанные с установкой неверных значений, что значительно улучшает стабильность программного обеспечения.

Почему это не выполняется вызывающей стороной

  1. Сложность управления флагами: Установка битов в члене структуры c_cflag требует применения битовых операций для корректного наложения флагов. Если бы этот процесс выполнялся вызывающей стороной, это увеличивало бы вероятность ошибок и несоответствий между различными реализациями и версиями ОС.

  2. Методология работы с конфигурациями: Задача управления флагами и конфигурационными параметрами, такими как скорость передачи данных, требует хорошо определенной и согласованной стратегии. Разлучение этой логики от вызывающего кода позволяет обеспечить единообразие и делает код более читаемым и поддерживаемым.

Платформенная специфичность CBAUD

Макрос CBAUD действительно является платформенно специфичным, так как различные аппаратные решения могут по-разному интерпретировать и использовать биты в c_cflag. Разработчикам рекомендуется не инициализировать c_cflag напрямую, а использовать специальные функции, такие как cfsetospeed, которые знают о местных нюансах и индивидуальных особенностях платформы.

Заключение

Функция cfsetospeed в glibc и musl иллюстрирует важность отделения логики программного обеспечения от аппаратных деталей, улучшая таким образом переносимость и упрощая разработку приложений. Это также подчеркивает необходимость в стандартизации интерфейсов для работы с системными уровнями, благодаря чему разработчики могут сосредоточиться на функциональности своих приложений, не отвлекаясь на детали взаимодействия с аппаратным обеспечением. Таким образом, хранение этой логики в библиотеке C вместо ядра или в вызывающем коде является не только разумным, но и необходимым шагом для обеспечения стабильности и универсальности при разработке программного обеспечения.

Оцените материал
Добавить комментарий

Капча загружается...