- •Операционные системы для программиста
- •Введение
- •1. Основные понятия
- •1.1. Понятие операционной системы
- •1.2. Системные соглашения для доступа к функциям ос
- •1.3. Особенности разработки программ в базовых ос
- •1.4. Командный интерфейс пользователя в ос
- •1.5. Информация об ошибках системной функции
- •2. Программный доступ к файловой системе
- •2.1. Понятия дескрипторов, идентификаторов и хэндлов
- •2.2. Ввод и вывод в стандартные файлы.
- •2.3. Базовые средства использования файлов
- •2.4. Многопользовательская блокировка файлов
- •2.5. Установка произвольной позиции в файле
- •3. Принципы построения ос
- •3.1. Модульная структура построения ос
- •3.2. Использование прерываний в ос
- •3.3. Управление системными ресурсами
- •3.4 Строение ядра операционной системы
- •3.5. Структура операционной системы типа Windows nt
- •4. Многофункциональный консольный вывод
- •4.1. Функции управления курсором
- •4.2. Многократный вывод символов и атрибутов
- •4.3. Вывод в произвольную позицию экрана
- •4.4. Ввод данных, размещенных предварительно на экране
- •5. Системные функции ввода для консольных устройств
- •5.1. Системные функции ввода текстовых строк
- •5.2. Событийно-управляемый ввод
- •5.3. Системные функции ввода с клавиатуры
- •5.4. Опрос ввода с клавиатуры в программе
- •5.5. Системные функции мыши для текстового режима
- •6. Файловые системы
- •6.1. Структуры файловых систем для пользователя
- •6.2. Методы распределения внешней памяти
- •6.3. Принципы построения файловых систем типа fat
- •6.4. Современные модификации файловой системы fat
- •6.5. Особенности построения файловой системы hpfs
- •6.6. Принципы построения файловой системы ntfs
- •6.7. Особенности строения файловых систем для Unix
- •6.8. Программный опрос файловой системы
- •7. Обеспечение множественности процессов
- •7.1. Основные понятия теории вычислительных процессов
- •7.2. Программное порождение процессов
- •7.3. Уничтожение процессов
- •7.4. Ожидание завершения процессов
- •8. Многопоточное функционирование ос
- •8.1. Понятие нити и связь Хе с процессом
- •8.2. Создание нитей (thread) в программе
- •8.3. Уничтожение нитей
- •8.4. Приостановка и повторный запуск нити
- •8.5. Ожидание завершения нити
- •9. Средства взаимодействия программных единиц
- •9.1. Абстрактные критические секции
- •9.2. Абстрактные семафоры
- •9.3. Семафоры взаимоисключения
- •9.4. Семафоры событий
- •9.5. Средства группового ожидания
- •9.6. Программные критические секции
- •9.7. Программные семафоры с внутренним счетчиком
- •10. Управление памятью
- •10.1. Виртуальная память
- •10.2. ЏодкРчка страниц для реализациШ виртуальной памяти
- •10.3. Системные функции распределения памяти
- •10.4. Совместное использование памяти
- •10.5. Отображение файлов в оперативную память
- •10.6. Динамически распределяемая память
- •11. Средства коммуникации процессов
- •11.1. Неименованные коммуникационные каналы Unix
- •11.2. Переназначение хэндлов для доступа к каналу
- •11.3. Неименованные каналы в Windows
- •11.4. Именованные каналы в Windows nt
- •11.5. Именованные каналы в Unix
- •12. Взаимодействие пользователя с ос
- •12.1. Интерфейсы операционных систем
- •12.2. Командные и операционные оболочки (shells)
- •12.3. Основные команды базовых операционных систем
- •12.4. Групповое выполнение и фоновый запуск команд
- •12.5. Стандартный ввод-вывод и конвейеры командной строки
- •12.6. Командные файлы и сценарии
- •Библиографический список
5. Системные функции ввода для консольных устройств
5.1. Системные функции ввода текстовых строк
Как ни странно, ввод текстовых строк организуется для пользователей системных функций проще чем ввод отдельных символов. Поэтому с ввода текстовых строк и начнем.
В операционных системах MS Windows для ввода текстовых строк с клавиатуры в консольном режиме предназначена функция ReadConsole с прототипом
BOOL ReadConsole(HANDLE hConsInput, VOID* buffer,
DWORD len, DWORD *actlen, VOID* reserved).
Первый параметр этой функции задает хэндл буфера ввода для консоли. Он в простейших (и большинстве) случаях получается в результате вызова функции GetStdHandle с аргументом STD_INPUT_HANDLE. Параметр buffer задает буфер для ввода текстовой строки, а параметр len определяет максимальный размер вводимой строки (обычно этот параметр совпадает с длиной буфера buffer). Параметр actlen используется для получения числа – сколько символов было введено в результате выполнения функции. (В число символов входит и завершающий символ '\n'.) Последний параметр вызова функции зарезервирован разработчиками и должен браться равным NULL.
Заметим, что рассмотренная функция дает возможность ввода с консоли только в том случае, когда стандартный ввод не переназначен. Если же это условие нарушено, то данная функция возвращает значение FALSE, свидетельствующее об ошибке. При необходимости в Windows осуществлять ввод только с консоли, даже когда стандарный ввод переназначен, следует открыть для ввода файл, обозначаемый специальным именем CON (применив функцию CreateFile) и осуществлять ввод из этого файла.
В операционной системе Unix для ввода текста с консоли, если стандартный ввод не переназначается, можно использовать стандартные функции gets и scanf. Следует заметить, что использование функции gets настойчиво не рекомендуется профессионалами. Дело в том, что она может вернуть текст большей длины, чем предусмотрено программистом в ее вызове. Такая ситуация приводит к катастрофическим последствиям. Единственным эффективным решением указанной проблемы является отказ от применения данной функции. Вместо нее допустимо использовать более общую функцию стандартной библиотеки Си с прототипом
char* fgets(char *s, int size, FILE *stream),
где в качестве последнего параметра можно использовать символическую константу stdin, обозначающую поток стандартного ввода. (В этой функции явно указывается максимальный размер size текста, который может быть введен при ее вызове.) В то же время рассмотренная возможность не дает принципиального решения проблемы ввода с консоли, поскольку стандартный ввод может переназначаться в момент вызова программы в Unix.
В Unix для специализированного ввода именно с консоли следует использовать непосредственно устройство консоли как специальный файл. С этой целью нужно открыть доступ к виртуальной консоли, имеющей файловое имя /dev/tty. (В Unix обычно параллельно функционирует ряд виртуальных консолей, обозначаемых именами /dev/tty1, /dev/tty2, /dev/tty3 и т.д., но обозначение /dev/tty задает текущую управляющую консоль для исполняемой программы.) Заметим, что в Unix по историческим причинам принято называть консоль словом терминал, которое в общем случае обозначает нечто гораздо более общее, в частности, удаленное средство доступа к операционной системе. В данном изложении для единообразия в рассмотрении средств различных ОС будет использоваться термин консоль как приближенное наименование терминала в Unix.
Открытие доступа к терминалу Unix выполняется обычной функцией открытия, например, в виде
hcons=open("/dev/tty",O_RDONLY),
где переменная hcons должна быть предварительно описана как целочисленная. После такого открытия можно использовать функцию read(hcons, buffer, сколько) для чтения текста непосредственно с клавиатуры (даже если стандартный ввод переназначен).