table of contents
- bullseye 1:4.10.0-1
- bullseye-backports 1:4.18.0-1~bpo11+1
- testing 1:4.18.0-1
- unstable 1:4.18.0-1
STAT(2) | Podręcznik programisty Linuksa | STAT(2) |
NAZWA¶
stat, fstat, lstat, fstatat - pobieranie stanu pliku
SKŁADNIA¶
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h>
int stat(const char *pathname, struct stat *statbuf); int fstat(int fd, struct stat *statbuf); int lstat(const char *pathname, struct stat *statbuf); #include <fcntl.h> /* Definicja stałych AT_* */ #include <sys/stat.h>
int fstatat(int dirfd, const char *pathname, struct stat *statbuf, int flags);
lstat():
|| /* Od glibc 2.20 */ _DEFAULT_SOURCE
|| _XOPEN_SOURCE >= 500
|| /* Od glibc 2.10: */ _POSIX_C_SOURCE >= 200112L
fstatat():
- Od glibc 2.10:
- _POSIX_C_SOURCE >= 200809L
- Przed glibc 2.10:
- _ATFILE_SOURCE
OPIS¶
Funkcje te zwracają informacje o podanym pliku w buforze wskazanym przez statbuf. Do uzyskania tej informacji nie są wymagane prawa dostępu do samego pliku, lecz — w przypadku stat, fstatat() i lstat() — konieczne są prawa wykonywania (przeszukiwania) do wszystkich katalogów na prowadzącej do pliku ścieżce pathname.
stat() i fstatat() pobierają informacje o pliku wskazanym przez pathname; cechy wyróżniające fstatat() opisano poniżej.
lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that the link refers to.
fstat() jest identyczny z stat(), z tym wyjątkiem, że plik o którym mają być pobrane informacje, jest określony przez deskryptor pliku fd.
The stat structure¶
Wszystkie te funkcje zwracają strukturę stat, zawierającą następujące pola:
struct stat {
dev_t st_dev; /* ID urządzenia zawierającego plik */
ino_t st_ino; /* numer i-węzła (inode) */
mode_t st_mode; /* tryb i typ pliku */
nlink_t st_nlink; /* liczba dowiązań stałych (hardlinks) */
uid_t st_uid; /* ID użytkownika właściciela */
gid_t st_gid; /* ID grupy właściciela */
dev_t st_rdev; /* ID urządzenia (jeśli plik specjalny) */
off_t st_size; /* całkowity rozmiar w bajtach */
blksize_t st_blksize; /* wielkość bloku dla I/O systemu plików */
blkcnt_t st_blocks; /* liczba zaalokowanych bloków 512-bajtowych */
/* Od Linuksa 2.6 jądro obsługuje nanosekundową
rozdzielczość następujących pól znaczników czasu.
Szczegóły opisujące Linuksa w wersji starszej niż 2.6
znajdują się w rozdziale UWAGI */
struct timespec st_atim; /* czas ostatniego dostępu */
struct timespec st_mtim; /* czas ostatniej modyfikacji */
struct timespec st_ctim; /* czas ostatniej zmiany */ }; #define st_atime st_atim.tv_sec /* Kompatybilność wsteczna */ #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec };
Uwaga: kolejność pól w strukturze stat różni się nieco w zależności od architektury. Dodatkowo, powyższa definicja nie pokazuje bajtów wyrównujących, które mogą być obecne pomiędzy niektórymi polami na różnych architekturach. Z tymi detalami można się zapoznać analizując glibc i kod źródłowy jądra.
Uwaga: Dla zachowania wydajności i prostoty, różne pola w strukturze stat mogą zawierać stany z różnych momentów wykonywania wywołania systemowego. Przykładowo, jeśli st_mode lub st_uid zostanie zmieniony przez inny proces za pomocą wywołania chmod(2) lub chown(2), stat() może zwrócić stary st_mode razem z nowym st_uid albo stary st_uid razem z nowym st_mode.
The fields in the stat structure are as follows:
- st_dev
- This field describes the device on which this file resides. (The major(3) and minor(3) macros may be useful to decompose the device ID in this field.)
- st_ino
- This field contains the file's inode number.
- st_mode
- This field contains the file type and mode. See inode(7) for further information.
- st_nlink
- This field contains the number of hard links to the file.
- st_uid
- This field contains the user ID of the owner of the file.
- st_gid
- This field contains the ID of the group owner of the file.
- st_rdev
- This field describes the device that this file (inode) represents.
- st_size
- This field gives the size of the file (if it is a regular file or a symbolic link) in bytes. The size of a symbolic link is the length of the pathname it contains, without a terminating null byte.
- st_blksize
- This field gives the "preferred" block size for efficient filesystem I/O.
- st_blocks
- This field indicates the number of blocks allocated to the file, in 512-byte units. (This may be smaller than st_size/512 when the file has holes.)
- st_atime
- This is the time of the last access of file data.
- st_mtime
- This is the time of last modification of file data.
- st_ctime
- This is the file's last status change timestamp (time of last change to the inode).
For further information on the above fields, see inode(7).
fstatat()¶
The fstatat() system call is a more general interface for accessing file information which can still provide exactly the behavior of each of stat(), lstat(), and fstat().
Jeśli ścieżka podana w pathname jest względna, jest to interpretowane w odniesieniu do katalogu do którego odnosi się deskryptor pliku dirfd (zamiast w odniesieniu do bieżącego katalogu roboczego procesu wywołującego, jak w stosunku do ścieżek względnych robi to stat() i lstat()).
Jeśli pathname jest względna a dirfd ma wartość specjalną AT_FDCWD, to pathname jest interpretowana w odniesieniu do bieżącego katalogu roboczego procesu wywołującego (jak stat() i lstat()).
If ścieżka pathname jest bezwzględna, to dirfd jest ignorowane.
flags mogą wynosić albo 0, albo składać się z co najmniej jednej z poniższych opcji połączonych operatorem OR:
- AT_EMPTY_PATH (od Linuksa 2.6.39)
- If pathname is an empty string, operate on the file referred to by dirfd (which may have been obtained using the open(2) O_PATH flag). In this case, dirfd can refer to any type of file, not just a directory, and the behavior of fstatat() is similar to that of fstat(). If dirfd is AT_FDCWD, the call operates on the current working directory. This flag is Linux-specific; define _GNU_SOURCE to obtain its definition.
- AT_NO_AUTOMOUNT (od Linuksa 2.6.38)
- Don't automount the terminal ("basename") component of pathname if it is a directory that is an automount point. This allows the caller to gather attributes of an automount point (rather than the location it would mount). Since Linux 4.14, also don't instantiate a nonexistent name in an on-demand directory such as used for automounter indirect maps. This flag has no effect if the mount point has already been mounted over.
- Both stat() and lstat() act as though AT_NO_AUTOMOUNT was set.
- The AT_NO_AUTOMOUNT can be used in tools that scan directories to prevent mass-automounting of a directory of automount points.
- Jest to opcja charakterystyczna dla Linuksa, proszę zdefiniować _GNU_SOURCE, aby dostać się do jej definicji.
- AT_SYMLINK_NOFOLLOW
- Jeśli pathname jest dowiązaniem symbolicznym nie podąża za nim, w zamian zwraca informacje o samym dowiązaniu, jak lstat(). Domyślnie fstatat () podąża za dowiązaniami symbolicznymi, jak stat().)
Więcej informacji o potrzebie wprowadzenia fstatat() można znaleźć w podręczniku openat(2).
WARTOŚĆ ZWRACANA¶
Po pomyślnym zakończeniu zwracane jest zero. Po błędzie zwracane jest -1 i odpowiednio ustawiane jest errno.
BŁĘDY¶
- EACCES
- Brak uprawnień do przeszukiwania jednego z katalogów w ścieżce zaczynającej pathname. (Patrz także path_resolution(7)).
- EBADF
- fd nie jest prawidłowym otwartym deskryptorem pliku.
- EFAULT
- Niepoprawny adres.
- ELOOP
- Podczas rozwiązywania ścieżki napotkano zbyt wiele dowiązań symbolicznych.
- ENAMETOOLONG
- Ścieżka pathname jest zbyt długa.
- ENOENT
- A component of pathname does not exist or is a dangling symbolic link.
- ENOENT
- pathname is an empty string and AT_EMPTY_PATH was not specified in flags.
- ENOMEM
- Brak pamięci (tj. pamięci jądra).
- ENOTDIR
- Składnik ścieżki pathname nie jest katalogiem.
- EOVERFLOW
- pathname lub fd odnosi się do pliku, numeru i-węzła lub numeru bloków, których rozmiar nie jest reprezentowalny w - odpowiednio - typie off_t, ino_t, blkcnt_t. Błąd ten może wystąpić na przykład wtedy, gdy aplikacja skompilowana na platformie 32-bitowej bez -D_FILE_OFFSET_BITS=64 wywoła stat () na pliku, którego rozmiar jest większy niż (1<<31)-1 bajtów.
Mogą wystąpić następujące dodatkowe błędy dla fstatat():
WERSJE¶
fstatat() zostało dodane do Linuksa w jądrze 2.6.16; obsługę biblioteki dodano do glibc w wersji 2.4.
ZGODNE Z¶
stat(), fstat(), lstat(): SVr4, 4.3BSD, POSIX.1-2001, POSIX.1.2008.
fstatat(): POSIX.1-2008.
Według POSIX.1-2001 lstat() na dowiązaniu symbolicznym powinien zwrócić poprawne wartości tylko w polu st_size i w części pola st_mode związanej z typem pliku struktury stat. POSIX.1-2008 zaostrza tę specyfikację, wymagając od lstat() zwracania poprawnych informacji we wszystkich polach z wyjątkiem bitów trybu w st_mode.
Używanie pól st_blocks i st_blksize może być nieprzenośne. (Były wprowadzone w BSD; interpretacje różnią się zarówno między systemami, jak i na jednym systemie, jeśli użyty jest zdalny system plików montowany po NFS-ie).
UWAGI¶
Pola znaczników czasu¶
Starsze jądra i starsze standardy nie obsługują nanosekundowych pól znaczników czasu. Zamiast tego były trzy pola znaczników czasu — st_atime, st_mtime i st_ctime— zapisywane jako time_t przechowujące znaczniki czasu z sekundową precyzją.
Since kernel 2.5.48, the stat structure supports nanosecond resolution for the three file timestamp fields. The nanosecond components of each timestamp are available via names of the form st_atim.tv_nsec, if suitable feature test macros are defined. Nanosecond timestamps were standardized in POSIX.1-2008, and, starting with version 2.12, glibc exposes the nanosecond component names if _POSIX_C_SOURCE is defined with the value 200809L or greater, or _XOPEN_SOURCE is defined with the value 700 or greater. Up to and including glibc 2.19, the definitions of the nanoseconds components are also defined if _BSD_SOURCE or _SVID_SOURCE is defined. If none of the aforementioned macros are defined, then the nanosecond values are exposed with names of the form st_atimensec.
Różnice biblioteki C/jądra¶
Z upływem czasu, zwiększanie rozmiarów struktury stat doprowadziło do powstania trzech kolejnych wersji funkcji stat(): sys_stat() (slot __NR_oldstat), sys_newstat() (slot __NR_stat) i sys_stat64() (slot __NR_stat64) na platformach 32-bitowych takich jak i386. Pierwsze dwie wersje były już obecne w Linuksie 1.0 (choć z różnymi nazwami), ostatnią dodano w Linuksie 2.4. Podobne uwagi mają zastosowanie do fstat() i lstat().
Wewnątrzjądrowe wersje struktury stat, za pomocą których jądro obsługuje te różne wersje, to odpowiednio:
- __old_kernel_stat
- Oryginalna struktura z dość wąskimi polami i brakiem dopełnienia (wyrównania).
- stat
- Większe pole st_ino i dodane dopełnienie do różnych części struktury pozwalające na późniejszą rozbudowę.
- stat64
- Jeszcze większe pole st_ino, większe pola st_uid i st_gid aby przyjąć rozszerzone w Linuksie 2.4 UID-y i GID-y do 32 bitów i różne inne poszerzenia pól oraz jeszcze więcej dopełnień w strukturze (dopełnione bajty zostały w końcu wykorzystane w Linuksie 2.6 po pojawieniu się 32-bitowych identyfikatorów urządzeń oraz części nanosekundowej w polach znaczników czasowych).
Funkcja opakowująca glibc stat() ukrywa te detale przed użytkownikami, wywołując najnowszą wersję wywołania systemowego udostępnianą przez jądra i przepakowując zwracane informacje, jeśli jest to wymagane, dla starszych plików wykonywalnych.
Na współczesnych systemach 64-bitowych wszystko jest prostsze: istnieje jedno wywołanie systemowe stat(), a jądro wykorzystuje strukturę stat zawierającą pola o wystarczającym rozmiarze.
Wywołanie systemowe niższego stopnia używane przez funkcję opakowującą fstatat() glibc nazywa się w rzeczywistości fstatat64() lub, na niektórych architekturach, newfstatat().
PRZYKŁADY¶
Poniższy program wywołuje lstat() i wypisuje wybrane pola zwrócone w strukturze stat:
#include <sys/types.h> #include <sys/stat.h> #include <stdint.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <sys/sysmacros.h> int main(int argc, char *argv[]) {
struct stat sb;
if (argc != 2) {
fprintf(stderr, "Użycie: %s <ścieżka>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (lstat(argv[1], &sb) == -1) {
perror("lstat");
exit(EXIT_FAILURE);
}
printf("ID of containing device: [%jx,%jx]\n",
(uintmax_t) major(sb.st_dev),
(uintmax_t) minor(sb.st_dev));
printf("Typ pliku: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("urządzenie blokowe\n"); break;
case S_IFCHR: printf("urządzenie znakowe\n"); break;
case S_IFDIR: printf("katalog\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("dowiązanie symboliczne\n"); break;
case S_IFREG: printf("zwykły plik\n"); break;
case S_IFSOCK: printf("gniazdo\n"); break;
default: printf("typ nieznany\n"); break;
}
printf("numer I-węzła: %ju\n", (uintmax_t) sb.st_ino);
printf("Tryb: %jo (octal)\n",
(uintmax_t) sb.st_mode);
printf("Liczba dowi◈za◈: %ju\n", (uintmax_t) sb.st_nlink);
printf("W◈a◈ciciel: UID=%ju GID=%ju\n",
(uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid);
printf("Preferowany rozmiar bloku I/O: %jd bajtów\n",
(intmax_t) sb.st_blksize);
printf("Rozmiar bloku: %jd bajtów\n",
(intmax_t) sb.st_size);
printf("Liczba zaalokowanych bloków: %jd\n",
(intmax_t) sb.st_blocks);
printf("Ostatnia zmiana stanu: %s", ctime(&sb.st_ctime));
printf("Ostatni dostęp do pliku: %s", ctime(&sb.st_atime));
printf("Ostatnia zmiana pliku: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS); }
ZOBACZ TAKŻE¶
ls(1), stat(1), access(2), chmod(2), chown(2), readlink(2), statx(2), utime(2), capabilities(7), inode(7), symlink(7)
O STRONIE¶
Angielska wersja tej strony pochodzi z wydania 5.10 projektu Linux man-pages. Opis projektu, informacje dotyczące zgłaszania błędów oraz najnowszą wersję oryginału można znaleźć pod adresem https://www.kernel.org/doc/man-pages/.
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Przemek Borys <pborys@dione.ids.pl>, Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.
13 sierpnia 2020 r. | Linux |