%20console%20%D0%B4%D0%BB%D1%8F%20%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2%D1%8B%D1%85%20%D0%B4%D0%B5%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D1%80%D0%BE%D0%B2%20%D0%BF%D0%BE%20%D1%83%D0%BC%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8%D1%8E.png)
Я читаю реализацию программы оболочки на языке C (оболочка xv6 из курса 6.828 «Инженерия операционных систем» Массачусетского технологического института).
Функция main()
этой оболочки начинается со следующего кода:
//Assumes three file descriptors open
while((fd = open("console", O_RDWR)) >= 0){
if(fd >= 3){
close(fd)
break;
}
}
Это цитата из книги xv6, которая объясняет приведенный выше код:
«Оболочка гарантирует, что у нее всегда открыты три файловых дескриптора, которые являются файловыми дескрипторами по умолчанию для консоли».
Я понимаю, что open()
это вернет файловый дескриптор с наименьшим доступным номером, таким образом, этот код гарантирует, что открыто не более трех файловых дескрипторов, что довольно очевидно после прочтения объяснения автора.
Но вот что я не понимаю:
Почему оболочка хочет закрыть все файловые дескрипторы, кроме 0, 1 и 2? В конце концов, гарантировано, что 0, 1 и 2 будут связаны с консолью, не так ли? Почему оболочка должна заботиться о том, чтобы закрывались файловые дескрипторы с большим номером?
Наверное, я не совсем понимаю назначение файла console ( /dev/console ? ).
решение1
Этот фрагмент кода открывает /dev/console
. Результирующий файловый дескриптор — это файловый дескриптор с наименьшим номером, который еще не открыт. Если это число не больше 2, цикл выполняется снова. Если это число равно 3 или больше, дескриптор закрывается и цикл останавливается.
Когда цикл завершается, файловые дескрипторы от 0 до 2 (stdin, stdout и stderr) гарантированно открыты. Либо они были открыты ранее и могут быть подключены к любому файлу, либо они были только что открыты и подключены к /dev/console
.
Выбор /dev/console
странный. Я бы ожидал /dev/tty
, что , который всегда является управляющим терминалом, связанным с группой процессов вызывающего процесса. Это один из немногих файлов, которыестандарт POSIX требует существования. /dev/console
этосистемная консоль, куда попадают сообщения syslog, отправляемые на консоль; оболочке нет смысла беспокоиться об этом.
решение2
Это интересно для цикла. 'open()' возвращает наименьшее количество файловых дескрипторов. Например, текущий fd равен 10, что иллюстрирует, что 0,1... и 9 были открыты ранее. Он закрывает один дополнительный файловый дескриптор для консоли, которую он только что открыл.