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



         

Пример управления терминалом: программа tscript - часть 2


var

  act:sigactionrec;

  mfd, sfd:longint;

  err:integer;

  buf:array [0..511] of char;

  mask:sigset_t;

begin

  (* Сохранить текущие установки терминала *)

  tcgetattr (0, dattr);

  (* Открыть псевдотерминал *)

  err := pttyopen (mfd, sfd);

  if err <> 1 then

  begin

    writeln (stderr, 'pttyopen: ', err);

    perror ('Ошибка при открытии псевдотерминала');

    halt (1);

  end;

  (* Установить обработчик сигнала SIGCHLD *)

  act.handler.sh := @catch_child;

  sigfillset (@mask);

  act.sa_mask:=mask.__val[0];

  sigaction (SIGCHLD, @act, nil);

  (* Создать процесс оболочки *)

  case fork of

    -1:               (* ошибка *)

    begin

      perror ('Ошибка вызова оболочки');

      halt (2);

    end;

    0:                (* дочерний процесс *)

    begin

      fdclose (mfd);

      runshell (sfd);

    end;

    else         (* родительский процесс *)

    begin

      fdclose (sfd);

      script (mfd);

    end;

  end;

end.

Основная программа использует четыре процедуры. Первая из них называется catch_child. Это обработчик сигнала SIGCHLD. При получении сигнала SIGCHLD процедура catch_child восстанавливает атрибуты терминала и завершает работу.

procedure catch_child (signo:integer);cdecl;

begin

  tcsetattr (0, TCSAFLUSH, dattr);

  halt (0);

end;

Вторая процедура, pttyopen, открывает псевдотерминал.

function pttyopen (var masterfd, slavefd:longint):integer;

var

  slavenm:pchar;

begin

  (* Открыть псевдотерминал -

   * получить дескриптор файла главного устройства *)

  masterfd := fdopen ('/dev/ptmx', Open_RDWR);

  if masterfd = -1 then

  begin

    pttyopen:=-1;

    exit;

  end;

  (* Изменить права доступа для ведомого устройства *)

  if grantpt (masterfd) = -1 then

  begin

    fdclose (masterfd);

    pttyopen:=-2;

    exit;

  end;

  (* Разблокировать ведомое устройство, связанное с mfd *)

  if unlockpt (masterfd) = -1 then

  begin

    fdclose (masterfd);

    pttyopen:=-3;

    exit;

  end;




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