stat(2)

NAZWA
stat, fstat, lstat, fstatat - pobiera stan pliku

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

SKŁADNIA
#include <sys/stat.h>

int stat(const char *restrict path,
         struct stat *restrict statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *restrict path,
         struct stat *restrict statbuf);

#include <fcntl.h>           /* Definicja stałych AT_* */
#include <sys/stat.h>

int fstatat(int dirfd, const char *restrict path,
         struct stat *restrict statbuf, int flags);

    Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

lstat():
    /* Od glibc 2.20 */ _DEFAULT_SOURCE
        || _XOPEN_SOURCE >= 500
        || /* Od glibc 2.10: */ _POSIX_C_SOURCE >= 200112L
        || /* glibc 2.19 i wcześniejsze */ _BSD_SOURCE

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 path.

stat() i fstatat() pobierają informacje o pliku wskazanym przez path; cechy wyróżniające fstatat() opisano poniżej.

lstat() jest identyczny z stat(), lecz w przypadku gdy path jest dowiązaniem symbolicznym, to zwraca informacje o samym dowiązaniu, a nie pliku, do którego się to dowiązanie odwołuje.

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.

  Struktura stat
Wszystkie te funkcje zwracają strukturę stat (zob. stat(3type)).

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.

  fstatat()
Wywołanie systemowe fstatat() jest ogólniejszym interfejsem do uzyskiwania dostępu do informacji o pliku, które może wciąż zapewnić zachowanie identyczne do każdego z wywołań stat(), lstat() i fstat().

Jeśli ścieżka path 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 path jest względna a dirfd ma wartość specjalną AT_FDCWD, to path jest interpretowana w odniesieniu do bieżącego katalogu roboczego procesu wywołującego (jak stat() i lstat()).

Jeśli ścieżka path jest bezwzględna, to dirfd jest ignorowane.

flags mogą wynosić albo 0, albo składać się z co najmniej jednego z poniższych znaczników zsumowanych bitowo (OR):

AT_EMPTY_PATH (od Linuksa 2.6.39)
    Jeśli path jest łańcuchem pustym (lub NULL, od Linuksa 6.11), to działa na pliku do którego odnosi się dirfd (który mógł zostać pozyskany za pomocą znacznika O_PATH open(2)). W takim przypadku dirfd może odnosić się do każdego typu pliku, nie tylko katalogu, a zachowanie fstatat() jest podobne do fstat(). Jeśli dirfd wynosi AT_FDCWD, to wywołanie działa w bieżącym katalogu roboczym. Jest to opcja charakterystyczna dla Linuksa, proszę zdefiniować _GNU_SOURCE, aby dostać się do jej definicji.

AT_NO_AUTOMOUNT (od Linuksa 2.6.38)
    Nie dokonuje automatycznego montowania składowej terminala („basename”) ścieżki z path. Od Linuksa 3.1 znacznik ten jest ignorowany. Od Linuksa 4.11 znacznik ten jest implikowany.

AT_SYMLINK_NOFOLLOW
    Jeśli path jest dowiązaniem symbolicznym, nie podąża za nim, w zamian zwracając 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 ustawiane errno, wskazując błąd.

BŁĘDY

EACCES
    Brak uprawnień do przeszukiwania jednego z katalogów w ścieżce zaczynającej path (zob. też path_resolution(7)).

EBADF
    fd nie jest prawidłowym otwartym deskryptorem pliku.

EBADF
    (fstatat()) path jest względna, lecz dirfd nie wynosi ani AT_FDCWD, ani nie jest prawidłowym deskryptorem pliku.

EFAULT
    Niepoprawny adres.

EINVAL
    (fstatat()) Podano nieprawidłową opcję we flags.

ELOOP
    Podczas rozwiązywania ścieżki napotkano zbyt wiele dowiązań symbolicznych.

ENAMETOOLONG
    path jest zbyt długie.

ENOENT
    Składowa path nie istnieje lub jest wiszącym dowiązaniem symbolicznym.

ENOENT
    path jest łańcuchem pustym, a we flags nie podano AT_EMPTY_PATH.

ENOMEM
    Brak pamięci (tj. pamięci jądra).

ENOTDIR
    Składowa ścieżki path nie jest katalogiem.

ENOTDIR
    (fstatat()) path jest względna, a dirfd jest deskryptorem pliku odnoszącym się do pliku, zamiast do katalogu.

EOVERFLOW
    path 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.

STANDARDY
POSIX.1-2024.

HISTORIA

stat()
fstat()
lstat()
    SVr4, 4.3BSD, POSIX.1-2001.

fstatat()
    POSIX.1-2008. Linux 2.6.16, glibc 2.4.

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).

  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 <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <sys/sysmacros.h>
    #include <time.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 urządzenia:  [%x,%x]\n",
               major(sb.st_dev),
               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/potok\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 (ósemkowo)\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 przydzielonych 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), stat(3type), capabilities(7), inode(7), symlink(7)

TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: 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 (https://www.gnu.org/licenses/gpl-3.0.html) 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.