Kniga-Online.club
» » » » Linux программирование в примерах - Роббинс Арнольд

Linux программирование в примерах - Роббинс Арнольд

Читать бесплатно Linux программирование в примерах - Роббинс Арнольд. Жанр: Интернет год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Строки 81–85 обрабатывают случай «успеха», при котором размер содержимого ссылки меньше размера буфера. В этом случае добавляется завершающий ноль (строка 83), а затем буфер возвращается, прерывая бесконечный цикл. Это гарантирует, что в буфер помещено все содержимое ссылки, поскольку у readlink() нет возможности сообщить о «недостаточном размере буфера».

Строки 87–88 освобождают буфер и удваивают размер буфера для следующей попытки в начале цикла. Строки 89–90 обрабатывают случай, при котором размер ссылки слишком велик: buf_size больше, чем SSIZE_MAX, или SSIZE_MAX больше, чем значение, которое может быть представлено в знаковом целом того же размера, который использовался для хранения SIZE_MAX, и buf_size обернулся в ноль. (Это маловероятные условия, но странные вещи все же случаются.) Если одно из этих условий верно, программа завершается с сообщением об ошибке. В противном случае функция возвращается в начало цикла, чтобы сделать еще одну попытку выделить буфер и прочесть ссылку.

Некоторое дополнительное разъяснение: условие 'SIZE_MAX / 2 < SSIZE_MAX' верно лишь на системах, в которых 'SIZE_MAX < 2 * SSIZE_MAX'; мы не знаем таких, но лишь на таких системах buf_size может обернуться в ноль. Поскольку на практике это условие не может быть истинным, компилятор может оптимизировать все выражение, включив следующую проверку 'buf_size == 0'. После прочтения этого кода вы можете спросить: «Почему не использовать lstat() для получения размера символической ссылки, не выделить буфер нужного размера с помощью malloc(), и все?» На это есть несколько причин.[61]

• lstat() является системным вызовом — лучше избежать накладных расходов по его вызову, поскольку содержимое большинства символических ссылок поместится в первоначальный размер буфера в 128.

• Вызов lstat() создает условие состязания: ссылка может измениться между исполнением lstat() и readlink(), в любом случае вынуждая повторение.

• Некоторые системы не заполняют должным образом член st_size для символической ссылки. (Печально, но верно.) Сходным образом, как мы увидим в разделе 8.4.2 «Получение текущего каталога: getcwd()», Linux в /proc предоставляет специальные символические ссылки, у которых st_size равен нулю, но для которых readlink() возвращает действительное содержимое.

Наконец, буфер не слишком большой, xreadlink() использует free() и malloc() с большим размером вместо realloc(), чтобы избежать бесполезного копирования, которое делает realloc(). (Поэтому комментарий в строке 58 устарел, поскольку realloc() не используется; это исправлено в версии Coreutils после 5.0.)

5.5. Смена владельца, прав доступа и времени изменения

Несколько других системных вызовов дают вам возможность изменять другие относящиеся к файлу сведения: в частности, владельца и группу файла, права доступа к файлу и времена доступа и изменения файла.

5.5.1. Смена владельца файла: chown(), fchown() и lchown()

Владелец и группа файла изменяются с помощью трех сходных системных вызовов.

#include <sys/types.h> /* POSIX */

#include <unistd.h>

int chown(const char *path, uid_t owner, gid_t group);

int fchown(int fd, uid_t owner, gid_t group);

int lchown(const char *path, uid_t owner, gid_t group);

chown() работает с аргументом имени файла, fchown() работает с открытым файлом, а lchown() работает с символической ссылкой вместо файла, на который эта ссылка указывает. Во всех других отношениях эти три вызова работают идентично, возвращая 0 в случае успеха и -1 при ошибке.

Стоит заметить, что один системный вызов изменяет как владельца, так и группу файла. Чтобы изменить лишь владельца или лишь группу, передайте (-1) в качестве того идентификационного номера, который должен остаться без изменений.

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

Вы могли бы поинтересоваться: «Зачем нужно изменять владельца символической ссылки? Права доступа и владение ей не имеют значения». Но что случится, если пользователь уходит, а все его файлы все еще нужны? Необходима возможность изменения владельца всех файлов этого лица на кого-то еще, включая символические ссылки.

Системы GNU/Linux обычно не позволяют рядовым пользователям (не root) изменять владельца («отдавать») своих файлов. Смена группы на одну из групп пользователя, конечно, разрешена. Ограничение в смене владельцев идет от BSD систем, у которых тоже есть этот запрет. Главная причина в том, что разрешение пользователям отдавать файлы может нарушить дисковый учет. Рассмотрите такой сценарий:

$ <b>mkdir mywork</b> /* Создать каталог */

$ <b>chmod go-rwx mywork</b> /* Установить права доступа drwx------ */

$ <b>cd mywork</b> /* Перейти в него */

$ <b>myprogram &gt; large_data_file</b> /* Создать большой файл */

$ <b>chmod ugo+rw large_data_file</b> /* Установить доступ -rw-rw-rw- */

$ <b>chown otherguy large_data_file</b> /* Передать файл otherguy */

В этом примере large_data_file теперь принадлежит пользователю otherguy. Первоначальный пользователь может продолжать читать и записывать файл из-за его прав доступа. Но дисковое пространство, которое он занимает, будет записано на счет otherguy. Однако, поскольку он находится в каталоге, который принадлежит первому пользователю и к которому otherguy не может получить доступ, otherguy не имеет возможности удалить файл.

Перейти на страницу:

Роббинс Арнольд читать все книги автора по порядку

Роббинс Арнольд - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Linux программирование в примерах отзывы

Отзывы читателей о книге Linux программирование в примерах, автор: Роббинс Арнольд. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*