readlink(2) System Calls Manual readlink(2) NAZWA readlink, readlinkat - odczytuje wartosc dowiazania symbolicznego BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include ssize_t readlink(size_t bufsiz; const char *restrict path, char buf[restrict bufsiz], size_t bufsiz); #include /* Definicja stalych AT_* */ #include ssize_t readlinkat(size_t bufsiz; int dirfd, const char *restrict path, char buf[restrict bufsiz], size_t bufsiz); Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)): readlink(): _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L || /* glibc <= 2.19: */ _BSD_SOURCE readlinkat(): Od glibc 2.10: _POSIX_C_SOURCE >= 200809L Przed glibc 2.10: _ATFILE_SOURCE OPIS readlink() umieszcza zawartosc dowiazania symbolicznego path w buforze buf, ktorego wielkosc wynosi bufsiz. readlink() nie dokleja do bufora buf koncowego bajtu null. W przypadku, gdy bufor jest za maly, aby pomiescic cala zawartosc dowiazania, jest ona (po cichu) obcinana (do ilosci znakow rownej dlugosci bufsiz). readlinkat() Wywolanie systemowe readlinkat() operuje w dokladnie taki sam sposob jak readlink(), z wyjatkiem roznic opisanych tutaj. Jesli sciezka podana w path jest wzgledna, jest to interpretowane w odniesieniu do katalogu do ktorego odnosi sie deskryptor pliku dirfd (zamiast w odniesieniu do biezacego katalogu roboczego procesu wywolujacego, jak w stosunku do sciezek wzglednych robi to readlink()). Jesli path jest wzgledna a dirfd ma wartosc specjalna AT_FDCWD, to path jest interpretowana w odniesieniu do biezacego katalogu roboczego procesu wywolujacego (jak readlink()). Jesli sciezka path jest bezwzgledna, to dirfd jest ignorowane. Od Linuksa 2.6.39, path moze byc lancuchem pustym; wowczas wywolanie dziala na dowiazaniu symbolicznym, do ktorego odnosi sie dirfd (ktore powinno byc uzyskane za pomoca open(2) ze znacznikami O_PATH i O_NOFOLLOW). Wiecej informacji o potrzebie wprowadzenia readlinkat() mozna znalezc w podreczniku openat(2). WARTOSC ZWRACANA W przypadku powodzenia, te wywolania zwracaja liczbe bajtow umieszczonych w buf (jesli wartosc zwracana rowna sie bufsiz, to moglo dojsc do obciecia). W razie wystapienia bledu zwracane jest -1 i ustawiane errno wskazujac blad. BLEDY EACCES Brak praw do przeszukiwania skladowej sciezki (patrz takze path_resolution(7)). EBADF (readlinkat()) path jest wzgledna, lecz dirfd nie wynosi ani AT_FDCWD, ani nie jest prawidlowym deskryptorem pliku. EFAULT buf wskazuje poza przydzielona procesowi przestrzen adresowa. EINVAL bufsiz nie jest dodatnie. EINVAL Nazwany plik (tj. ostatnia skladowa sciezki path) nie jest dowiazaniem symbolicznym. EIO Podczas odczytu z systemu plikow wystapil blad wejscia/wyjscia. ELOOP Natrafiono na zbyt wiele dowiazan symbolicznych podczas tlumaczenia sciezki. ENAMETOOLONG Sciezka, lub skladnik sciezki, byly za dlugie. ENOENT Plik wskazywany przez nazwe nie istnieje. ENOMEM Brak pamieci jadra. ENOTDIR Skladowa sciezki nie jest katalogiem. ENOTDIR (readlinkat()) path jest wzgledna, a dirfd jest deskryptorem pliku odnoszacym sie do pliku zamiast do katalogu. STANDARDY POSIX.1-2024. HISTORIA readlink() 4.4BSD (pojawilo sie pierwotnie w 4.2BSD), POSIX.1-2001, POSIX.1-2008. readlinkat() POSIX.1-2008. Linux 2.6.16, glibc 2.4. Do glibc 2.4 wlacznie, zwracany typ readlink() byl zadeklarowany jako int. Obecnie, zwracany typ jest zadeklarowany jako ssize_t, zgodnie z (nowym) wymaganiem POSIX.1-2001. glibc Na starszych wersjach jadra Linuxa gdzie readlinkat() nie bylo dostepne, funkcja opakowujaca z glibc wraca do uzywania readlink(). Kiedy path jest wzgledna, glibc konstruuje sciezke na bazie dowiazania symbolicznego w /proc/self/fd, ktore odpowiada argumentowi dirfd. UWAGI Uzywanie bufora o statycznym rozmiarze, moze nie dac wystarczajaco duzo miejsca na zawartosc dowiazania symbolicznego. Wymagany rozmiar bufora mozna uzyskac z wartosci stat.st_size, zwracanej przez wywolanie lstat(2), na dowiazaniu. Jednak nalezy sprawdzic liczbe bajtow zapisanych przez readlink() i readlinkat() aby upewnic sie, ze rozmiar dowiazania symbolicznego nie zmienil sie miedzy tymi wywolaniami. Dynamicznie przydzielany bufor readlink() i readlinkat() rozwiazuje rowniez czesty problem z przenosnoscia, gdy korzysta sie PATH_MAX jako rozmiaru bufora, bowiem zdefiniowanie tej stalej nie jest gwarantowane przez POSIX, jesli system nie posiada takiego limitu. PRZYKLADY Ponizszy program dynamicznie przydziela bufor, potrzebny readlink(), na podstawie informacji zapewnionych przez lstat(2), alternatywnie uzywajac bufora o rozmiarze PATH_MAX, w przypadku gdy lstat(2) zwroci rozmiar zerowy. #include #include #include #include #include #include int main(int argc, char *argv[]) { char *buf; ssize_t nbytes, bufsiz; struct stat sb; if (argc != 2) { fprintf(stderr, "Uzycie: %s \n", argv[0]); exit(EXIT_FAILURE); } if (lstat(argv[1], &sb) == -1) { perror("lstat"); exit(EXIT_FAILURE); } /* Dodaje jeden do rozmiaru dowiazania, dzieki czemu mozna sprawdzic, czy bufor zwrocony przez readlink() byl obciety. */ bufsiz = sb.st_size + 1; /* Niektore magiczne dowiazania symboliczne np. w /proc i /sys zglaszaja 'st_size' rowny zero. W takim przypadku uzywa PATH_MAX jako "wystarczajacego" oszacowania. */ if (sb.st_size == 0) bufsiz = PATH_MAX; buf = malloc(bufsiz); if (buf == NULL) { perror("malloc"); exit(EXIT_FAILURE); } nbytes = readlink(argv[1], buf, bufsiz); if (nbytes == -1) { perror("readlink"); exit(EXIT_FAILURE); } /* Wypisuje jedynie 'nbytes' z 'buf', dzieki czemu nie zawiera konczacego znaku null ('\0'). */ printf("'%s' wskazuje na '%.*s'\n", argv[1], (int) nbytes, buf); /* Jesli wartosc zwracana jest rowna rozmiarowi bufora, to dowiazanie docelowe bylo dluzsze niz oczekiwano (byc moze cel zmienil sie pomiedzy wywolaniem lstat() i wywolaniem readlink()). Ostrzega uzytkownika, ze zwracany cel mogl byc przyciety. */ if (nbytes == bufsiz) printf("(Zwracany bufor mogl byc przyciety)\n"); free(buf); exit(EXIT_SUCCESS); } ZOBACZ TAKZE readlink(1), lstat(2), stat(2), symlink(2), realpath(3), path_resolution(7), symlink(7) TLUMACZENIE Tlumaczenie niniejszej strony podrecznika: Przemek Borys , Andrzej Krzysztofowicz i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.18 8 lutego 2026 r. readlink(2)