stat(2)

NAZWA
stat, fstat, lstat, fstatat - pobieranie stanu pliku

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

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

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

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

int fstatat(int dirfd, const char *restrict pathname,
         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 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
All of these system calls return a stat structure (see 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()
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. Since Linux 3.1 this flag is ignored. Since Linux 4.11 this flag is implied.

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 ustawiane jest errno wskazując błąd.

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.

EBADF
    (fstatat()) pathname is relative but dirfd is neither AT_FDCWD nor a valid file descriptor.

EFAULT
    Niepoprawny adres.

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

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.

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

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.

STANDARDY
POSIX.1-2008.

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, "Usage: %s <pathname>\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        if (lstat(argv[1], &sb) == -1) {
            perror("lstat");
            exit(EXIT_FAILURE);
        }

        printf("ID of containing device:  [%x,%x]\n",
               major(sb.st_dev),
               minor(sb.st_dev));

        printf("File type:                ");

        switch (sb.st_mode & S_IFMT) {
        case S_IFBLK:  printf("block device\n");            break;
        case S_IFCHR:  printf("character device\n");        break;
        case S_IFDIR:  printf("directory\n");               break;
        case S_IFIFO:  printf("FIFO/pipe\n");               break;
        case S_IFLNK:  printf("symlink\n");                 break;
        case S_IFREG:  printf("regular file\n");            break;
        case S_IFSOCK: printf("socket\n");                  break;
        default:       printf("unknown?\n");                break;
        }

        printf("I-node number:            %ju\n", (uintmax_t) sb.st_ino);

        printf("Mode:                     %jo (octal)\n",
               (uintmax_t) sb.st_mode);

        printf("Link count:               %ju\n", (uintmax_t) sb.st_nlink);
        printf("Ownership:                UID=%ju   GID=%ju\n",
               (uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid);

        printf("Preferred I/O block size: %jd bytes\n",
               (intmax_t) sb.st_blksize);
        printf("File size:                %jd bytes\n",
               (intmax_t) sb.st_size);
        printf("Blocks allocated:         %jd\n",
               (intmax_t) sb.st_blocks);

        printf("Last status change:       %s", ctime(&sb.st_ctime));
        printf("Last file access:         %s", ctime(&sb.st_atime));
        printf("Last file modification:   %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
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 (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.