Системное программирование в UNIX средствами Free Pascal



Командный интерпретатор smallsh


В этом разделе создается простой командный интерпретатор smallsh. Этот пример имеет два достоинства. Первое состоит в том, что он развивает понятия, введенные в этой главе. Второе – в том, что подтверждается отсутствие в стандартных командах и утилитах UNIX чего-то особенного. В частности, пример показывает, что оболочка является обычной программой, которая запускается при входе в систему.

Наши требования к программе smallsh просты: она должна транслировать и выполнять команды – на переднем плане и в фоновом режиме – а также обрабатывать строки, состоящие из нескольких команд, разделенных точкой с запятой. Другие средства, такие как перенаправление ввода/вывода и раскрытие имен файлов, могут быть добавлены позднее.

Основная логика понятна:

while не встретится EOF do

begin

  получить строку команд от пользователя

  оттранслировать аргументы и выполнить

  ожидать возврата из дочернего процесса

end;

Дадим имя userin функции, выполняющей «получение командной строки от пользователя». Эта функция должна выводить приглашение, а затем ожидать ввода строки с клавиатуры и помещать введенные символы в буфер программы. Функция userin реализована следующим образом:

uses stdio,linux;

(* Заголовочный файл для примера *)

{$i smallsh.inc}

 

(* Буферы программы и рабочие указатели *)

var

  inpbuf:array [0..MAXBUF-1] of char;

  tokbuf:array [0..2*MAXBUF-1] of char;

const

  ptr:pchar=@inpbuf[0];

  tok:pchar=@tokbuf[0];

 

 (* Вывести приглашение и считать строку *)

function userin(p:pchar):integer;

var

  c, count:integer;

begin

  (* Инициализация для следующих процедур *)

  ptr := inpbuf;

  tok := tokbuf;

  (* Вывести приглашение *)

  write(p);

  count := 0;

  while true do

  begin

    c := getchar;

    if c = EOF then

    begin

      userin:=EOF;

      exit;

    end;

    if count < MAXBUF then

    begin

      inpbuf[count] := char(c);

      inc(count);

    end;

    if (c = $a) and (count < MAXBUF) then

    begin

      inpbuf[count] := #0;




Содержание  Назад  Вперед