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

       

Второй пример: процедура find_entry


Процедура find_entry будет искать в каталоге следующий файл (или подкаталог), заканчивающийся определенным суффиксом. Она имеет три параметра: имя каталога, в котором будет выполняться поиск, строка суффикса и флаг, определяющий, нужно ли продолжать дальнейший поиск после того, как искомый элемент будет найден.

Процедура find_entry использует процедуру проверки совпадения строк match с целью определения, заканчивается ли файл заданным суффиксом. Процедура match, в свою очередь, вызывает две процедуры из стандартной библиотеки C системы UNIX: функцию strlen, возвращающую длину строки в символах, и функцию strcmp, которая сравнивает две строки, возвращая нулевое значение в случае их совпадения.

uses linux,strings;

function match(s1, s2: pchar):boolean;forward;

function find_entry(dirname:pchar;suffix:pchar;cont:integer):pchar;

const

  dp:pdir=nil;

var

  d:pdirent;

begin

  if (dp = nil) or (cont = 0) then

  begin

    if dp <> nil then



      closedir (dp);

    dp:=opendir(dirname);

    if dp = nil then

    begin

      find_entry:=nil;

      exit;

    end;

  end;

  d := readdir (dp);

  while d <> nil do

  begin

    if d^.ino = 0 then

      continue;

    if match (d^.name, suffix) then

    begin

      find_entry:=d^.name;

      exit;

    end;

    d := readdir (dp);

  end;

  closedir (dp);

  dp := nil;

  find_entry:=nil;

end;

 

function match(s1, s2: pchar):boolean;

var

  diff:integer;

begin

  diff := strlen (s1) - strlen (s2);

  if strlen (s1) > strlen (s2) then

    match:=(strcomp (@s1[diff], s2) = 0)

  else

    match:=false;

end;

Упражнение 4.1. Измените функцию my_double_ls из предыдущего примера так, чтобы она имела второй параметр – целочисленную переменную skip. Если значение skip равно нулю, то функция my_double_ls должна выполняться так же, как и раньше. Если значение переменной skip равно 1, функция my_double_ls должна пропускать все имена файлов, которые начинаются сточки (.).




Упражнение 4.2. В предыдущей главе мы познакомились с использованием системного вызова fstat для получения информации о файле. Структура tstat, возвращаемая вызовом fstat, содержит поле mode, режим доступа к файлу. Режим доступа к файлу образуется при помощи выполнения побитовой операции ИЛИ значения кода доступа с константами, определяющими, является ли этот файл обычным файлом, каталогом, специальным файлом, или механизмом межпроцессного взаимодействия, таким как именованный канал. Наилучший способ проверить, является ли файл каталогом – использовать макрос S_ISDIR:

(* Переменная buf получена в результате вызова fstat *)

if S_ISDIR(buf.mode) then

  writeln('Это каталог')

else

  writeln('Это не каталог');

Измените процедуру my_double_ls так, чтобы она вызывала fstat для каждого найденного файла и выводила звездочку после каждого имени каталога.

В дополнение к упражнению приведем пример, демонстрирующий остальные S_-функции:

Uses linux;

Var Info : Stat;

begin

  if LStat (paramstr(1),info) then

    begin

    if S_ISLNK(info.mode) then

      Writeln ('File is a link');

    if S_ISREG(info.mode) then

      Writeln ('File is a regular file');

    if S_ISDIR(info.mode) then

      Writeln ('File is a directory');

    if S_ISCHR(info.mode) then

      Writeln ('File is a character device file');

    if S_ISBLK(info.mode) then

      Writeln ('File is a block device file');

    if S_ISFIFO(info.mode) then

      Writeln ('File is a named pipe (FIFO)');

    if S_ISSOCK(info.mode) then

      Writeln ('File is a socket');

    end;

end.


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