параметр установлен в F_SETSIG, а последний — в сигнал, который должен использоваться вместо SIGIO.

Использование F_SETSIG дает один значительный эффект. По умолчанию siginfo_t не передается обработчику при доставке SIGIO. Если используется F_SETSIG, даже когда сигналом, передаваемым в ядро, является SIGIO, a SA_SIGINFO был установлен при регистрации обработчика сигнала, файловый дескриптор, аренда которого инициировала событие, передается в обработчик сигналов одновременно с элементом siginfo_t по имени si_fd. Это позволяет применять отдельный сигнал к аренде множества файлов, в то время как si_fd сообщает сигналу, какому файлу необходимо уделить внимание[96].

Единственные два системных вызова, которые могут инициировать передачу сигнала для арендуемого файла — это open() и truncate(). Когда они вызываются процессом для арендуемого файла, они блокируются[97], и процессу- владельцу передается сигнал, open() или truncate() завершаются после удаления аренды с файла (или его закрытия процессом-владельцем, что вызывает удаление аренды). Если процесс, удерживающий аренду, не отменяет снятие в течение времени, указанного в файле /proc/sys/fs/lease-break-time, ядро прерывает аренду и позволяет завершиться запускающему системному вызову.

Ниже приведен пример применения владений файлами для уведомления о намерении другого процесса получить доступ к файлу. Список файлов берется командной строки, и на каждый файл помещается аренда записи. Когда другой процесс намеревается получить доступ к файлу (даже для чтения, поскольку использовалась блокировка записи), программа освобождает блокировку файла, позволяя другому процессу продолжать работу. Она также выводит сообщение о том, какой именно файл был освобожден.

 1: /* leases.с */

 2:

 3: #define GNU_SOURCE

 4:

 5: #include <fcntl.h>

 6: #include <signal.h>

 7: #include <stdio.h>

 8: #include <string.h>

 9: #include <unistd.h>

10:

11: const char ** fileNames;

12: int numFiles;

13:

14: void handler (int sig, siginfo_t * siginfo, void * context) {

15:  /* Когда аренда истекает, вывести сообщение и закрыть файл.

16:     Предполагается, что первый открываемый файл получит файловый

17:     дескриптор 3, следующий - 4 и так далее. */

18:

19:  write(1, 'освобождение', 10);

20:  write(1, fileNames[siginfo->si_fd - 3],

21:  strlen(fileNames[siginfo->si_fd - 3]));

22:  write(1, ' ', 1);

23:  fcntl(siginfo->si_fd, F_SETLEASE, F_UNLCK);

24:  close(siginfo->si_fd);

25:  numFiles--;

26: }

27:

28: int main(int argc, const char ** argv) {

29:  int fd;

30:  const char ** file;

31:  struct sigaction act;

32:

33:  if (argc < 2) {

34:   fprintf(stderr, 'использование: %s <filename>+ ', argv[0]);

35:   return 1;

36:  }

37:

38:  /* Зарегистрировать обработчик сигналов. Указав SA_SIGINFO, предоставить

39:     обработчику возможность узнать, какой файловый дескриптор имеет

40:     истекшую аренду. */

41:  act.sa_sigaction = handler;

42:  act.sa_flags = SA_SIGINFO;

43:  sigemptyset(&act.sa_mask);

44:  sigaction(SIGRTMIN, &act, NULL);

45:

46:  /* Сохранить список имен файлов в глобальной переменной, чтобы

47:     обработчик сигналов мог иметь доступ к нему. */

48:  fileNames = argv + 1;

49:  numFiles = argc - 1;

50:

51:  /* Открыть файлы, установить используемые сигнал

52:     и создать аренду */

53:  for (file = fileNames; *file; file++) {

54:   if ((fd = open(* file, O_RDONLY)) < 0) {

55:    perror('open');

56:    return 1;

57:   }

58:

59:   /* Для правильного заполнения необходимо использовать F_SETSIG

60:      для структуры siginfo */

61:   if (fcntl(fd, F_SETSIG, SIGRTMIN) < 0) {

62:    perror('F_SETSIG');

63:    return 1;

64:   }

65:

66:   if (fcntl(fd, F_SETLEASE, F_WRLCK) < 0) {

67:    perror('F_SETLEASE');

68:    return 1;

69:   }

70:  }

71:

72:  /* Пока файлы остаются открытыми, ожидать поступления сигналов. */

73:  while (numFiles)

74:   pause();

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату