Безопасно ли использовать fd 3?

Безопасно ли использовать fd 3?

Есть несколько вопросов, в которых он используется для таких вещей, как несколько выходных каналов без использования подстановки процессов:

Безопасно ли просто использовать фиксированный номер fd для этого? Возможно ли, что программа уже использует его, как описаноздесьи мы перезаписываем что-то важное или читаем что-то постороннее?

решение1

Возможно ли, что программа уже использует его?

Нет. Видите ли, перенаправление ввода-вывода происходит до запуска программы или скрипта.

Обычно при запуске программы или скрипта открыты только стандартные дескрипторы (0/стандартный ввод, 1/стандартный вывод и 2/стандартная ошибка). (Они могут ссылаться на терминал, устройство, файл или даже сетевой сокет; но ожидается, что они будут открыты. Вместо того, чтобы «закрыть» один, мы перенаправляем нежелательный дескриптор из/в /dev/null, по сути «никуда»/«ничего».)

Программы используют дескрипторы через системные вызовы, например, openкоторые используют свободный дескриптор. То есть, они не просят ядро ​​открыть файл или сокетк определенному дескриптору, ядро ​​выбирает дескриптор. Таким образом, единственный случай, когда программа использует дополнительный дескриптор, это когда ожидается, что он уже открыт при запуске программы. Существуют некоторые редкие служебные демоны, подобные этому, — в дополнение к стандартным дескрипторам они ожидают, что если, например, дескриптор 3 открыт при их запуске, он подключен к их службе управления (или чему-то подобному).

Если программа решает использовать жестко запрограммированный дескриптор (а единственная причина, по которой это необходимо, заключается в том, что она разветвляется и выполняет другую программу, котораянадеетсяэтот дескриптор должен быть открыт; как я уже сказал, это случается очень редко), уже открытый дескриптор закрывается, когда программа заменяет его тем, для чего он используется. (Кстати, ядро ​​выполняет закрытие, когда программа указывает, что хочет использовать определенный дескриптор, например, dup2()в системах POSIXy; процессу это не нужно.)

Скрипты оболочки (Bash и sh) используют фиксированные номера дескрипторов, поэтому возможно, что скрипт использует определенный дескриптор для выполнения некоторых перенаправлений ввода/вывода. Однако, когда это происходит, предыдущие перенаправления просто игнорируются и не имеют никакого эффекта, потому что скрипты предполагают, что дескриптор был закрыт. (Если дескриптор открыт, и скрипт использует этот дескриптор для каких-то внутренних вещей, исходный дескриптор сначала закрывается — ядром, и по причинам, указанным в предыдущем абзаце — когда скрипты перенаправляют его. Для того, чтобы произошла какая-либо утечка данных, скрипт должен был бы специальнотестесли дескриптор уже открыт, иизбегатьперенаправив его.)

Также обратите внимание, что блоки ввода-вывода Fortran или каналы не связаны с дескрипторами, даже если оба используют номер для идентификации. Таким образом, даже если программа Fortran использует блок 10, это не означает, что она использует дескриптор 10.

Безопасно ли использовать для этого фиксированный номер FD?

Да. POSIX гласит, что программа может иметь не менее 20 открытых дескрипторов, поэтому любое фиксированное число от 3 до 19 должно работать нормально.

Главное — хорошо документировать его, желательно в виде короткого комментария в начале скрипта (для скриптов) или на странице использования ( -hили --helpпараметра командной строки) и в справочном руководстве (для программ).

Для скриптов вы можете предположить, что если возникнет конфликт (а если он возникнет, то это будет что-то вроде «скрипт вообще не работает, потому что канал закрывается сразу после запуска программы», как подробно описано выше), пользователи могут изменить фиксированный номер дескриптора, чтобы он лучше соответствовал их потребностям. Поэтому ваша задача как автора скрипта — планировать заранее и упростить это для тех, кто придет после. (Достаточно четкого комментария, описывающего ваши намерения и общий дизайн; не обязательно делать номер дескриптора переменной или описывать каждое мелкое действие, которое выполняет скрипт.)

Для программ хорошей идеей будет сделать его настраиваемым во время выполнения. Например, вы можете заставить свою программу/демон использовать дескриптор 3, если он открыт, для специального протокола управления с графическим пользовательским интерфейсом; но, используя некоторые параметры командной строки, например '-c 5', используйте именованный дескриптор (или, с -c /dev/nameили -c named-pipeили -c :socketpath используйте указанный файл, именованный канал или локальный доменный сокет). Таким образом, пользователи могут легко обойти любые конфликты со скриптами.

Связанный контент