ЗАМЕЧАНИЕ. Справочная страница GNU/Linux flock()
не работают для смонтированных удаленных файлов. Блокировки fcntl()
работают, при условии, что у вас достаточно новая версия Linux и сервер NFS поддерживает блокировки файлов
14.2.4. Обязательная блокировка
Большинство коммерческих систем Unix поддерживают в дополнение к вспомогательной обязательную блокировку файлов. Обязательная блокировка работает лишь с fcntl()
. Обязательная блокировка файла контролируется установками прав доступа файла, в частности, путем добавления к файлу бита setgid с помощью команды chmod
.
$ echo hello, world > myfile /* Создать файл */
$ ls -l myfile /* Отобразить права доступа */
-rw-r--r-- 1 arnold devel 13 Apr 3 17:11 myfile
$ chmod g+s myfile /* Добавить бит setgid */
$ ls -l myfile /* Показать новые права доступа */
-rw-r-Sr-- 1 arnold devel 13 Apr 3 17:11 myfile
Бит права на исполнение группой должен быть оставлен сброшенным. S
показывает, что бит setgid установлен, но что бит права на исполнение — нет; если бы были установлены оба бита, была бы использована строчная буква s
.
Комбинация установленного бита setgid и сброшенного бита права на исполнение группой обычно бессмысленно. По этой причине, она была выбрана разработчиками System V для обозначения «использования обязательного блокирования». И в самом деле, добавления этого бита достаточно, чтобы заставить коммерческую систему Unix, такую как Solaris, использовать блокировку файлов.
На системах GNU/Linux несколько другая история. Для обязательных блокировок файл должен иметь установленный бит setgid, но этого одного недостаточно. Файловая система, содержащая файл, также должна быть смонтирована с опцией mand
в команде mount
.
Мы уже рассмотрели файловые системы, разделы диска, монтирование и команду mount, главным образом, в разделе 8.1 «Монтирование и демонтирование файловых систем». Мы можем продемонстрировать обязательную блокировку с помощью небольшой программы и файловой системой для тестирования на гибком диске. Для начала, вот программа:
1 /* ch14-lockall.c --- Демонстрация обязательной блокировки. */
2
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10
11 int
12 main(int argc, char **argv)
13 {
14 int fd;
15 int i, j;
16 mode_t rw_mode;
17 static char message[] = "hello, world\n";
18 struct flock lock;
19
20 if (argc != 2) {
21 fprintf(stderr, "usage: %s file\n", argv[0]);
22 exit(1);
23 }
24
25 rw_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; / * 0644 */
26 fd = open(argv[1], O_RDWR|O_TRUNC|O_CREAT|O_EXCL, rw_mode);
27 if (fd < 0) {
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",