Provided by: manpages-pl-dev_4.27.0-1_all 

NAZWA
getrlimit, setrlimit, prlimit - pobiera/ustawia limity zasobów
BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)
SKŁADNIA
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
int prlimit(pid_t pid, int resource,
const struct rlimit *_Nullable new_limit,
struct rlimit *_Nullable old_limit);
struct rlimit {
rlim_t rlim_cur; /* ograniczenie miękkie */
rlim_t rlim_max; /* ogr. sztywne (górna granica rlim_cur) */
};
typedef /* ... */ rlim_t; /* Typ: liczba całkowita bez znaku */
Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):
prlimit():
_GNU_SOURCE
OPIS
Wywołania systemowe getrlimit() i setrlimit() pobierają i ustawiają limity zasobów. Z każdym z zasobów
stowarzyszone jest miękkie i sztywne ograniczenie zdefiniowane w strukturze rlimit.
Ograniczenie miękkie jest wartością odpowiedniego zasobu wymuszoną przez jądro. Ograniczenie sztywne
działa jako górna granica dla ograniczenia miękkiego: proces nieuprzywilejowany może sobie ustawić
ograniczenie miękkie tylko w zakresie od 0 do ograniczenia sztywnego oraz (nieodwracalnie) obniżyć swoje
ograniczenie sztywne. Proces uprzywilejowany (w Linuksie: proces z przywilejem CAP_SYS_RESOURCE (ang.
capability) w swojej pierwotnej przestrzeni nazw użytkownika) może dowolnie zmieniać każdą z wartości
ograniczenia.
Wartość RLIM_INFINITY określa brak ograniczenia dla zasobu (zarówno w strukturze zwracanej przez
getrlimit(), jak i w strukturze przekazywanej do setrlimit()).
Argument resource musi być jednym z:
RLIMIT_AS
Jest to maksymalny rozmiar pamięci wirtualnej procesu (przestrzeni adresowej). Limit jest
określony w bajtach i zaokrąglony w dół, do systemowego rozmiaru strony. Limit dotyczy wywołań do
brk(2), mmap(2) i mremap(2), które po jego przekroczeniu zawiodą z błędem ENOMEM. Dodatkowo,
zawiedzie automatyczne rozszerzenie stosu (i wygeneruje sygnał SIGSEGV zabijający proces, jeśli za
pomocą sigaltstack(2) nie stał się dostępny alternatywny stos). Ze względu na to, że wartość ta
ma typ long, na komputerach z 32-bitowym long limit ten wynosi co najwyżej 2 GiB lub zasób ten
jest nieograniczony.
RLIMIT_CORE
Maksymalny rozmiar pliku core (zob. core(5)) w bajtach, który może zrzucić proces. Wartość 0
oznacza, że pliki zrzutu nie są tworzone. Gdy wartość jest niezerowa, większe zrzuty są przycinane
do wskazanego rozmiaru.
RLIMIT_CPU
Limit, w sekundach, czasu procesora (CPU), jaki może użyć proces. Gdy proces osiąga swoje
ograniczenie miękkie, jest do niego wysyłany sygnał SIGXCPU. Domyślną reakcją na ten sygnał jest
przerwanie procesu. Jednakże, sygnał może zostać przechwycony i procedura obsługi może przekazać
sterowanie do programu głównego. Jeśli proces nadal będzie używać zasoby procesora, będzie do
niego co sekundę wysyłany sygnał SIGXCPU aż do osiągnięcia ograniczenia sztywnego, kiedy to
wysyłany jest sygnał SIGKILL. (Ostatni punkt opisuje zachowanie Linuksa. W zależności od
implementacji procesy kontynuujące używanie zasobów procesora po osiągnięciu ograniczenia
miękkiego są różnie traktowane. Aplikacje przenośne, które mają potrzebę przechwycenia tego
sygnału, powinny zakończyć się w sposób kontrolowany w chwili otrzymaniu pierwszego SIGXCPU.)
RLIMIT_DATA
Maksymalny rozmiar segmentu danych procesu (dane zainicjowane, dane niezainicjowane i sterta).
Limit jest podawany w bajtach i jest zaokrąglany w dół, do systemowego rozmiaru strony.
Ograniczenie to wpływa na wywołania brk(2), sbrk(2) i (od Linuksa 4.7) mmap(2), które kończą się
niepomyślnie, zgłaszając błąd ENOMEM w momencie natrafienia na miękkie ograniczenie tego zasobu.
RLIMIT_FSIZE
Maksymalny rozmiar plików w bajtach, jakie może utworzyć dany proces. Próba rozszerzenia pliku
ponad to ograniczenie kończy się otrzymaniem sygnału SIGXFSZ. Domyślnie, sygnał ten kończy
działanie procesu, ale proces może go przechwycić. Wówczas odpowiednia funkcja systemowa (np.
write(2), truncate(2)) kończy się błędem EFBIG.
RLIMIT_LOCKS (Linux 2.4.0 do Linuksa 2.4.24)
Ograniczenie łącznej liczby blokad flock(2) i dzierżaw fcntl(2), które może ustanowić proces.
RLIMIT_MEMLOCK
Maksymalna liczba bajtów pamięci, które mogą być zablokowane w RAM. Limit jest w praktyce
zaokrąglany w dół do najbliższej wielokrotności systemowego rozmiaru strony. Limit dotyczy
mlock(2), mlockall(2) oraz operacji MAP_LOCKED mmap(2). Od Linuksa 2.6.9, limit dotyczy również
operacji SHM_LOCK shmctl(2), gdzie ustawia maksymalną sumę bajtów segmentów pamięci dzielonej
(zob. shmget(2)), które mogą być zablokowane przez rzeczywisty identyfikator użytkownika procesu
wywołującego. Blokady SHM_LOCK shmctl(2) są liczone oddzielnie od blokad pamięci na proces,
ustanowionych przez mlock(2), mlockall(2) i MAP_LOCKED mmap(2); proces może zablokować bajty do
tego limitu w każdej z tych dwóch kategorii.
Przed Linuksem 2.6.9, limit ten kontrolował wielkość pamięci, która mogła być zablokowana przez
proces uprzywilejowany. Od Linuksa 2.6.9, na wielkość pamięci, jaka może być zablokowana przez
proces uprzywilejowany nie są nakładane limity, a opisywany limit dotyczy w zamian procesów
nieuprzywilejowanych.
RLIMIT_MSGQUEUE (od Linuksa 2.6.8)
Limit liczby bajtów, które mogą być przydzielone kolejkom komunikatów POSIX dla rzeczywistego
identyfikatora użytkownika procesu wywołującego. Limit ten jest wymuszony na mq_open(3). Każda
kolejka komunikatów, którą tworzy użytkownika wlicza się do tego limitu (do momentu jej usunięcia)
zgodnie ze wzorem:
Od Linuksa 3.5:
bytes = attr.mq_maxmsg * sizeof(struct msg_msg) +
MIN(attr.mq_maxmsg, MQ_PRIO_MAX) *
sizeof(struct posix_msg_tree_node)+
/* Do narzutu */
attr.mq_maxmsg * attr.mq_msgsize;
/* Do danych komunikatów */
Linux 3.4 i wcześniejsze:
bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +
/* Do narzutu */
attr.mq_maxmsg * attr.mq_msgsize;
/* Do danych komunikatów */
gdzie attr jest strukturą mq_attr określoną jako czwarty argument do mq_open(3), a struktury
msg_msg i posix_msg_tree_node są wewnętrznymi strukturami jądra.
Składowa „narzutu” we wzorze bierze pod uwagę bajty narzutu wymagane przez implementację i
zapewnia, że użytkownik nie może utworzyć nieskończonej liczby komunikatów o zerowej długości
(takie komunikaty wciąż zajmują nieco pamięci systemowej ze względu na narzut księgowania).
RLIMIT_NICE (od Linuksa 2.6.12, lecz zob. USTERKI poniżej)
Określa górną granicę, do której można zwiększyć wartość nice procesu za pomocą setpriority(2) lub
nice(2). Rzeczywista górna granica jest obliczana jako 20 - rlim_cur. Użyteczny zakres tego limitu
wynosi zatem od 1 (co odpowiada wartości nice 19) do 40 (co odpowiada wartości nice -20). Ten
nietypowy zakres był konieczny, ponieważ liczby ujemne nie mogą stanowić wartości limitów zasobów,
gdyż zwykle mają specjalne znaczenie. Na przykład RLIM_INFINITY jest zwykle równoważne -1. Więcej
szczegółów na temat wartości nice można znaleźć w podręczniku sched(7).
RLIMIT_NOFILE
Określa wartość o jeden większą niż maksymalna liczba deskryptorów plików, które dany proces może
otworzyć. Próby (open(), pipe(), dup() itd.) przekroczenia tego limitu dają błąd EMFILE
(historycznie limit ten nosił nazwę RLIMIT_OFILE na BSD).
Od Linuksa 4.5, limit ten definiuje również maksymalną liczbę deskryptorów pliku, jakie proces
nieuprzywilejowany (bez przywileju CAP_SYS_RESOURCE (ang. capability)) może mieć „w locie” do
innych procesów, przy przekazywaniu za pomocą gniazd domeny Uniksa. Limit ten dotyczy wywołania
systemowego sendmsg(2). Więcej szczegółów w podręczniku unix(7).
RLIMIT_NPROC
Limit liczby istniejących procesów (lub, precyzyjniej w Linuksie, wątków) dla rzeczywistego
identyfikatora użytkownika procesu wywołującego. Jeśli liczba bieżących procesów, będących
własnością rzeczywistego identyfikatora użytkownika tego procesu, jest większa lub równa limitowi,
fork() zawiedzie z błędem EAGAIN.
Limit RLIMIT_NPROC nie jest wymuszany na procesach z przywilejem CAP_SYS_ADMIN lub
CAP_SYS_RESOURCE (ang. capability) i procesach z rzeczywistym identyfikatorem użytkownika równym
0.
RLIMIT_RSS
Limit (w bajtach) rezydentnych stron procesu (liczba stron pamięci wirtualnej pozostających w
RAM). Ograniczenie to działa tylko w Linuksie 2.4.x, gdzie x < 30, i dotyczy jedynie wywołań
madvise(2) z użyciem MADV_WILLNEED.
RLIMIT_RTPRIO (od Linuksa 2.6.12, lecz zob. USTERKI)
Górna granica, jaką można ustawić dla priorytetu czasu rzeczywistego, dla danego procesu, za
pomocą sched_setscheduler(2) i sched_setparam(2).
Więcej informacji o politykach szeregowania zadań czasu rzeczywistego opisano w podręczniku
sched(7).
RLIMIT_RTTIME (od Linuksa 2.6.25)
Limit (w mikrosekundach) czasu procesora, jaki proces korzystający z szeregowania zadań czasu
rzeczywistego może użyć, bez czynienia blokującego wywołania systemowego. Do celu tego limitu, za
każdym razem, gdy proces tworzy blokujące wywołanie systemowe, licznik użytego czasu procesora
jest resetowany do zera. Licznik czasu procesora nie jest resetowany, jeśli proces kontynuuje
próbę użycia procesora, lecz jest wywłaszczony, przydzielona mu jednostka czasu wyczerpała się lub
wywoła sched_yield(2).
Po osiągnięciu limitu miękkiego, do procesu wysyłany jest sygnał SIGXCPU. Jeśli proces go
przechwyci lub zignoruje i będzie kontynuował używanie czasu procesora, sygnał SIGXCPU będzie
generowany co sekundę, do momentu osiągnięcia limitu sztywnego, gdy proces otrzyma sygnał SIGKILL.
Limit ten ma na celu zapobiegnięcie zablokowania systemu przez zbiegłe procesy czasu
rzeczywistego.
Więcej informacji o politykach szeregowania zadań czasu rzeczywistego opisano w podręczniku
sched(7).
RLIMIT_SIGPENDING (od Linuksa 2.6.8)
Limit liczby sygnałów, jakie mogą być zakolejkowane dla rzeczywistego identyfikatora użytkownika
procesu wywołującego. Do celu sprawdzania tego limitu liczą się sygnały zwykłe i czasu
rzeczywistego. Limit jest jednak wymuszany jedynie dla sigqueue(3); można zawsze skorzystać z
kill(2), aby zakolejkować po jednym z każdego sygnału, który nie występuje w kolejce do procesu.
RLIMIT_STACK
Maksymalny rozmiar stosu procesu w bajtach. W chwili osiągnięcia tego ograniczenia, generowany
jest sygnał SIGSEGV. W celu obsłużenia tego sygnału proces musi założyć alternatywny stos dla
sygnałów (sigaltstack(2)).
Od Linuksa 2.6.23, limit ten określa również wielkość przestrzeni używanej dla argumentów wiersza
polecenia oraz zmiennych środowiskowych procesu; więcej szczegółów w podręczniku execve(2).
prlimit()
Typowo linuksowe wywołanie systemowe prlimit() łączy i rozszerza funkcjonalność setrlimit() i
getrlimit(). Można go używać do ustawienia i pobrania limitów zasobów dowolnego procesu.
Argument resource ma takie samo znaczenie jak w przypadku setrlimit() i getrlimit().
Jeśli argument new_limit nie wynosi NULL, to struktura rlimit, na którą on wskazuje, jest używana do
ustawienia nowych wartości limitów miękkich i sztywnych resource. Jeśli argument old_limit nie wynosi
NULL, to pomyślne wywołanie prlimit() umieszcza poprzednie limity miękkie i sztywne resource w strukturze
rlimit, na którą wskazuje old_limit.
Argument pid określa identyfikator procesu, na którym wywołanie ma operować. Jeśli pid wynosi 0, to
wywołanie stosuje się do procesu wywołującego. Aby ustawić lub pobrać zasoby procesu innego niż własny,
wywołujący musi mieć przywilej CAP_SYS_RESOURCE (ang. capability) w przestrzeni nazw użytkownika procesu,
którego limity zasobów są zmieniane lub identyfikatory: rzeczywisty, efektywny i zapisany suid procesu
docelowego muszą odpowiadać identyfikatorowi rzeczywistemu procesu wywołującego oraz identyfikatory:
rzeczywisty, efektywny i zapisany suid procesu docelowego muszą odpowiadać rzeczywistemu identyfikatorowi
grupy wywołującego.
WARTOŚĆ ZWRACANA
W przypadku powodzenia, te wywołania zwracają 0. W razie wystąpienia błędu zwracane jest -1 i ustawiane
errno, wskazując błąd.
BŁĘDY
EFAULT Argument wskaźnika wskazuje na położenie poza dostępną przestrzeń adresową.
EINVAL WArtość określona w resource nie jest prawidłowa; albo — w przypadku setrlimit() lub prlimit():
rlim->rlim_cur był większy niż rlim->rlim_max.
EPERM Proces nieuprzywilejowany próbował zwiększyć limit sztywny; do dokonania tego konieczny jest
przywilej CAP_SYS_RESOURCE (ang. capability).
EPERM Wywołujący próbował zwiększyć limit sztywny RLIMIT_NOFILE ponad wartość maksymalną określoną w
/proc/sys/fs/nr_open (zob. proc(5))
EPERM (prlimit()) Proces wywołujący nie miał uprawnień do ustawiania limitów dla procesu podanego w
pid.
ESRCH Nie udało się znaleźć procesu o identyfikatorze podanym w pid.
ATRYBUTY
Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).
┌──────────────────────────────────────────────────────────────┬────────────────────────┬───────────────┐
│ Interfejs │ Atrybut │ Wartość │
├──────────────────────────────────────────────────────────────┼────────────────────────┼───────────────┤
│ getrlimit(), setrlimit(), prlimit() │ Bezpieczeństwo wątkowe │ MT-bezpieczne │
└──────────────────────────────────────────────────────────────┴────────────────────────┴───────────────┘
STANDARDY
getrlimit()
setrlimit()
POSIX.1-2008.
prlimit()
Linux.
RLIMIT_MEMLOCK i RLIMIT_NPROC pochodzą z BSD i nie są określone w POSIX.1; są obecne w systemach BSD i
Linux, ale z różnymi implementacjami. RLIMIT_RSS pochodzi z BSD i nie jest określone w POSIX.1; jest
jednak obecne w większości implementacji. RLIMIT_MSGQUEUE, RLIMIT_NICE, RLIMIT_RTPRIO, RLIMIT_RTTIME i
RLIMIT_SIGPENDING są typowo linuksowe.
HISTORIA
getrlimit()
setrlimit()
POSIX.1-2001, SVr4, 4.3BSD.
prlimit()
Linux 2.6.36, glibc 2.13.
UWAGI
Proces potomny utworzony za pomocą fork(2) dziedziczy limity zasobów swojego procesu macierzystego.
Limity zasobów są zachowywane przez execve(2).
Limity zasobów są atrybutami przypisanymi procesowi i są dzielone przez wszystkie wątki procesu.
Zmniejszenie miękkiego limitu zasobu poniżej jego aktualnego użycia przez proces powiedzie się (lecz
zapobiegnie dalszemu zwiększeniu użycia zasobu przez proces).
Można ustawić limity zasobów powłoki za pomocą wbudowanego polecenia ulimit (limit w csh(1)). Limity
zasobów powłoki są dziedziczone przez procesy tworzone do wykonywania poleceń powłoki.
Od Linuksa 2.6.24, limity zasobów dowolnego procesu można sprawdzić za pomocą /proc/pid/limits; zob.
proc(5).
Dawne systemy udostępniały funkcję vlimit() o podobnym zastosowaniu do setrlimit(). Ze względu na
kompatybilność wsteczną, glibc również udostępnia vlimit(). Wszystkie nowe aplikacje powinny używać
wyłącznie setrlimit().
Różnice ABI biblioteki C/jądra
Od glibc 2.13, funkcje opakowujące getrlimit() i setrlimit() z glibc nie przywołują już odpowiadających
im wywołań systemowych, lecz używają prlimit(), ze względów opisanych w USTERKACH.
Nazwą opakowującej funkcji z glibc jest prlimit(); nazwą wywołania systemowego jest prlimit64().
USTERKI
W starszych jądrach Linux, sygnały SIGXCPU i SIGKILL dostarczane, gdy proces napotkał miękkie i sztywne
limity RLIMIT_CPU, dostarczano jedną sekundę (procesorową) później, niż powinno to nastąpić. Poprawiono
to w Linuksie 2.6.8.
W jądrach Linux 2.6.x wcześniejszych niż Linux 2.6.17, limit RLIMIT_CPU wynoszący 0 był nieprawidłowo
traktowany jako „brak limitu” (jak RLIM_INFINITY). Od Linuksa 2.6.17, ustawienie limitu 0 jest stosowane,
ale faktycznie skutkuje limitem 1 sekundy.
Błąd jądra powodował, że RLIMIT_RTPRIO nie działał w Linuksie 2.6.12; problem poprawiono w Linuksie
2.6.13.
W Linuksie 2.6.12, istniała niezgodność o jeden pomiędzy zakresami priorytetów zwracanymi przez
getpriority(2) i RLIMIT_NICE. Dawało te efekt, że faktyczna górna granica wartości nice była obliczana
jako 19 - rlim_cur. Poprawiono to w Linuksie 2.6.13.
Od Linuksa 2.6.12, jeśli proces osiąga swój miękki limit RLIMIT_CPU i posiada procedurę obsługi SIGXCPU,
to, oprócz przywołania procedury obsługi, jądro zwiększa miękki limit o jedną sekundę. Zachowanie to
powtarza się, jeśli proces kontynuuje używanie czasu procesora, aż do osiągnięcia limitu sztywnego, gdy
proces jest zabijany. Inne implementacje nie zmieniają miękkiego limitu RLIMIT_CPU w ten sposób, a
zachowanie Linuksa prawdopodobnie nie jest zgodne ze standardami; przenośne aplikacje powinny unikać
polegania na tym typowo linuksowym zachowaniu. Typowo linuksowy limit RLIMIT_RTTIME działa w ten sam
sposób, gdy osiągnie się miękki limit.
Jądra przed Linuksem 2.4.22 nie diagnozują błędu EINVAL w przypadku setrlimit(), gdy rlim->rlim_cur było
większe niż rlim->rlim_max.
Ze względu na kompatybilność, Linux nie zwraca błędu, gdy próba ustawienia RLIMIT_CPU zawodzi.
Reprezentacja „dużych” wartości limitu zasobu na platformach 32-bitowych
Funkcje opakowujące getrlimit() i setrlimit() z glibc używają 64-bitowego typu danych rlim_t, nawet na
platformach 32-bitowych. Jednakże typ danych rlim_t używany w wywołaniach systemowych getrlimit() i
setrlimit() jest (32-bitowym) unsigned long. Co więcej, w Linuksie jądro reprezentuje limit zasobów na
platformach 32-bitowych jako unsigned long. Jednak 32-bitowy typ danych nie jest wystarczająco szeroki.
Najtrudniejsza sytuacja występuje odnośnie limitu RLIMIT_FSIZE określającego maksymalny rozmiar, do
jakiego może zostać zwiększony plik: aby być użytecznym, limit ten musi być reprezentowany przez typ,
który jest tak szeroki, jak typ używany do reprezentowania przesunięć pliku tj. tak szeroki jak 64-bitowe
off_t (zakładając, że program skompilowano z _FILE_OFFSET_BITS=64).
Aby obejść to ograniczenie, w przypadku gdy program próbował ustawić limit zasobów na wartość większą niż
może być reprezentowana w 32-bitowym unsigned long, funkcja opakowująca setrlimit() z glibc po cichu
konwertowała wartość limitu na RLIM_INFINITY. Innymi słowy, żądany limit zasobów był po cichu ignorowany.
OD glibc 2.13, glibc obchodzi to ograniczenie wywołań systemowych getrlimit() i setrlimit() implementując
setrlimit() i getrlimit() jako funkcje opakowujące wywołujące prlimit().
PRZYKŁADY
Poniższy program demonstruje użycie prlimit().
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <time.h>
int
main(int argc, char *argv[])
{
pid_t pid;
struct rlimit old, new;
struct rlimit *newp;
if (!(argc == 2 || argc == 4)) {
fprintf(stderr, "Użycie: %s <pid> [<nowy-limit-miękki> "
"<nowy-limit-sztywny>]\n", argv[0]);
exit(EXIT_FAILURE);
}
pid = atoi(argv[1]); /* PID procesu docelowego */
newp = NULL;
if (argc == 4) {
new.rlim_cur = atoi(argv[2]);
new.rlim_max = atoi(argv[3]);
newp = &new;
}
/* Ustawia limit czasu procesora procesu docelowego; pobiera
i wyświetla poprzedni limit */
if (prlimit(pid, RLIMIT_CPU, newp, &old) == -1)
err(EXIT_FAILURE, "prlimit-1");
printf("Poprzednie limity: miękki=%jd; sztywny=%jd\n",
(intmax_t) old.rlim_cur, (intmax_t) old.rlim_max);
/* Pobiera i wyświetla nowy limit czasu procesora */
if (prlimit(pid, RLIMIT_CPU, NULL, &old) == -1)
err(EXIT_FAILURE, "prlimit-2");
printf("Nowe limity: miękki=%jd; sztywny=%jd\n",
(intmax_t) old.rlim_cur, (intmax_t) old.rlim_max);
exit(EXIT_SUCCESS);
}
ZOBACZ TAKŻE
prlimit(1), dup(2), fcntl(2), fork(2), getrusage(2), mlock(2), mmap(2), open(2), quotactl(2), sbrk(2),
shmctl(2), malloc(3), sigqueue(3), ulimit(3), core(5), capabilities(7), cgroups(7), credentials(7),
signal(7)
TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz
<ankry@green.mf.pg.gda.pl> 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.
Linux man-pages 6.9.1 17 czerwca 2024 r. getrlimit(2)