Arhn - архитектура программирования

Возможно ли, что дескриптор файла linux 0 1 2 не для stdin, stdout и stderr?

Когда программа запускается, принимает ли она файловые дескрипторы 0, 1 и 2 для stdin, stdout и stderr по умолчанию? И не будут ли вызовы API, такие как open(...), socket(...), возвращать 0, 1 и 2, поскольку эти значения уже приняты? Есть ли случай, когда open(...) или socket(...) вернут 0, 1 или 2. И 0, 1 и 2 не связаны с stdin, stdout и stderr.

13.03.2014

  • Как я ответил, ваш вопрос не имеет большого смысла. файловый дескриптор 0 всегда является стандартным. 13.03.2014

Ответы:


1

На уровне файлового дескриптора stdin определяется как файловый дескриптор 0, stdout определяется как файловый дескриптор 1; а stderr определяется как файловый дескриптор 2. См. это.

Даже если ваша программа или оболочка- изменятся (например, перенаправление с помощью dup2(2 )) что такое файловый дескриптор 0, он всегда остается stdin (поскольку по определению STDIN_FILENO равен 0).

Конечно, stdin может быть каналом, сокетом или файлом (не терминалом). Вы можете проверить с помощью isatty(3), если это tty и/или используйте fstat(2) для получения информации о состоянии на нем.

Системные вызовы типа open(2) или pipe(2) или socket(2) может дать, например STDIN_FILENO (т.е. 0), если этот файловый дескриптор свободен (например, потому что он был закрыть(2)-d раньше). Но когда это происходит, это по-прежнему stdin по определению.

Конечно, в stdio(3) поток FILE stdin немного сложнее. Ваша программа может fclose(3), freopen(3), fdopen(3) ...

Вероятно, ядро ​​устанавливает файловые дескрипторы stdin, stdout и stderr на консоль при волшебном запуске /sbin/init в качестве первого процесса.

13.03.2014

2
  1. #P1#
    #P2# #P3#
    #P4#
  2. #P5#
    #P6#
  3. #P7#
    #P8#
    close(0);
    close(1);
    close(2);
    open(...); /* this open will return 0 if success */
    
13.03.2014
  • Наследование сокета как FD 0 также происходит, если программа запускается с помощью inetd или чего-то еще, что ведет себя так же. 13.03.2014
  • Обратите внимание, что именно это делает оболочка, когда вы просите ее перенаправить эти потоки — она повторно открывает эти дескрипторы файлов, чтобы они указывали на файл или канал, как вы просили. (Я только что работал над некоторым кодом в логике запуска WebSphere, который делает что-то похожее на настройку обработки WebSphere native_stdout.log и native_stderr.log.) 13.03.2014
  • Перенаправление ввода-вывода @keshlam также может быть реализовано с использованием dup() или dup2(). 13.03.2014

  • 3

    Хотя пара ответов уже существовала, но я не нашел их достаточно информативными, чтобы объяснить всю историю.

    Поскольку я пошел дальше и исследовал больше, я добавляю свои выводы.

    Всякий раз, когда процесс запускается, запись о запущенном процессе добавляется в каталог /proc/<pid>. Это место, где хранятся все данные, связанные с процессом. Кроме того, при запуске процесса ядро ​​выделяет процессу 3 файловых дескриптора для связи с тремя потоками данных, называемыми stdin, stdout и stderr.
    ядро ​​linux использует алгоритм, всегда создающий FD с наименьшим возможным целочисленным значением, поэтому эти потоки данных отображаются на числа 0, 1 и 2.

    Так как это не что иное, как ссылки на поток, и мы можем закрыть поток. Можно легко вызвать close(<fd>), в нашем случае close(1), чтобы закрыть файловый дескриптор.

    при выполнении ls -l /proc/<pid>/fd/ мы видим только 2 FD, перечисленных там 0 и 2.
    Если мы сейчас выполним вызов open(), ядро ​​создаст новый FD для сопоставления этой новой ссылки на файл, и поскольку ядро ​​использует алгоритм поиска с наименьшим целым числом, оно подберет целочисленное значение 1.

    Итак, теперь новый созданный FD указывает на файл, который мы открыли (используя системный вызов open())
    Любая передача данных, которая происходит сейчас, осуществляется не через поток данных по умолчанию, который был связан ранее, а через новый файл, который мы открыли.

    Так что да, мы можем сопоставить FD 0, 1 или 2 с любым файлом и не обязательно stdin, stdout или stderr

    12.07.2020
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..