$ <b>echo hello, world > myfile</b> /* Создать файл */$ <b>ls -l myfile</b> /* Отобразить права доступа */-rw-r--r-- 1 arnold devel 13 Apr 3 17:11 myfile$ <b>chmod g+s myfile</b> /* Добавить бит setgid */$ <b>ls -l myfile</b> /* Показать новые права доступа */-rw-r-Sr-- 1 arnold devel 13 Apr 3 17:11 myfileБит права на исполнение группой должен быть оставлен сброшенным.
SsКомбинация установленного бита setgid и сброшенного бита права на исполнение группой обычно бессмысленно. По этой причине, она была выбрана разработчиками System V для обозначения «использования обязательного блокирования». И в самом деле, добавления этого бита достаточно, чтобы заставить коммерческую систему Unix, такую как Solaris, использовать блокировку файлов.
На системах GNU/Linux несколько другая история. Для обязательных блокировок файл должен иметь установленный бит setgid, но этого одного недостаточно. Файловая система, содержащая файл, также должна быть смонтирована с опцией
mandmountМы уже рассмотрели файловые системы, разделы диска, монтирование и команду mount, главным образом, в разделе 8.1 «Монтирование и демонтирование файловых систем». Мы можем продемонстрировать обязательную блокировку с помощью небольшой программы и файловой системой для тестирования на гибком диске. Для начала, вот программа:
1 /* ch14-lockall.c --- Демонстрация обязательной блокировки. */23 #include <stdio.h> /* для fprintf(), stderr, BUFSIZ */4 #include <errno.h> /* объявление errno */5 #include <fcntl.h> /* для флагов open() */6 #include <string.h> /* объявление strerror() */7 #include <unistd.h> /* для ssize_t */8 #include <sys/types.h>9 #include <sys/stat.h> /* для mode_t */1011 int12 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;1920 if (argc != 2) {21 fprintf(stderr, "usage: %s file\n", argv[0]);22 exit(1);23 }2425 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 }3334 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 }4041 rw_mode |= S_ISGID; /* добавить бит обязательной блокировки */4243 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 }4950 /* заблокировать файл */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; /* блокировка записи */5657 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 }6364 pause();6566 (void)close(fd);6768 return 0;69 }Программа устанавливает права доступа и создает файл, указанный в командной строке (строки 25 и 26). Затем она записывает в файл некоторые данные (строка 34). Строка 41 добавляет к правам доступа бит setgid, а строка 43 изменяет их. (Системный вызов
fchmod()chmod()fchmod()Строки 51–55 устанавливают
struct flockpause()