Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
1080 /* init_groupset --- инициализация набора групп */10811082 static void1083 init_groupset()1084 {1085 #if defined(HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 01086 #ifdef GETGROUPS_NOT_STANDARD1087 /* Для систем, которые не отвечают стандарту, используйте старый способ */1088 ngroups = NGROUPS_MAX;1089 #else1090 /*1091 * Если оба аргумента при вызове равны 0, возвращаемое1092 * значение является общим числом групп.1093 */1094 ngroups = getgroups(0, NULL);1095 #endif1096 if (ngroups == -1)1097 fatal(_("could not find groups: %s"), strerror(errno));1098 else if (ngroups == 0)1099 return;11001101 /* заполнить группы */1102 emalloc(groupset, GETGROUPS_T*, ngroups * sizeof(GETGROUPS_T), "init_groupset");11031104 ngroups = getgroups(ngroups, groupset);1105 if (ngroups == -1)1106 fatal(_("could not find groups: %s"), strerror(errno));1107 #endif1108 }Переменные
ngroupsgroupsetGETGROUPS_Tgid_tintСтроки 1085 и 1107 заключают в скобки все тело функции; на древних системах, в которых вообще нет наборов групп, тело функции пустое.
Строки 1086–1088 обрабатывают не-POSIX системы; до компиляции программы механизмом конфигурации определяется
GETGROUPS_NOT_STANDARDNGROUPS_MAXСтроки 1089–1094 для систем POSIX, причем нулевой параметр
sizeСтроки 1096–1099 осуществляют проверку ошибок. Если возвращаемое значение 0, дополнительных групп нет, поэтому
init_groupset()Наконец, строка 1102 для выделения массива достаточного размера использует
malloc()11.3. Проверка для действительного пользователя:
access()В большинстве случаев значения эффективного и действительного UID и GID являются одними и теми же. Таким образом, не имеет значения, что проверка прав доступа к файлу осуществляется по эффективному ID, а не по действительному.
Однако, при написании приложения с setuid или setgid вы можете иногда захотеть проверить, является ли операция, разрешенная для эффективных UID и GID, также разрешенной для действительных UID и GID. В этом заключается задача функции
access()#include <unistd.h> /* POSIX */int access(const char *path, int amode);Аргумент
pathamodeR_OK W_OK X_OK F_OK Проверяется каждый компонент в имени пути, а на некоторых реализациях при проверке для
root access()X_OKЕсли
pathaccess()Возвращаемое значение равно 0, если операция для действительных UID и GID разрешена, и -1 в противном случае. Соответственно, если
access()if (access("/some/special/file", R_OK|W_OK) < 0) { fprintf(stderr, "Sorry: /some/special/file: %sn", strerror(errno)); exit(1);}По крайней мере для серии ядра Linux 2.4, когда тест X_OK применяется к файловой системе, смонтированной с опцией
noexecЗАМЕЧАНИЕ. Хотя использование
access()access()open()stat()fstat()access()open()Например, программа
pathchkaccess()pathchk.c