Бит права на исполнение группой должен быть оставлен сброшенным.
S
показывает, что бит setgid установлен, но что бит права на исполнение — нет; если бы были установлены оба бита, была бы использована строчная буква
s
.
Комбинация установленного бита setgid и сброшенного бита права на исполнение группой обычно бессмысленно. По этой причине, она была выбрана разработчиками System V для обозначения «использования обязательного блокирования». И в самом деле, добавления этого бита достаточно, чтобы заставить коммерческую систему Unix, такую как Solaris, использовать блокировку файлов.
На системах GNU/Linux несколько другая история. Для обязательных блокировок файл должен иметь установленный бит setgid, но этого одного недостаточно. Файловая система, содержащая файл, также должна быть смонтирована с опцией
mand
в команде
mount
.
Мы уже рассмотрели файловые системы, разделы диска, монтирование и команду mount, главным образом, в разделе 8.1 «Монтирование и демонтирование файловых систем». Мы можем продемонстрировать обязательную блокировку с помощью небольшой программы и файловой системой для тестирования на гибком диске. Для начала, вот программа:
28 fprintf(stderr, "%s: %s: cannot open for read/write: %s\n",
29 argv[0], argv[1], strerror(errno));
30 (void)close(fd);
31 return 1;
32 }
33
34 if (write(fd, message, strlen(message)) != strlen(message)) {
35 fprintf(stderr, "%s: %s: cannot write: %s\n",
36 argv[0], argv[1], strerror(errno));
37 (void)close(fd);
38 return 1;
39 }
40
41 rw_mode |= S_ISGID; /*
добавить бит обязательной блокировки */
42
43 if (fchmod(fd, rw_mode) < 0) {
44 fprintf(stderr, "%s: %s: cannot change mode to %o: %s\n",
45 argv[0], argv[1], rw_mode, strerror(errno));
46 (void)close(fd);
47 return 1;
48 }
49
50 /* заблокировать файл */
51 memset(&lock, '\0', sizeof(lock));
52 lock.l_whence = SEEK_SET;
53 lock.l_start = 0;
54 lock.l_len =0; /* блокировка всего файла */
55 lock.l_type = F_WRLCK; /* блокировка записи */
56
57 if (fcntl(fd, F_SETLK, &lock) < 0) {
58 fprintf(stderr, "%s: %s: cannot lock the file: %s\n",
59 argv[0], argv[1], strerror(errno));
60 (void)close(fd);
61 return 1;
62 }
63
64 pause;
65
66 (void)close(fd);
67
68 return 0;
69 }
Программа устанавливает права доступа и создает файл, указанный в командной строке (строки 25 и 26). Затем она записывает в файл некоторые данные (строка 34). Строка 41 добавляет к правам доступа бит setgid, а строка 43 изменяет их. (Системный вызов
fchmod
обсуждался в разделе 5.5.2 «Изменение прав доступа:
chmod
и
fchmod
».)
Строки 51–55 устанавливают
struct flock
для блокировки всего файла, а затем блокировка осуществляется реально в строке 57. Выполнив блокировку, программа засыпает, используя системный вызов
pause
(см. раздел 10.7 «Сигналы для межпроцессного взаимодействия»). После этого программа закрывает дескриптор файла и завершается. Вот расшифровка с комментариями, демонстрирующая использование обязательной блокировки файлов: