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

       

Файловая система proc


Упражнение 13.35. Напишите программу, печатающую: свои аргументы, переменные окружения, информацию обо всех открытых ею файлах и используемых каналах.

uses dos,linux,strings;

var

  i,n,pid:integer;

  s,fullname:array [0..200] of char;

  temp:string;

  d:pdir;

  el:pdirent;

begin

  i:=fdopen('/etc/passwd',Open_RDONLY);

  n:=paramcount;

  writeln('В командной строке ',paramcount+1, ' параметров');

  for i:=0 to n do



    writeln('Параметр ',i+1,' - ',paramstr(i));

  writeln('Переменные окружения:');

  n:=envcount;

  for i:=1 to n do

    writeln(envstr(i));

  pid:=getpid;

  strcopy(s,'/proc/');

  str(pid,temp);

  strpcopy(s+strlen(s),temp);

  strcat(s,'/fd/');

  d:=opendir(pchar(s));

  el:=readdir(d);

  writeln('Файлы, открытые процессом:');

  while el<>nil do

  begin

    if (strcomp(el^.name,'.')<>0) and (strcomp(el^.name,'..')<>0) then

    begin

      strcopy(fullname,s);

      strcat(fullname,el^.name);

      writeln('Дескриптор ',el^.name,' соответствует ',readlink(fullname));

    end;

    el:=readdir(d);

  end;

  closedir(d);

end.

 

Упражнение 13.36. Создайте аналог команды ps.

uses linux,strings,sysutils; (*для системных вызовов Linux и работы со строками PChar*)

var

  d:^TDir;        (*указатель на запись для работы с каталогом*)

  elem:^Dirent;   (*указатель на запись, хранящую один элемент каталога*)

  realname,                       (*имя процесса из файла status*)    

  fullpath                        (*полный путь к элементу каталога*)

          :array [0..1000] of char;

  number,coder:integer;    (*номер процесса и код ошибки преобразования*)

  f:text;

  name:string;

begin

  d:=opendir('/proc');        (*попытка открытия каталога для чтения*)

 

  if d=nil then                   (*если попытка не удалась*)

  begin

    writeln('Ошибка вызова opendir для каталога /proc');  (*диагностика*)

    halt(1);                        (*возврат в предыдущую программу*)

  end;

 

  elem:=readdir(d);               (*попытка чтения элемента каталога*)




  while elem<>nil do              (*пока не достигнут конец каталога*)

  begin

    (* пытаемся преобразовать имя элемента катлога в число*)

    val(strpas(elem^.name),number,coder);

    (*если это удается, катлог имеет числовое имя и соответствует процессу*)

    if coder=0 then

    begin

    (*формируем путь к файлу status в виде /proc/номер_процесса/status *)

      strcopy(fullpath,'/proc/');

      strcat(fullpath,elem^.name);

      strcat(fullpath,'/status');

      (*открываем файл и чтиаем из него первую строку*)

      assign(f,fullpath);

      reset(f);

      readln(f,name);

      close(f);

     (*вырезаем из строки ту ее часть, что соответствует имени процесса*)

      strlcopy(realname,@name[7],length(name));

      realname[length(name)-6]:=#0;

      (*выводим номер и имя процесса*)

      writeln(number,#9,realname);

    end;

    elem:=readdir(d);               (*попытка чтения элемента каталога*)

  end;

  closedir(d);                    (*закрытие открытого opendir каталога*)

end.

Упражнение 13.37. Используя файловую систему /proc, получите информацию об открытых всеми процессами файлах.

uses linux,strings,sysutils; (*для системных вызовов Linux и работы со строками PChar*)

var

  d,d1:^TDir;             (*указатель на запись для работы с каталогом*)

  elem,elem1:^Dirent;      (*указатель на запись, хранящую один элекмент каталога*)

  realname,                       (*имя процесса из файла status*)    

  fullpath,fullpath1              (*полный путь к элементу каталога*)

          :array [0..1000] of char;

  number,coder:integer;   (*номер процесса и код ошибки преобразования*)

  f:text;

  name:string;

begin

  d:=opendir('/proc');       (*попытка открытия каталога для чтения*)

 

  if d=nil then                   (*если попытка не удалась*)

  begin

    writeln('Ошибка вызова opendir для каталога /proc');  (*диагностика*)

    halt(1);                   (*возврат в предыдущую программу*)

  end;

 



  elem:=readdir(d);               (*попытка чтения элемента каталога*)

  while elem<>nil do              (*пока не достигнут конец каталога*)

  begin

    (* пытаемся преобразовать имя элемента катлога в число*)

    val(strpas(elem^.name),number,coder);

    (*если это удается, катлог имеет числовое имя и соответствует процессу*)

    if coder=0 then

    begin

      (*формируем путь к файлу status в виде /proc/номер_процесса/fd *)

      strcopy(fullpath,'/proc/');

      strcat(fullpath,elem^.name);

      strcat(fullpath,'/fd');

      d1:=opendir(fullpath);

      if d1=nil then

        writeln('Для процесса ',number,' информация об открытых файлах недоступна')

      else

      begin

        writeln('Процесс ',number,' открыл следующие файлы:');

        elem1:=readdir(d1);      (*попытка чтения элемента каталога*)

        while elem1<>nil do      (*пока не достигнут конец каталога*)

        begin

          strcopy(fullpath1,fullpath);

          strcat(fullpath1,'/');

          strcat(fullpath1,elem1^.name);

          if (strcomp(elem1^.name,'.')<>0) and (strcomp(elem1^.name,'..')<>0) then

          begin

            (*realname[readlink(realname,fullpath1,999)]:=#0;*)

              writeln(#9,readlink(strpas(fullpath1)));

          end;

          elem1:=readdir(d1);     (*попытка чтения элемента каталога*)

        end;

      end;

    end;

    elem:=readdir(d);               (*попытка чтения элемента каталога*)

  end;

  closedir(d);                    (*закрытие открытого opendir каталога*)

end.

Упражнение 13.38. Используя файловую систему /proc, получите информацию о типе, версии и дате выпуска операционной системы.

uses sysutils,crt,linux;

var

    f:text;

    count:integer;

    ch:char;

begin

assign(f,'/proc/version');

reset(f);

if IOResult<>0 then

 begin

  writeln('Неудалось открыть файл, попробуйте другими средствами');

  halt;

 end;

textcolor(7);

write('Тип операционной системы - ');



read(f,ch);

textcolor(2);

write(ch);

while ch<>' ' do

begin

read(f,ch);

write(ch);

end;

writeln;

while ch=' ' do

begin

read(f,ch);

end;

while ch<>' 'do

begin

read(f,ch);

end;

while ch=' ' do

begin

read(f,ch);

end;

textcolor(7);

write('Версия операционной системы - ');

textcolor(2);

write(ch);

while ch<>' 'do

begin

read(f,ch);

write(ch);

end;

while ch<>'#' do

begin

read(f,ch);

end;

read(f,ch);

writeln;

textcolor(7);

write('Дата выпуска -');

textcolor(2);

while not eof(f)do

begin

read(f,ch);

write(ch);

end;

textcolor(7);

Close(f);

end.

Упражнение 13.39. Используя файловую систему /proc, получите информацию о процессоре (vendor_id, cpu family, model, model name, stepping, cpu MHz, cache size, fdiv_bug, hlt_bug, sep_bug, f00f_bug, coma_bug, fpu, fpu_exception, cpuid level, wp, flags, bogomips).

uses sysutils,linux;

var

    f,count:integer;

    ch:array [0..511] of byte;

begin

  f:=fdopen('/proc/cpuinfo',Open_RDONLY);

  if f=-1 then

  begin

    writeln('Невозможно открыть файл ');

    halt;

  end;

  writeln('Information about CPU');

  count:=fdread(f,ch,512);

  while count>0 do

  begin

    fdwrite(1,ch,count);

    count:=fdread(f,ch,512);

  end;

  fdClose(f);

end.

Упражнение 13.40. Используя файловую систему /proc, получите информацию об используемой памяти.

uses sysutils,linux;

var

    f,count:integer;

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

begin

  f:=fdopen('/proc/meminfo',Open_RDONLY);

  if f=-1 then

  begin

    writeln('Невозможно открыть файл для просмотра информации об используемой памяти');

    halt;

  end;

  writeln('Information about MEMORY');

  count:=fdread(f,ch,512);

  while count>0 do

  begin

    fdwrite(1,ch,count);

    count:=fdread(f,ch,512);

  end;

  fdClose(f);

end.


Содержание раздела