[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Упражнения

Создание двух процессов
Напишите программу, которая создает подпроцесс. Этот подпроцесс должен
исполнить cat(1) длинного файла. Родитель должен вызвать printf(3S) и
распечатать какой-либо текст.
После выполнения первой части задания модифицируйте программу так,
чтобы последняя строка, распечатанная родителем, выводилась после
завершения порожденного процесса. Используйте wait(2), waitid(2) или
waitpid(3C).
Код завершения команды
Напишите программу, которая запускает команду, заданную в качестве
первого аргумента, в виде порожденного процесса. Все остальные
аргументы программы передаются этой команде. Затем программа должна
дождаться завершения порожденного процесса и распечатать его код
завершения.
Функция execvpe()
Напишите функцию execvpe(), которая работает как execvp(2), но
позволяет изменять среду исполнения, как execve(2). Совет: используйте
внешнюю переменную environ.
Командный интерпретатор shell
В этом упражнении вы должны разработать упрощенную версию командного
интерпретатора системы UNIX - shell. В Части 2 этого курса этот shell
будет улучшен добавлением программных каналов и обработки сигналов.
Для вас заранее написаны некоторые функции этой программы. В файле
shell.c содержится скелет функции main() с комментариями, говорящими,
где следует вставить ваш код. Функция main() вызывает функцию
prompline() из файла promptline.c, которая читает строку из
стандартного ввода. Затем main() вызывает parseline() из файла
parseline.c, которая проверяет ввод на отсутствие синтаксических
ошибок. Для каждой команды в строке, parseline() формирует дескриптор
команды типа struct command, определенного в shell.h Существует
глобальный массив таких структур, называемый cmds[] и объявленный в
shell.c.
Дескриптор команды состоит из двух полей. Первое поле - массив
указателей, называемый cmdargs[]. Функция parseline() инициализирует
этот массив указателями на строки - аргументы. Каждый аргумент
завершается нулевым байтом. Во входной строке аргументы разделяются
пробелами. Кроме того, parseline() помещает после последнего аргумента
в списке cmdargs[] нулевой указатель. Команды могут разделяться
переводом строки, точкой с запятой, амперсендом (&) или символами <,
>, >> или |.
Другие глобальные переменные, объявленные в shell.c определяют, должна
ли команда быть запущена в основном (foreground) или фоновом
(background) режиме, а также для перенаправления ввода/вывода из/в
файл. Эти переменные (bkgrnd, infile, outfile и appfile)
устанавливаются в функции parseline(). Если bkgrnd ненулевой, команда
должна быть запущена в фоновом режиме, то есть ваш shell не должен
ожидать завершения соответствующего процесса. Если infile ненулевой,
он указывает на имя файла, из которого должен быть получен стандартный
ввод первой команды в строке, т.е. символ <. Аналогично, если outfile
ненулевой, он указывает на имя файла, куда следует перенаправить вывод
последней команды в строке, т.е. символ >. Наконец, если appfile
ненулевой, это имя файла, к содержимому которого следует добавить
вывод последней команды в строке, т.е. символ >>.
В следующих упражнениях вы будете модифицировать shell.c. Каждое
последующее упражнение является улучшением предыдущего. Вы должны
использовать следующую версию вызова exec(2):
          execvp(cmds[i].cmdargs[0], cmds[i].cmdargs);
Исполнение команд
Модифицируйте shell.c для исполнения каждой команды в массиве cmds[]
как подпроцесса. Во время исполнения этого подпроцесса, ваша программа
должна ждать его завершения. Если программа, заданная во входной
строке, не может быть найдена, shell должен распечатать сообщение об
ошибке и продолжить исполнение. Предполагается, что пользователь
набирает только простые команды, т.е. только одна команда на строке,
без метасимволов, перенаправления ввода/вывода, конвейеров и символа
&.
Исполнение в фоновом режиме
Измените вашу программу так, чтобы позволить исполнение команд в
фоновом режиме, обозначаемое символом & в конце командной строки.
Программа должна выводить идентификатор фонового процесса на
стандартный вывод.
Перенаправление ввода/вывода
Измените вашу программу так, чтобы позволить перенаправление
ввода/вывода. Заметьте, что перенаправление ввода ("< filename")
используется только с первой командой в строке, а вывода ("> filename"
или ">> filename") - только с последней. Совет: используйте dup(2).