(* Программа unfreeze -- освобождение терминала *)
uses stdio,linux,strings;

const
  LINESZ =150;
  SUCCESS=0;
  ERROR  =(-1);

(* Получить подтверждение, затем завершить работу программы *)
function dokill(procid:longint;line,hd:pchar):integer;
var
  c:char;
begin
  writeln (#$a'Найден процесс, выполняющий заданную программу :');
  writeln (#9,hd,#9,line);
  writeln ('Нажмите `y` для завершения процесса ', procid);
  write (#$a'Yes\No? > ');
  (* Введите следующий не пробельный символ *)
  readln (c);
  if (c = 'y') or (c = 'Y') then
  begin
    kill (procid, SIGKILL);
    dokill:=SUCCESS;
    exit;
  end;
  dokill:=ERROR;
end;


const
  killflag:integer=0;
  (* Инициализация этой переменной зависит от вашей системы *)
  pspart:pchar = 'ps t ';
  fmt:pchar = '%d %*s %*s %*s %s';
var
  comline, inbuf, header, name:array [0..LINESZ-1] of char;
  f:pfile;  
  j:integer;
  pid:longint;
begin
  if paramcount <2 then
  begin
    writeln (stderr, 'синтаксис: ',paramstr(0),' терминал программа ...');
    halt (1);
  end;

  (* Сборка командной строки *)
  strcopy (comline, pspart);
  strcat (comline, argv[1]);

  (* Запуск команды ps *)
  f := pipeopen (comline, 'r');
  if f = nil then
  begin
    writeln (stderr, paramstr(0),': не могу запустить команду ps ');
    halt (2);
  end;

  (* Получить первую строку от ps и игнорировать ее *)
  if fgets (header, LINESZ, f) = nil then
  begin
    writeln (stderr, paramstr(0),': нет вывода от ps?');
    halt (3);
  end;

  (* Поиск программы, которую нужно завершить *)
  while fgets (inbuf, LINESZ, f) <> nil do
  begin
    if sscanf (inbuf, fmt, [@pid, pchar(name)]) < 2 then
      break;
    for j := 2 to argc-1 do
    begin
      if strcomp (name, argv[j]) = 0 then
      begin
        if dokill (pid, inbuf, header) = SUCCESS then
          inc(killflag);
      end;
    end;
  end;
  (* Это предупреждение, а не ошибка *)
  if killflag=0 then
    writeln(stderr, paramstr(0),': работа программы не завершена ',
	    paramstr(1));
  pipeclose(f);
  halt (0);
end.
