.\" -*- coding: UTF-8 -*-
'\" t
.\" Copyright (c) 1992 Drew Eckhardt <drew@cs.colorado.edu>, March 28, 1992
.\" and Copyright (c) Michael Kerrisk, 2001, 2002, 2005, 2013, 2019
.\"
.\" SPDX-License-Identifier: GPL-1.0-or-later
.\"
.\" Modified by Michael Haardt <michael@moria.de>
.\" Modified 24 Jul 1993 by Rik Faith <faith@cs.unc.edu>
.\" Modified 21 Aug 1994 by Michael Chastain <mec@shell.portal.com>:
.\"   New man page (copied from 'fork.2').
.\" Modified 10 June 1995 by Andries Brouwer <aeb@cwi.nl>
.\" Modified 25 April 1998 by Xavier Leroy <Xavier.Leroy@inria.fr>
.\" Modified 26 Jun 2001 by Michael Kerrisk
.\"     Mostly upgraded to Linux 2.4.x
.\"     Added prototype for sys_clone() plus description
.\"	Added CLONE_THREAD with a brief description of thread groups
.\"	Added CLONE_PARENT and revised entire page remove ambiguity
.\"		between "calling process" and "parent process"
.\"	Added CLONE_PTRACE and CLONE_VFORK
.\"	Added EPERM and EINVAL error codes
.\"	Renamed "__clone" to "clone" (which is the prototype in <sched.h>)
.\"	various other minor tidy ups and clarifications.
.\" Modified 26 Jun 2001 by Michael Kerrisk <mtk.manpages@gmail.com>
.\"	Updated notes for 2.4.7+ behavior of CLONE_THREAD
.\" Modified 15 Oct 2002 by Michael Kerrisk <mtk.manpages@gmail.com>
.\"	Added description for CLONE_NEWNS, which was added in Linux 2.4.19
.\" Slightly rephrased, aeb.
.\" Modified 1 Feb 2003 - added CLONE_SIGHAND restriction, aeb.
.\" Modified 1 Jan 2004 - various updates, aeb
.\" Modified 2004-09-10 - added CLONE_PARENT_SETTID etc. - aeb.
.\" 2005-04-12, mtk, noted the PID caching behavior of NPTL's getpid()
.\"	wrapper under BUGS.
.\" 2005-05-10, mtk, added CLONE_SYSVSEM, CLONE_UNTRACED, CLONE_STOPPED.
.\" 2005-05-17, mtk, Substantially enhanced discussion of CLONE_THREAD.
.\" 2008-11-18, mtk, order CLONE_* flags alphabetically
.\" 2008-11-18, mtk, document CLONE_NEWPID
.\" 2008-11-19, mtk, document CLONE_NEWUTS
.\" 2008-11-19, mtk, document CLONE_NEWIPC
.\" 2008-11-19, Jens Axboe, mtk, document CLONE_IO
.\"
.\"*******************************************************************
.\"
.\" This file was generated with po4a. Translate the source file.
.\"
.\"*******************************************************************
.TH clone 2 "5 lutego 2023 r." "Linux man\-pages 6.03" 
.SH NAZWA
clone, __clone2, clone3 \- tworzy proces potomny
.SH BIBLIOTEKA
Standardowa biblioteka C (\fIlibc\fP, \fI\-lc\fP)
.SH SKŁADNIA
.nf
/* Prototyp funkcji opakowującej z glibc */
.PP
\fB#define _GNU_SOURCE\fP
\fB#include <sched.h>\fP
.PP
\fBint clone(int (*\fP\fIfn\fP\fB)(void *_Nullable), void *\fP\fIstack\fP\fB, int \fP\fIflags\fP\fB,\fP
\fB          void *_Nullable \fP\fIarg\fP\fB, ...\fP\fI  \fP/*\fB pid_t *_Nullable \fP\fIparent_tid\fP\fB,\fP
\fB                                       void *_Nullable \fP\fItls\fP\fB,\fP
\fB                                       pid_t *_Nullable \fP\fIchild_tid\fP\fB \fP*/\fB );\fP
.PP
/* Zob. UWAGI dot. prototypu surowego wywołania syst. clone() */
.PP
\fB#include <linux/sched.h>\fP    /* Definicja \fBstruct clone_args\fP */
\fB#include <sched.h>\fP          /* Definicja stałych \fBCLONE_*\fP */
\fB#include <sys/syscall.h>\fP    /* Definicja stałych \fBSYS_*\fP */
\fB#include <unistd.h>\fP
.PP
\fBlong syscall(SYS_clone3, struct clone_args *\fP\fIcl_args\fP\fB, size_t \fP\fIsize\fP\fB);\fP
.fi
.PP
\fIUwaga\fP: glibc nie udostępnia opakowania do \fBclone3\fP(), zatem wymagane
jest użycie \fBsyscall\fP(2).
.SH OPIS
Niniejsze wywołania systemowe tworzą nowy proces (\[Bq]potomny\[rq]), w
sposób podobny do \fBfork\fP(2).
.PP
W przeciwieństwie do \fBfork\fP(2), te wywołania systemowe udostępniają
precyzyjniejszą kontrolę wobec kontekstu wykonania, który jest dzielony
między procesem wywołującym a procesem potomnym. Przykładowo, za pomocą
niniejszych wywołań systemowych, wywołujący może kontrolować czy oba procesy
dzielą wirtualną przestrzeń adresową, tablicę deskryptorów pliku i tablicę
procedur obsługi sygnałów. Te wywołania systemowego umożliwiają również
umieszczenie procesu potomnego w oddzielnych przestrzeniach nazw
(zob. \fBnamespaces\fP(7)).
.PP
Proszę zauważyć, że w niniejszym podręczniku systemowym \[Bq]proces
wywołujący\[rq] odpowiada zwykle \[Bq]procesowy macierzystemu\[rq]. Proszę
jednak sprawdzić opisy \fBCLONE_PARENT\fP i \fBCLONE_THREAD\fP niżej.
.PP
Niniejsza strona podręcznika opisuje następujące interfejsy:
.IP \[bu] 3
Funkcję opakowującą \fBclone\fP() z glibc i podległe wywołanie systemowe, w
oparciu o które działa. Główna część podręcznika opisuje funkcję
opakowującą; różnice w stosunku do surowego wywołania systemowego opisano
bliżej końca.
.IP \[bu]
Nowsze wywołanie systemowe \fBclone3\fP().
.PP
.\"
W pozostałej treści niniejszego podręcznika, pojęcie \[Bq]wywołanie
clone\[rq] lub \[Bq]wywołanie klonowania\[rq] używane jest przy opisywaniu
szczegółów odnoszących się do wszystkich tych interfejsów.
.SS "Funkcja opakowująca clone()"
Gdy proces potomny tworzony jest za pomocą funkcji opakowującej \fBclone\fP(),
rozpoczyna on wykonanie od wywołania funkcji, na którą wskazuje argument
\fIfn\fP (różni się to od \fBfork\fP(2), gdzie proces potomny kontynuuje wykonanie
od miejsca wywołania \fBfork\fP(2)). Argument \fIarg\fP jest przekazywany jako
argument do funkcji \fIfn\fP.
.PP
Gdy funkcja \fIfn\fP(\fIarg\fP) powróci, proces potomny kończy działanie. Liczba
całkowita zwrócona przez \fIfn\fP jest statusem zakończenia procesu
potomnego. Proces potomny może również zakończyć się jawnie wołając
\fBexit\fP(2) lub po otrzymaniu krytycznego sygnału.
.PP
Argument \fIstack\fP określa położenie stosu używanego przez proces
potomny. Ponieważ potomek i proces wywołujący mogą współdzielić pamięć, nie
jest możliwe, aby proces potomny korzystał z tego samego stosu, co proces
wywołujący. Proces wywołujący musi więc przydzielić obszar pamięci
przeznaczony na stos potomka i przekazać wskaźnik do tego obszaru w
\fBclone\fP. Stosy rosną w dół na wszystkich procesorach, na których działa
Linux (z wyjątkiem procesorów HP PA), więc \fIstack\fP zazwyczaj wskazuje na
najwyższy adres obszaru pamięci zarezerwowanego na stos potomka. Proszę
zauważyć, że \fBclone\fP() nie zapewnia mechanizmu, w którym wywołujący mógłby
poinformować jądro o wielkości obszaru stosu.
.PP
.\"
Pozostałe argumenty \fBclone\fP() opisano poniżej.
.SS clone3()
Wywołanie systemowe \fBclone3\fP() udostępnia nadzbiór funkcjonalności wobec
starszego interfejsu \fBclone\fP(). Zawiera również wiele usprawnień API m.in:
przestrzeń na dodatkowe bity znaczników, przejrzystszy podział stosowania
różnych argumentów oraz możliwość określenia rozmiaru przestrzeni stosu
procesu potomnego.
.PP
Podobnie jak \fBfork\fP(2), \fBclone3\fP() powraca zarówno w procesie
macierzystym, jak i potomnym. Zwraca 0 do procesu potomnego, natomiast
procesowi macierzystemu zwraca PID procesu potomnego.
.PP
Argumentem \fIcl_args\fP \fBclone3\fP() jest struktura w następującej postaci:
.PP
.in +4n
.EX
struct clone_args {
    u64 flags;        /* Maska bitowa znaczników */
    u64 pidfd;        /* Gdzie przechowywać deskryptor pliku PID
                         (\fIint *\fP) */
    u64 child_tid;    /* Gdzie przechowywać TID p. potomnego,
                         w pamięci p. potomnego (\fIpid_t *\fP) */
    u64 parent_tid;   /* Gdzie przechowywać TID, w pamięci
                         procesu macierzystego (\fIpid_t *\fP) */
    u64 exit_signal;  /* Sygnał do dostarcz. przy zakończeniu
                         procesu potomnego */
    u64 stack;        /* Wskaźnik do najniższych bajtów stosu */
    u64 stack_size;   /* Rozmiar stosu */
    u64 tls;          /* Położenie nowego TLS */
    u64 set_tid;      /* Wskaźnik do tablicy \fIpid_t\fP
                         (od Linuksa 5.5) */
    u64 set_tid_size; /* Liczba elementów w \fIset_tid\fP
                         (od Linuksa 5.5) */
    u64 cgroup;       /* Deskryptor pliku docelowej gr. kontr.
                         procesu potomnego (od Linuksa 5.7) */
};
.EE
.in
.PP
Argument \fIsize\fP dostarczany do \fBclone3\fP() powinien być zainicjowany z
rozmiarem tej struktury (obecność argumentu \fIsize\fP pozwala na przyszłe
poszerzanie struktury \fIclone_args\fP).
.PP
Stos procesu potomnego podaje się za pomocą \fIcl_args.stack\fP, które wskazuje
na najniższe bajty w przestrzeni stosu oraz za pomocą \fIcl_args.stack_size\fP,
które określa rozmiar stosu w bajtach. W przypadku gdy poda się znacznik
\fBCLONE_VM\fP (zob. niżej), stos musi być jawnie zaalokowany i określony. W
przeciwnym przypadku, te dwa pola można podać jako NULL i 0, co powoduje
używanie przez proces potomny tej samej przestrzeni stosu, z jakiej korzysta
proces macierzysty (we własnej wirtualnej przestrzeni adresowej procesu
potomnego).
.PP
.\"
Pozostałe pola argumentu \fIcl_args\fP opisano niżej.
.SS "Równoważność pomiędzy argumentami clone() i clone3()"
W odróżnieniu do starszego interfejsu \fBclone\fP(), którego argumenty są
przekazywane pojedynczo, w nowszym interfejsie \fBclone3\fP() argumenty są
łączone w strukturze \fIclone_args\fP pokazanej wyżej. Struktura pozwala na
przekazanie nadzbioru informacji, przekazywanych za pomocą argumentów
\fBclone\fP().
.PP
Poniższa tabela ukazuje równoważność pomiędzy argumentami \fBclone\fP() i
polami w argumencie \fIclone_args\fP przekazywanym \fBclone3\fP():
.RS 4
.TS
lb lb lb
l l l
li li l.
clone()	clone3()	Uwagi
	pole \fIcl_args\fP
flags & \[ti]0xff	flags	T{
Do większości znaczników; szczegóły niżej
T}
parent_tid	pidfd	Zob. CLONE_PIDFD
child_tid	child_tid	Zob. CLONE_CHILD_SETTID
parent_tid	parent_tid	Zob. CLONE_PARENT_SETTID
flags & 0xff	exit_signal
stack	stack
\fI\-\-\-\fP	stack_size
tls	tls	Zob. CLONE_SETTLS
\fI\-\-\-\fP	set_tid	Zob. niżej aby poznać szczegóły
\fI\-\-\-\fP	set_tid_size
\fI\-\-\-\fP	cgroup	Zob. CLONE_INTO_CGROUP
.TE
.RE
.\"
.SS "Sygnał zakończenia potomka"
.\"
Gdy proces potomny zostanie zakończony, do rodzica może być wysłany
sygnał. Sygnał zakończenia jest określany niższym bajtem \fIflags\fP
(\fBclone\fP()) lub \fIcl_args.exit_signal\fP (\fBclone3\fP()). Jeśli określono inny
sygnał niż \fBSIGCHLD\fP, to proces macierzysty musi podać opcję \fB__WALL\fP lub
\fB__WCLONE\fP czekając na potomka w \fBwait\fP(2). Gdy sygnał nie zostanie
określony (tj. podano zero), to proces macierzysty nie zostanie zawiadomiony
o zakończeniu pracy potomka.
.SS "Tablica set_tid"
Domyślnie, jądro wybiera następny numer PID dla nowego procesu, w każdej
przestrzeni nazw PID, w której jest on obecny. Przy tworzeniu procesu za
pomocą \fBclone3\fP(), tablicę \fIset_tid\fP (dostępną od Linuksa 5.5) można użyć
do wybrania konkretnych PID\-ów w niektórych lub we wszystkich przestrzeniach
nazw PID, w których jest on obecny. Jeśli PID nowo tworzonego procesu ma być
ustawiony tylko w bieżącej przestrzeni nazw PID lub w nowo tworzonej
przestrzeni nazw PID (jeśli \fIflags\fP zawiera \fBCLONE_NEWPID\fP), to pierwszym
elementem w tablicy \fIset_tid\fP musi być żądany PID, a \fIset_tid_size\fP musi
wynosić 1.
.PP
Jeśli PID nowo tworzonego procesu ma mieć określoną wartość w wielu
przestrzeniach nazw PID, to tablica \fIset_tid\fP może zawierać wiele
wpisów. Pierwszy wpis definiuje PID najbardziej zagnieżdżonej przestrzeni
nazw PID, a każdy kolejny zawiera PID w odpowiadającej przestrzeni nazw PID
przodka. Liczba przestrzeni nazw PID, w której PID ma być ustawiony, jest
definiowana przez \fIset_tid_size\fP, które nie może być większe od liczby
aktualnie zagnieżdżonych przestrzeni nazw.
.PP
Aby utworzyć proces z następującymi PID\-ami w hierarchii przestrzeni nazw
PID:
.RS 4
.TS
lb lb lb
l l l.
Poziom zagn. PID	Żądany PID	Uwagi
0	31496	Najbardziej zewnętrzna p. n. PID
1	42
2	7	Najbardziej wewnętrzna p. n. PID
.TE
.RE
.PP
Należy ustawić tablicę na
.PP
.in +4n
.EX
set_tid[0] = 7;
set_tid[1] = 42;
set_tid[2] = 31496;
set_tid_size = 3;
.EE
.in
.PP
Jeśli mają być określone jedynie PID\-y w dwóch najbardziej wewnętrznych
przestrzeniach nazw PID, należy ustawić tablicę na:
.PP
.in +4n
.EX
set_tid[0] = 7;
set_tid[1] = 42;
set_tid_size = 2;
.EE
.in
.PP
PID w przestrzeni nazw PID poza dwoma najbardziej wewnętrznymi
przestrzeniami nazw PID jest wybierany w ten sam sposób, jak inne PID\-y.
.PP
.\" commit 124ea650d3072b005457faed69909221c2905a1f
.\" commit 1caef81da05a84a40dbf02110e967ce6d1135ff6
Funkcja \fIset_tid\fP wymaga przywileju (ang. capability) \fBCAP_SYS_ADMIN\fP lub
(od Linuksa 5.9) \fBCAP_CHECKPOINT_RESTORE\fP we wszystkich posiadanych
przestrzeniach nazw użytkownika, w których PID ma być zmieniany.
.PP
.\"
Wywołujący mogą wybrać PID większy od 1 jedynie, gdy w danej przestrzeni
nazw PID istnieje już proces \fBinit\fP (tj. proces z PID 1). W przeciwnym
przypadku, wpis PID dla tej przestrzeni nazw musi wynosić 1.
.SS "Maska znaczników"
\fBclone\fP() i \fBclone3\fP() umożliwiają użycie maski bitowej znaczników, które
modyfikują ich zachowanie i pozwalają wywołującemu na określenie tego, co ma
być dzielone między procesem wywołującym a potomnym. Maska bitowa \[em]
argument \fIflags\fP \fBclone\fP() lub pole \fIcl_args.flags\fP przekazywane do
\fBclone3\fP() \[em] jest nazywana w pozostałem części niniejszego podręcznika
maską \fIflags\fP.
.PP
Maskę \fIflags\fP można podać jako sumę bitową (OR) zera lub więcej z
poniższych zmiennych. Poza wskazanymi wyjątkami, znaczniki te są dostępne (i
mają takie samo zastosowanie) w \fBclone\fP() i \fBclone3\fP().
.TP 
\fBCLONE_CHILD_CLEARTID\fP (od Linuksa 2.5.49)
Czyści (zeruje) identyfikator wątku potomnego w położeniu, na które wskazuje
\fIchild_tid\fP (\fBclone\fP()) lub \fIcl_args.child_tid\fP (\fBclone3\fP()) w pamięci
potomka, gdy potomek istnieje i wybudza zatrzask (mutex) pod tym
adresem. Adres można zmienić wywołaniem systemowym
\fBset_tid_address\fP(2). Używane przez biblioteki związane z wątkami.
.TP 
\fBCLONE_CHILD_SETTID\fP (od Linuksa 2.5.49)
Przechowuje identyfikator wątku potomnego w położeniu, na które wskazuje
\fIchild_tid\fP (\fBclone\fP()) lub \fIcl_args.child_tid\fP (\fBclone3\fP()) w pamięci
potomka. Operacja przechowania kończy się przed zwróceniem kontroli przez
wywołanie clone do przestrzeni użytkownika w procesie potomnym (proszę
zauważyć, że operacja przechowania może nie zakończyć się przed powrotem
przez wywołanie clone do procesu macierzystego, co ma znaczenie, jeśli używa
się również znacznika \fBCLONE_VM\fP).
.TP 
\fBCLONE_CLEAR_SIGHAND\fP (od Linuksa 5.5)
.\" commit b612e5df4587c934bd056bf05f4a1deca4de4f75
Domyślnie, dyspozycje sygnału w wątku potomnym są takie same jak w wątku
macierzystym. Przy podaniu tego znacznika, wszystkie sygnały, które są
obsługiwane przez wątek macierzysty są resetowane do swych domyślnych
dyspozycji (\fBSIG_DFL\fP) w potomku.
.IP
Podanie tego znacznika razem z \fBCLONE_SIGHAND\fP jest bezsensowne i
niedozwolone.
.TP 
\fBCLONE_DETACHED\fP (historyczny)
.\" added in Linux 2.5.32; removed in Linux 2.6.0-test4
Przez pewien czas (w trakcie serii rozwojowej Linuksa 2.5) istniał znacznik
\fBCLONE_DETACHED\fP, który powodował nieotrzymywanie przez rodzica sygnału
przy przerwaniu potomka. Ostatecznie, efekt tego znacznika został włączony
do znacznika \fBCLONE_THREAD\fP i w momencie wydania Linuksa 2.6.0, znacznik
już nie działał. Począwszy od Linuksa 2.6.2, potrzeba podawania tego
znacznika razem z \fBCLONE_THREAD\fP zanikła.
.IP
Znacznik jest wciąż zdefiniowany, lecz z reguły jest ignorowany przy
wywoływaniu \fBclone\fP(). Pewne wyjątki opisano przy znaczniku \fBCLONE_PIDFD\fP.
.TP 
\fBCLONE_FILES\fP (od Linuksa 2.0)
Jeśli \fBCLONE_FILES\fP będzie ustawione, to proces wywołujący i proces potomny
będą współdzielić tablicę deskryptorów plików. Dowolny deskryptor pliku
utworzony przez proces wywołujący, jak też przez proces potomny będzie
obowiązywać również w drugim procesie. Podobnie, jeśli jeden z procesów
zamknie deskryptor pliku lub zmieni stowarzyszone z nim znaczniki (za pomocą
operacji \fBF_SETFD\fP \fBfcntl\fP(2)), będzie to obowiązywać również w drugim
procesie. Jeśli proces dzielący tablicę deskryptorów pliku wywoła
\fBexecve\fP(2), to jego tablica deskryptorów pliku zostanie zduplikowana
(przestanie być współdzielona).
.IP
Jeśli \fBCLONE_FILES\fP nie zostanie ustawione, to proces potomny odziedziczy
kopię wszystkich deskryptorów plików otwartych w procesie macierzystym w
chwili wywołania klonowania.  Kolejne operacja otwierające lub zamykające
deskryptory pliku przeprowadzone później przez proces wywołujący lub przez
proces potomny nie będą miały wpływu na drugi proces. Proszę jednak
zauważyć, że zduplikowane deskryptory pliku w potomku odnoszą się tych samym
opisów otwartego pliku (ODF) jak odpowiadające im deskryptory pliku w
procesie wywołującym; będą zatem dzielić przesunięcie pliku i znaczniki
statusu pliku (zob. \fBopen\fP(2)).
.TP 
\fBCLONE_FS\fP (od Linuksa 2.0)
Jeśli ustawione będzie \fBCLONE_FS\fP, to wywołujący i proces potomny będą
współdzielić informacje o systemie plików. Informacje te obejmują katalog
główny systemu plików, bieżący katalog roboczy i umaskę. Dowolne z wywołań
\fBchroot\fP(2), \fBchdir\fP(2) lub \fBumask\fP(2) wykonane przez proces wywołujący
lub proces potomny będzie wpływać również na drugi proces.
.IP
Jeśli \fBCLONE_FS\fP nie zostanie ustawione, to proces potomny będzie pracować
na kopii informacji o systemie plików procesu wywołującego z chwili
wywołania klonowania. Wywołania \fBchroot\fP(2), \fBchdir\fP(2) lub \fBumask\fP(2)
wykonane później przez jeden z procesów nie będą mieć wpływu na drugi
proces.
.TP 
\fBCLONE_INTO_CGROUP\fP (od Linuksa 5.7)
.\" commit ef2c41cf38a7559bbf91af42d5b6a4429db8fc68
Domyślnie, proces potomny jest umieszczany w tej samej grupie kontrolnej
(cgroup) w wersji 2, jak rodzic. Znacznik \fBCLONE_INTO_CGROUP\fP pozwala na
utworzenie procesu potomnego w innej grupie kontrolnej w wersji 2 (proszę
zauważyć, że \fBCLONE_INTO_CGROUP\fP dotyczy tylko grup kontrolnych w wersji
2).
.IP
Aby umieścić proces potomny w innej grupie kontrolnej, wywołujący określa
\fBCLONE_INTO_CGROUP\fP w \fIcl_args.flags\fP i przekazuje deskryptor pliku, który
odnosi się do grupy kontrolnej w wersji 2 w polu \fIcl_args.cgroup\fP (ten
deskryptor pliku można uzyskać otwierając katalog grupy kontrolnej v2, za
pomocą znacznika \fBO_RDONLY\fP lub \fBO_PATH\fP). Proszę zauważyć, że obowiązują
wszystkie zwykłe ograniczenia na umieszczanie procesu w grupie kontrolnej w
wersji 2 (opisane w \fBcgroups\fP(7)).
.IP
Pośród możliwych zastosowań \fBCLONE_INTO_CGROUP\fP są następujące:
.RS
.IP \[bu] 3
Utworzenie procesu w grupie kontrolnej innej niż grupa kontrolna rodzica,
umożliwia menedżerowi usług bezpośrednie tworzenie nowych usług w
oddzielnych grupach kontrolnych. Eliminuje się w ten sposób narzut
księgowania, który spowodowany byłby tworzeniem procesu potomnego pierwotnie
w tej samej grupie kontrolnej co rodzic, a dopiero później przenoszenie go
do docelowej grupy kontrolnej. Co więcej, tworzenie procesu potomnego od
razu w docelowej grupie kontrolnej jest zdecydowanie tańsze, niż
przenoszenie procesu potomnego do docelowej grupy kontrolnej dopiero po
utworzeniu.
.IP \[bu]
Znacznik \fBCLONE_INTO_CGROUP\fP pozwala również na utworzenie zamrożonego
procesu potomnego, przez utworzenie go w zamrożonej grupie kontrolnej
(zob. \fBcgroups\fP(7) aby dowiedzieć się więcej o kontrolerze freezer).
.IP \[bu]
W przypadku aplikacji korzystających z wątków (lub choćby implementacji
wątków korzystających z grup kontrolnych do limitowania poszczególnych
wątków), da się ustanowić ustalony schemat grupy kontrolnej, przed
utworzeniem każdego wątku bezpośrednio w jego docelowej grupie kontrolnej.
.RE
.TP 
\fBCLONE_IO\fP (od Linuksa 2.6.25)
Jeśli \fBCLONE_IO\fP jest ustawiony, to nowy proces dzieli kontekst
wejścia/wyjścia z procesem wywołującym. Jeśli znacznik nie jest ustawiony,
to (jak przy \fBfork\fP(2)) nowy proces posiada swój kontekst wejścia/wyjścia.
.IP
.\" The following based on text from Jens Axboe
.\" the anticipatory and CFQ scheduler
.\" with CFQ and AS.
Kontekst wejścia/wyjścia (we/wy) jest zakresem we/wy planisty dysku
(tj. tym, co planista we/wy używa do planowania we/wy procesu). Jeśli
procesy dzielą ten sam kontekst we/wy, to są traktowane jako jedność przez
planistę we/wy. Muszą zatem dzielić czas dysku. W przypadku pewnych
planistów we/wy, jeśli dwa procesy dzielą kontekst we/wy, to pozwala się im
na przeplatanie dostępu do dysku. Jeśli wiele wątków korzysta z we/wy w
imieniu jakiegoś procesu (np. \fBaio_read\fP(3)), to aby uzyskać lepszą
wydajność wejścia/wyjścia, powinny korzystać z \fBCLONE_IO\fP.
.IP
Jeśli jądra nie skonfigurowano z opcją \fBCONFIG_BLOCK\fP, to ten znacznik nie
daje żadnego efektu.
.TP 
\fBCLONE_NEWCGROUP\fP (od Linuksa 4.6)
Tworzy proces w nowej przestrzeni nazw cgroup. Jeśli znacznik nie jest
ustawiony (jak w przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej
przestrzeni nazw cgroup, co proces wywołujący.
.IP
Więcej informacji o przestrzeniach nazw cgroup znajduje się w podręczniku
\fBcgroup_namespaces\fP(7).
.IP
.\"
Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć
\fBCLONE_NEWCGROUP\fP.
.TP 
\fBCLONE_NEWIPC\fP (od Linuksa 2.6.19)
Jeśli \fBCLONE_NEWIPC\fP jest ustawiony, to proces jest tworzony w nowej
przestrzeni nazw IPC. Jeśli znacznik nie jest ustawiony (jak w przypadku
\fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw IPC, co
proces wywołujący.
.IP
Więcej informacji o przestrzeniach nazw IPC znajduje się w podręczniku
\fBipc_namespaces\fP(7).
.IP
Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć
\fBCLONE_NEWIPC\fP. Niniejszy znacznik nie może być podany razem z
\fBCLONE_SYSVSEM\fP.
.TP 
\fBCLONE_NEWNET\fP (od Linuksa 2.6.24)
(Implementacja tej flagi została ukończona dopiero w okolicy Linuksa
2.6.29).
.IP
Jest \fBCLONE_NEWNET\fP jest ustawiony, to proces jest tworzony w nowej
przestrzeni nazw sieci. Jeśli znacznik nie jest ustawiony (jak w przypadku
\fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw sieci, co
proces wywołujący.
.IP
Więcej informacji o przestrzeniach nazw sieci znajduje się w podręczniku
\fBnetwork_namespaces\fP(7).
.IP
Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć \fBCLONE_NEWNET\fP.
.TP 
\fBCLONE_NEWNS\fP (od Linuksa 2.4.19)
Jeśli ustawiono \fBCLONE_NEWNS\fP, sklonowany potomek jest uruchamiany w nowej
przestrzeni nazw montowań, inicjowanej jako kopia przestrzeni nazw
rodzica. Jeśli nie ustawiono \fBCLONE_NEWNS\fP, to potomek istnieje w tej samej
przestrzeni nazw montowań, co rodzic.
.IP
Więcej informacji o przestrzeniach nazw montowań znajduje się w
podręcznikach \fBnamespaces\fP(7) i \fBmount_namespaces\fP(7).
.IP
.\" See https://lwn.net/Articles/543273/
Znacznik \fBCLONE_NEWNS\fP może zostać użyty jedynie przez proces
uprzywilejowany (\fBCAP_SYS_ADMIN\fP). Zabronione jest podanie w tym samym
wywołaniu klonowania zarówno \fBCLONE_NEWNS\fP, jak i \fBCLONE_FS\fP.
.TP 
\fBCLONE_NEWPID\fP (od Linuksa 2.6.24)
.\" This explanation draws a lot of details from
.\" http://lwn.net/Articles/259217/
.\" Authors: Pavel Emelyanov <xemul@openvz.org>
.\" and Kir Kolyshkin <kir@openvz.org>
.\"
.\" The primary kernel commit is 30e49c263e36341b60b735cbef5ca37912549264
.\" Author: Pavel Emelyanov <xemul@openvz.org>
Jest \fBCLONE_NEWPID\fP jest ustawiony, to proces jest tworzony w nowej
przestrzeni nazw PID. Jeśli znacznik nie jest ustawiony (jak w przypadku
\fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw PID, co
proces wywołujący.
.IP
Więcej informacji o przestrzeniach nazw PID znajduje się w podręcznikach
\fBnamespaces\fP(7) i \fBpid_namespaces\fP(7).
.IP
Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć
\fBCLONE_NEWPID\fP. Niniejszy znacznik nie może być podany razem z
\fBCLONE_THREAD\fP ani \fBCLONE_PARENT\fP.
.TP 
\fBCLONE_NEWUSER\fP
(Flaga ta nabrała znaczenia dla \fBclone\fP() w Linuksie 2.6.23, bieżąca
semantyka \fBclone\fP() pojawiła się w Linuksie 3.5, a ostatnie elementy dające
pełną funkcjonalność przestrzeni nazw użytkownika ukończono w Linuksie 3.8).
.IP
Jest \fBCLONE_NEWUSER\fP jest ustawiony, to proces jest tworzony w nowej
przestrzeni nazw użytkownika. Jeśli znacznik nie jest ustawiony (jak w
przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw
użytkownika, co proces wywołujący.
.IP
Więcej informacji o przestrzeniach nazw użytkownika znajduje się w
podręcznikach \fBnamespaces\fP(7) i \fBuser_namespaces\fP(7).
.IP
.\" Before Linux 2.6.29, it appears that only CAP_SYS_ADMIN was needed
Przed Linuksem 3.8, użycie \fBCLONE_NEWUSER\fP wymagało posiadania trzech
przywilejów (ang. capabilities) przez wywołującego: \fBCAP_SYS_ADMIN\fP,
\fBCAP_SETUID\fP i \fBCAP_SETGID\fP. Od Linuksa 3.8, do utworzenia przestrzeni
nazw użytkownika nie są wymagane przywileje.
.IP
.\" commit e66eded8309ebf679d3d3c1f5820d1f2ca332c71
.\" https://lwn.net/Articles/543273/
.\" The fix actually went into Linux 3.9 and into Linux 3.8.3. However, user namespaces
.\" were, for practical purposes, unusable in earlier Linux 3.8.x because of the
.\" various filesystems that didn't support userns.
Znacznika tego nie można podać razem z \fBCLONE_THREAD\fP lub
\fBCLONE_PARENT\fP. Ze względów bezpieczeństwa, \fBCLONE_NEWUSER\fP nie można
podać razem z \fBCLONE_FS\fP.
.TP 
\fBCLONE_NEWUTS\fP (od Linuksa 2.6.19)
Jest \fBCLONE_NEWUTS\fP jest ustawiony, to proces jest tworzony w nowej
przestrzeni nazw UTS, której identyfikatory są inicjowane przez
zduplikowanie identyfikatorów z przestrzeni nazw UTS procesu
wywołującego. Jeśli znacznik nie jest ustawiony (jak w przypadku
\fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw UTS, co
proces wywołujący.
.IP
Więcej informacji o przestrzeniach nazw UTS znajduje się w podręczniku
\fButs_namespaces\fP(7).
.IP
Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć \fBCLONE_NEWUTS\fP.
.TP 
\fBCLONE_PARENT\fP (od Linuksa 2.3.12)
Jeśli \fBCLONE_PARENT\fP będzie ustawione, to rodzic nowego procesu potomnego
(zwrócony przez \fBgetppid\fP(2)) będzie ten sam, co dla procesu wywołującego.
.IP
Jeśli \fBCLONE_PARENT\fP nie zostanie ustawione, to (jak dla \fBfork\fP(2))
rodzicem potomka będzie proces wywołujący.
.IP
Należy zauważyć, że to proces macierzysty, zwracany przez \fBgetppid\fP(2),
zostanie powiadomiony o zakończeniu pracy przez potomka, więc jeśli
\fBCLONE_PARENT\fP będzie ustawione, to zawiadomiony zostanie rodzic procesu
wywołującego, a nie sam proces wywołujący.
.IP
Znacznika \fBCLONE_PARENT\fP nie można użyć w wywołaniach klonowania przez
globalny proces init (o PID 1 w pierwotnej przestrzeni nazw PID) oraz
procesy init w innych przestrzeniach nazw PID. To ograniczenie zapobiega
tworzeniu zakorzenionych w wielu miejscach drzew procesów oraz tworzeniu
zombie w pierwotnej przestrzeni nazw, których nie da się dorżnąć
(unreapable).
.TP 
\fBCLONE_PARENT_SETTID\fP (od Linuksa 2.5.49)
Przechowuje identyfikator wątku potomka w położeniu, na które wskazuje
\fIparent_tid\fP (\fBclone\fP()) lub \fIcl_args.parent_tid\fP (\fBclone3\fP()) w pamięci
rodzica (w Linuksie 2.5.32\-2.5.48 istniał znacznik \fBCLONE_SETTID\fP, który
działał w ten sam sposób). Operacja przechowania kończy się, przed
zwróceniem kontroli do przestrzeni użytkownika przez wywołanie klonowania.
.TP 
\fBCLONE_PID\fP (od Linuksa 2.0 do Linuksa 2.5.15)
Jeśli \fBCLONE_PID\fP jest ustawiony, to proces potomny jest tworzony z tym
samym identyfikatorem jak proces wywołujący. Trudno wymyślić jego przydatne
zastosowanie, poza hakowaniem systemu. Od Linuksa 2.3.21, ten znacznik mógł
być podany tylko przez systemowy proces rozruchu (PID 0). Znacznik zupełnie
zniknął ze źródeł jądra w Linuksie 2.5.16. Następnie jądro po cichu
ignorowało ten bit, gdy był podany w masce \fIflags\fP. Znacznie później, ten
sam bit użyto do znacznika \fBCLONE_PIDFD\fP.
.TP 
\fBCLONE_PIDFD\fP (od Linuksa 5.2)
.\" commit b3e5838252665ee4cfa76b82bdf1198dca81e5be
Jeśli znacznik jest podany, to deskryptor pliku PID odnoszącego się do
procesu potomnego jest alokowany i umieszczany w określonym położeniu
pamięci rodzica. Na tym nowym deskryptorze pliku ustawiany jest znacznik
zamknij\-przy\-wykonaniu. Deskryptory pliku PID można wykorzystać w celach
opisanych w podręczniku \fBpidfd_open\fP(2).
.RS
.IP \[bu] 3
Jeśli korzysta się z \fBclone3\fP(), to deskryptor pliku PID jest umieszczany w
położeniu, na które wskazuje \fIcl_args.pidfd\fP.
.IP \[bu]
Jeśli korzysta się z \fBclone\fP(), to deskryptor pliku PID jest umieszczany w
położeniu, na które wskazuje \fIparent_tid\fP. Ponieważ argument \fIparent_tid\fP
jest używany do zwrócenia deskryptora pliku PID, nie można użyć
\fBCLONE_PIDFD\fP razem z \fBCLONE_PARENT_SETTID\fP przy wywoływaniu \fBclone\fP().
.RE
.IP
Nie da się obecnie korzystać z tego znacznika razem z
\fBCLONE_THREAD\fP. Oznacza to, że proces identyfikowany przez deskryptor pliku
PID będzie zawsze liderem grupy wątków.
.IP
Jeśli przestarzały znacznik \fBCLONE_DETACHED\fP poda się razem z
\fBCLONE_PIDFD\fP przy wywoływaniu \fBclone\fP(), to zwracany jest błąd. Błąd
występuje również jeśli poda się \fBCLONE_DETACHED\fP przy wywoływaniu
\fBclone3\fP(). Zwracanie błędu zapewnia, że bit odnoszący się do
\fBCLONE_DETACHED\fP może być w przyszłości użyty ponownie do następnych
funkcji deskryptora pliku PID.
.TP 
\fBCLONE_PTRACE\fP (od Linuksa 2.2)
Jeśli zostanie podane \fBCLONE_PTRACE\fP, a proces wywołujący będzie śledzony,
to śledzenie obejmie również potomka (zobacz \fBptrace\fP(2)).
.TP 
\fBCLONE_SETTLS\fP (od Linuksa 2.5.32)
Deskryptor TLS (Thread Local Storage \[em] pamięć lokalna wątku) jest
ustawiony na \fItls\fP.
.IP
The interpretation of \fItls\fP and the resulting effect is architecture
dependent.  On x86, \fItls\fP is interpreted as a \fIstruct user_desc\~*\fP (see
\fBset_thread_area\fP(2)).  On x86\-64 it is the new value to be set for the %fs
base register (see the \fBARCH_SET_FS\fP argument to \fBarch_prctl\fP(2)).  On
architectures with a dedicated TLS register, it is the new value of that
register.
.IP
Znacznik ten wymaga szczegółowej wiedzy i zwykle nie powinno się go używać
poza bibliotekami implementującymi wątkowanie.
.TP 
\fBCLONE_SIGHAND\fP (od Linuksa 2.0)
Jeśli \fBCLONE_SIGHAND\fP będzie ustawione, to proces wywołujący i procesy
potomne będą współdzielić tablicę programów obsługi sygnałów. Jeśli proces
wywołujący lub proces potomny wywoła \fBsigaction\fP(2), aby zmienić zachowanie
towarzyszące sygnałowi, zachowanie to zostanie zmienione również w drugim
procesie. Jednakże, proces wywołujący i proces potomny wciąż będą posiadać
osobne maski sygnałów i zestawy sygnałów oczekujących. Zatem jeden z nich
może zablokować lub odblokować niektóre sygnały za pomocą \fBsigprocmask\fP(2)
nie wpływając na drugi proces.
.IP
Jeśli \fBCLONE_SIGHAND\fP nie zostanie ustawione, to proces potomny odziedziczy
kopię programów obsługi sygnałów od procesu wywołującego z chwili wywołania
klonowania. Wywołania \fBsigaction\fP(2) przeprowadzone później przez jeden z
procesów nie będą mieć wpływu na drugi proces.
.IP
.\" Precisely: Linux 2.6.0-test6
Od Linuksa 2.6.0, maska \fIflags\fP musi również zawierać \fBCLONE_VM\fP, jeśli
podano \fBCLONE_SIGHAND\fP.
.TP 
\fBCLONE_STOPPED\fP (od Linuksa 2.6.0)
.\" Precisely: Linux 2.6.0-test2
Jeśli \fBCLONE_STOPPED\fP jest ustawione, to potomek jest początkowo zatrzymany
(jakby otrzymał sygnał \fBSIGSTOP\fP) i musi być wznowiony sygnałem \fBSIGCONT\fP.
.IP
.\" glibc 2.8 removed this defn from bits/sched.h
Znacznik był oznaczony jako \fIprzestarzały\fP od Linuksa 2.6.25 i został
zupełnie \fIusunięty\fP w Linuksie 2.6.38. Od tego czasu jądro po cichu
ignoruje go, nie wypisując błędu. Od Linuksa 4.6, ten sam bit służy
znacznikowi \fBCLONE_NEWCGROUP\fP.
.TP 
\fBCLONE_SYSVSEM\fP (od Linuksa 2.5.10)
Jeśli ustawiony jest \fBCLONE_SYSVSEM\fP to potomek i proces wywołujący dzielą
jedną listę wartości dostosowań semaforów Systemu V (\fIsemadj\fP;
zob. \fBsemop\fP(2)). W tym przypadku wspólna lista zbiera wartości \fIsemadj\fP
ze wszystkich procesów dzielących listę, a dostosowania semaforów są
wykonywane tylko gdy ostatni proces dzielący listę zostanie zakończony (lub
przestanie dzielić listę, za pomocą \fBunshare\fP(2)). Jeśli znacznik ten nie
jest ustawiony, to potomek posiada oddzielną listę \fIsemadj\fP, która
początkowo jest pusta.
.TP 
\fBCLONE_THREAD\fP (od Linuksa 2.4.0)
.\" Precisely: Linux 2.6.0-test8
Jeśli ustawiony jest \fBCLONE_THREAD\fP to potomek jest umieszczany w tej samej
grupie wątków, co proces wywołujący. Aby dalsza część opisu \fBCLONE_THREAD\fP
była bardziej przejrzysta, termin \[Bq]wątek\[rq] oznaczać będzie tu procesy
w grupie wątków.
.IP
Grupy wątków zostały dodane w Linuksie 2.4 do obsługi wątków POSIX dla
zbioru procesów współdzielących ten sam PID. Wewnętrznie, ten wspólny PID
jest tzw. identyfikatorem grupy wątków (ang. thread group ID \[em] TGID) dla
grupy wątków. Od Linuksa 2.4 wywołania \fBgetpid\fP(2) zwracają TGID
wywołującego.
.IP
Wątki wewnątrz grupy można rozróżnić za pomocą ich unikatowego (w systemie)
identyfikatora wątku (ang. thread ID \[em] TID). TID nowego wątku jest
dostępny jako wynik funkcji zwracany do wywołującego, a sam wątek może
uzyskać swój TID za pomocą \fBgettid\fP(2).
.IP
Gdy wywołanie clone ma miejsce bez podania \fBCLONE_THREAD\fP, to wynikowy
wątek jest umieszczany w nowej grupie wątków, której TGID jest taki sam jak
TID wątku. Wątek ten staje się \fIliderem\fP nowej grupy wątków.
.IP
Nowy wątek utworzony przy podaniu \fBCLONE_THREAD\fP ma ten sam proces
macierzysty jak proces, który wykonał wywołanie klonowania (tj. jak
\fBCLONE_PARENT\fP), tak więc wywołanie \fBgetppid\fP(2) zwróci tę samą wartość
dla wszystkich wątków w grupie wątków. Gdy wątek z \fBCLONE_THREAD\fP zostanie
zakończony, wątek który go utworzył nie otrzymuje sygnału \fBSIGCHLD\fP (ani
innego sygnału przerwania); statusu takiego wątku nie da się również
pozyskać za pomocą \fBwait\fP(2) (taki wątek jest nazywany \fIoddzielonym\fP \[em]
ang. detached).
.IP
Po tym, jak wszystkie wątki w grupie wątków zakończą się, proces macierzysty
grupy wątków otrzymuje sygnał \fBSIGCHLD\fP (lub inny sygnał przerwania).
.IP
Jeśli któryś z wątków w grupie wątków wykona \fBexecve\fP(2), to wszystkie
wątki poza liderem grupy wątków są zakańczane i nowy program wykonywany jest
przez lidera grupy wątków.
.IP
Jeśli jeden z wątków w grupie wątków tworzy potomka za pomocą \fBfork\fP(2), to
każdy wątek w grupie może czekać (\fBwait\fP(2)) na tego potomka.
.IP
.\" Precisely: Linux 2.6.0-test6
Od Linuksa 2.5.35, maska \fIflags\fP musi zawierać również \fBCLONE_SIGHAND\fP
jeśli podano \fBCLONE_THREAD\fP (i proszę zauważyć, że od Linuksa 2.6.0,
\fBCLONE_SIGHAND\fP wymaga również zamieszczenia \fBCLONE_VM\fP).
.IP
Akcje i dyspozycje sygnałów mają znaczenie dla całego procesu: jeśli do
wątku dostarczony zostanie nieobsłużony sygnał, to dotknie on (przerwie,
zatrzyma, wznowi, ustawi ignorowanie) wszystkich członków grupy wątków.
.IP
Każdy wątek ma swoją maskę sygnałów, jak ustawianą przez \fBsigprocmask\fP(2).
.IP
Sygnał może być kierowany do procesu lub kierowany do wątku. Sygnał
kierowany do procesu jest przeznaczony do grupy wątku (tj. TGID) i jest
dostarczany do dowolnie wybranego wątku spośród tych, które nie blokują
sygnału. Sygnał może być kierowany do procesu, ponieważ został wygenerowany
przez jądro z powodów innych niż wyjątek sprzętowy, albo ponieważ został
wysłany za pomocą \fBkill\fP(2) lub \fBsigqueue\fP(3). Sygnał kierowany do wątku
jest przeznaczony (tj. dostarczany) do określonego wątku. Sygnał może być
kierowany do wątku, ponieważ został wysłany za pomocą \fBtgkill\fP(2) lub
\fBpthread_sigqueue\fP(3), albo ponieważ wątek wykonał instrukcję języka
maszynowego, która wyzwoliła wyjątek sprzętowy (np. nieprawidłowy dostęp do
pamięci wyzwalający \fBSIGSEGV\fP lub wyjątek zmiennoprzecinkowy wyzwalający
\fBSIGFPE\fP).
.IP
Wywołanie do \fBsigpending\fP(2) zwraca sygnał, który jest ustawiany na sumę
oczekującego sygnału skierowanego do procesu oraz sygnałów które są
oczekujące dla wątku wywołującego.
.IP
Jeśli sygnał kierowany do procesu zostanie dostarczony do grupy wątków, a
grupa ta ma zainstalowaną procedurę obsługi sygnału, to jest ona wywoływana
w dokładnie jednym, dowolnie wybranym członku grupy wątków, który nie
zablokował sygnału. Jeśli na zaakceptowanie tego samego sygnału za pomocą
\fBsigwaitinfo\fP(2) czeka wiele wątków w grupie, to jądro wybierze w sposób
dowolny jeden z wątków, który otrzyma sygnał.
.TP 
\fBCLONE_UNTRACED\fP (od Linuksa 2.5.46)
Jeśli podano \fBCLONE_UNTRACED\fP, to proces śledzący nie może wymusić
\fBCLONE_PTRACE\fP na tym procesie potomnym.
.TP 
\fBCLONE_VFORK\fP (od Linuksa 2.2)
Jeśli \fBCLONE_VFORK\fP będzie ustawione, wykonywanie procesu wywołującego
zostanie wstrzymane do chwili, gdy potomek zwolni swoją pamięć wirtualną za
pomocą \fBexecve\fP(2) lub \fB_exit\fP(2) (jak w przypadku \fBvfork\fP(2)).
.IP
Jeśli \fBCLONE_VFORK\fP nie zostanie ustawione, wtedy zarówno proces
wywołujący, jak i potomny podlegają po wywołaniu \fBclone\fP szeregowaniu zadań
i aplikacja nie może zakładać, że ich wykonywanie będzie się odbywać w
określonej kolejności.
.TP 
\fBCLONE_VM\fP (od Linuksa 2.0)
Jeśli \fBCLONE_VM\fP będzie ustawione, to proces wywołujący i potomny będą
działać w tym samym obszarze pamięci. W szczególności, zapisy do pamięci
wykonywane przez proces wywołujący lub przez proces potomny będą widoczne
dla drugiego z procesów. Ponadto, dowolne mapowania pamięci i usunięcia
mapowań wykonane przez jeden z tych procesów za pomocą \fBmmap\fP(2) lub
\fBmunmap\fP(2) będą dotyczyć również drugiego procesu.
.IP
Jeśli \fBCLONE_VM\fP nie zostanie ustawione, to proces potomny będzie działać w
kopii obszaru pamięci procesu wywołującego, wykonanej w chwili wywołania
klonowania. Zapisy do pamięci oraz mapowania i usunięcia mapowań wykonane
przez jeden z tych procesów nie będą dotyczyć drugiego z nich, tak jak w
przypadku \fBfork\fP(2).
.IP
Jeśli podano znacznik \fBCLONE_VM\fP, a nie podano znacznika \fBCLONE_VFORK\fP to
wszystkie alternatywne stosy sygnałów ustanowione przez \fBsigaltstack\fP(2) są
czyszczone w procesie potomnym.
.SH "WARTOŚĆ ZWRACANA"
.\" gettid(2) returns current->pid;
.\" getpid(2) returns current->tgid;
Po pomyślnym zakończeniu, w wątku rodzica zwracany jest identyfikator wątku
potomka. W wypadku błędu, w kontekście procesu wywołującego zwracane jest
\-1, a proces potomny nie jest tworzony i ustawiane jest \fIerrno\fP wskazując
błąd.
.SH BŁĘDY
.TP 
\fBEACCES\fP (tylko \fBclone3\fP())
W \fIcl_args.flags\fP podano \fBCLONE_INTO_CGROUP\fP, nie spełniono ograniczeń
(opisanych w \fBcgroups\fP(7)), w odniesieniu do \fIcl_args.cgroup\fP, dotyczących
umieszczania procesu potomnego w grupie kontrolnej w wersji 2.
.TP 
\fBEAGAIN\fP
Działa już zbyt wiele procesów; zob. \fBfork\fP(2).
.TP 
\fBEBUSY\fP (tylko \fBclone3\fP())
W \fIcl_args.flags\fP podano \fBCLONE_INTO_CGROUP\fP, lecz deskryptor pliku podany
w \fIcl_args.cgroup\fP odnosi się do grupy kontrolnej w wersji 2, w której
włączony jest kontroler domeny.
.TP 
\fBEEXIST\fP (tylko \fBclone3\fP())
Jeden (lub więcej) PID podany w \fIset_tid\fP już istnieje w odpowiedniej
przestrzeni nazw PID.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano jednocześnie \fBCLONE_SIGHAND\fP i
\fBCLONE_CLEAR_SIGHAND\fP.
.TP 
\fBEINVAL\fP
.\" Precisely: Linux 2.6.0-test6
W masce \fIflags\fP podano \fBCLONE_SIGHAND\fP, lecz nie podano \fBCLONE_VM\fP (od
Linuksa 2.6.0).
.TP 
\fBEINVAL\fP
.\" .TP
.\" .B EINVAL
.\" Precisely one of
.\" .B CLONE_DETACHED
.\" and
.\" .B CLONE_THREAD
.\" was specified.
.\" (Since Linux 2.6.0-test6.)
W masce \fIflags\fP podano \fBCLONE_THREAD\fP, lecz nie podano \fBCLONE_SIGHAND\fP
(od Linuksa 2.5.35).
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano \fBCLONE_THREAD\fP, lecz bieżący proces użył uprzednio
\fBunshare\fP(2) ze znacznikiem \fBCLONE_NEWPID\fP lub użył \fBsetns\fP(2) do
ponownego związania się z przestrzenią nazw PID.
.TP 
\fBEINVAL\fP
.\" commit e66eded8309ebf679d3d3c1f5820d1f2ca332c71
W masce \fIflags\fP podano jednocześnie \fBCLONE_FS\fP i \fBCLONE_NEWNS\fP.
.TP 
\fBEINVAL\fP (od Linuksa 3.9)
W masce \fIflags\fP podano jednocześnie \fBCLONE_NEWUSER\fP i \fBCLONE_FS\fP.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano jednocześnie \fBCLONE_NEWIPC\fP i \fBCLONE_SYSVSEM\fP.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano jeden (lub oba) z \fBCLONE_NEWPID\fP lub
\fBCLONE_NEWUSER\fP i jeden (lub oba) z \fBCLONE_THREAD\fP lub \fBCLONE_PARENT\fP.
.TP 
\fBEINVAL\fP (od Linuksa 2.6.32)
.\" commit 123be07b0b399670a7cc3d82fef0cb4f93ef885c
Podano \fBCLONE_PARENT\fP, a wywołujący jest procesem init.
.TP 
\fBEINVAL\fP
Zwracane przez funkcję opakowującą \fBclone\fP() z glibc, gdy \fIfn\fP lub
\fIstack\fP określono jako NULL.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano \fBCLONE_NEWIPC\fP, lecz jądro nie zostało
skonfigurowane z opcjami \fBCONFIG_SYSVIPC\fP i \fBCONFIG_IPC_NS\fP.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano \fBCLONE_NEWNET\fP, lecz jądro nie zostało
skonfigurowane z opcją \fBCONFIG_NET_NS\fP.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano \fBCLONE_NEWPID\fP, lecz jądro nie zostało
skonfigurowane z opcją \fBCONFIG_PID_NS\fP.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, lecz jądro nie zostało
skonfigurowane z opcją \fBCONFIG_USER_NS\fP.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano \fBCLONE_NEWUTS\fP, lecz jądro nie zostało
skonfigurowane z opcją \fBCONFIG_UTS_NS\fP.
.TP 
\fBEINVAL\fP
Stos \fIstack\fP nie jest wyrównany do odpowiedniej granicy na tej
architekturze. Przykładowo na aarch64, \fIstack\fP musi być wielokrotnością 16.
.TP 
\fBEINVAL\fP (tylko \fBclone3\fP())
W masce \fIflags\fP podano \fBCLONE_DETACHED\fP.
.TP 
\fBEINVAL\fP (tylko \fBclone\fP())
W masce \fIflags\fP podano \fBCLONE_PIDFD\fP jednocześnie z \fBCLONE_DETACHED\fP.
.TP 
\fBEINVAL\fP
W masce \fIflags\fP podano \fBCLONE_PIDFD\fP jednocześnie z \fBCLONE_THREAD\fP.
.TP 
\fBEINVAL\fP (tylko \fBclone\fP())
W masce \fIflags\fP podano \fBCLONE_PIDFD\fP jednocześnie z
\fBCLONE_PARENT_SETTID\fP.
.TP 
\fBEINVAL\fP (tylko \fBclone3\fP())
\fIset_tid_size\fP jest większy od liczby zagnieżdżonych przestrzeni nazw PID.
.TP 
\fBEINVAL\fP (tylko \fBclone3\fP())
Jeden z PID\-ów podanych w \fIset_tid\fP był nieprawidłowy.
.TP 
\fBEINVAL\fP (tylko AArch64, Linux 4.6 i wcześniejsze)
\fIstack\fP nie był wyrównany do granicy 128\-bitów.
.TP 
\fBENOMEM\fP
Za mało pamięci aby przydzielić strukturę zadania dla procesu potomnego, lub
aby skopiować niezbędne fragmenty kontekstu procesu wywołującego.
.TP 
\fBENOSPC\fP (od Linuksa 3.7)
.\" commit f2302505775fd13ba93f034206f1e2a587017929
W masce \fIflags\fP podano \fBCLONE_NEWPID\fP, lecz zostałby przekroczony limit
zagnieżdżenia przestrzeni nazw PID; zob. \fBpid_namespaces\fP(7).
.TP 
\fBENOSPC\fP (od Linuksa 4.9; wcześniej \fBEUSERS\fP)
W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, a wywołanie przekroczyłoby limit
liczby zagnieżdżonych przestrzeni nazw
użytkownika. Zob. \fBuser_namespaces\fP(7).
.IP
Od Linuksa 3.11 do Linuksa 4.8, diagnozowanym w tym przypadku błędem był
\fBEUSERS\fP.
.TP 
\fBENOSPC\fP (od Linuksa 4.9)
Jedna z wartości w masce \fIflags\fP określiła utworzenie nowej przestrzeni
nazw użytkownika, lecz uczynienie tego, spowodowałoby przekroczenie limitu
zdefiniowanego przez odpowiedni plik w \fI/proc/sys/user\fP. Więcej informacji
znajduje się w podręczniku \fBnamespaces\fP(7).
.TP 
\fBEOPNOTSUPP\fP (tylko \fBclone3\fP())
W \fIcl_args.flags\fP podano \fBCLONE_INTO_CGROUP\fP, lecz deskryptor pliku podany
w \fIcl_args.cgroup\fP odnosi się do grupy kontrolnej w wersji 2, która jest w
stanie \fIdomain invalid\fP.
.TP 
\fBEPERM\fP
\fBCLONE_NEWCGROUP\fP, \fBCLONE_NEWIPC\fP, \fBCLONE_NEWNET\fP, \fBCLONE_NEWNS\fP,
\fBCLONE_NEWPID\fP lub \fBCLONE_NEWUTS\fP były określone przez proces
nieuprzywilejowany (proces bez przywileju \fBCAP_SYS_ADMIN\fP).
.TP 
\fBEPERM\fP
\fBCLONE_PID\fP został podany przez proces inny niż proces 0 (błąd ten
występował jedynie do Linuksa 2.5.15).
.TP 
\fBEPERM\fP
W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, lecz ani efektywny identyfikator
użytkownika, ani efektywny identyfikator grupy wywołującego nie jest
przypisany do przestrzeni nazw rodzica (zob. \fBuser_namespaces\fP(7)).
.TP 
\fBEPERM\fP (od Linuksa 3.9)
.\" commit 3151527ee007b73a0ebd296010f1c0454a919c7d
.\" FIXME What is the rationale for this restriction?
W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, a wywołujący znajduje się w
środowisku chroot (tj. główny katalog wywołującego nie jest głównym
katalogiem przestrzeni nazw montowań, w której rezyduje).
.TP 
\fBEPERM\fP (tylko \fBclone3\fP())
\fIset_tid_size\fP był większy niż zero, a wywołujący nie ma przywileju
\fBCAP_SYS_ADMIN\fP w jednej lub większej liczbie przestrzeni nazw użytkownika,
które posiadają odpowiednie przestrzenie nazw PID.
.TP 
\fBERESTARTNOINTR\fP (od Linuksa 2.6.17)
.\" commit 4a2c7a7837da1b91468e50426066d988050e4d56
Wywołanie systemowe przerwano sygnałem i zostanie ono przeładowane (widać to
tylko przy śledzeniu).
.TP 
\fBEUSERS\fP (od Linuksa 3.11 do Linuksa 4.8)
W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, a przekroczono by limit liczby
zagnieżdżonych przestrzeni nazw użytkownika. Zob. opis błędu \fBENOSPC\fP
powyżej.
.SH WERSJE
.\" There is no entry for
.\" .BR clone ()
.\" in libc5.
.\" glibc2 provides
.\" .BR clone ()
.\" as described in this manual page.
Wywołanie systemowe \fBclone3\fP() pojawiło się w Linuksie 5.3.
.SH STANDARDY
Te wywołania systemowe są typowo linuksowe i nie powinny być używane w
programach, które mają być przenośne.
.SH UWAGI
Jednym z zastosowań tych wywołań systemowych jest implementacja wątków:
zarządzanie wieloma przepływami kontroli w programie, które działają
równolegle we współdzielonej przestrzeni adresowej.
.PP
Proszę zauważyć, że funkcja opakowująca \fBclone\fP() z biblioteki glibc czyni
pewne zmiany w pamięci, na którą wskazuje \fIstack\fP (zmiany wymagane do
prawidłowego ustawienia stosu w stosunku do potomka) \fIprzed\fP przywołaniem
wywołania systemowego \fBclone\fP(). Dlatego, w przypadkach gdy \fBclone\fP()
służy do rekurencyjnego tworzenia potomków, nie należy używać bufora w
stosie rodzica, jako stosu potomka.
.PP
Wywołanie systemowe \fBkcmp\fP(2) może posłużyć do sprawdzenia, czy dwa procesy
współdzielą różne zasoby, takie jak tablica deskryptorów pliku, operacje
cofnięć semaforów Systemu V lub wirtualną przestrzeń adresową.
.PP
Uchwyty zarejestrowane przy pomocy \fBpthread_atfork\fP(3) nie są wykonywane
przy wywołaniu klonowania.
.PP
W serii Linuksa 2.4.x, \fBCLONE_THREAD\fP zwykle nie czyniło rodzicem nowego
wątku rodzica procesu wywołującego. Jednak od Linuksa 2.4.7 do Linuksa
2.4.18 znacznik \fBCLONE_THREAD\fP implikował znacznik \fBCLONE_PARENT\fP (jak ma
to miejsce od Linuksa 2.6.0).
.PP
.\"
Na i386, nie należy wywoływać \fBclone\fP() za pomocą vsyscall; powinno się to
robić bezpośrednio, poprzez \fIint $0x80\fP.
.SS "Różnice biblioteki C/jądra"
Surowe wywołanie systemowe \fBclone\fP() jest bliższe \fBfork\fP(2) w tym
zakresie, że wykonanie procesu potomnego jest kontynuowane od miejsca
wywołania. Dlatego argumenty \fIfn\fP i \fIarg\fP funkcji opakowującej \fBclone\fP()
są pominięte.
.PP
W odróżnienie od opakowania z glibc, surowe wywołanie systemowe \fBclone\fP()
jako argument \fIstack\fP akceptuje NULL (a \fBclone3\fP() podobnie pozwala, aby
\fIcl_args.stack\fP wynosiło NULL). W takim przypadku, potomek używa duplikatu
stosu rodzica (jest to dokonywane za pomocą kopiowania\-przy\-zapisie, co
zapewnia, że potomek otrzyma odrębne kopie stron stosu, gdy jeden z procesów
zmodyfikuje stos). W tym przypadku, aby zapewnić poprawne działanie, nie
powinno się podawać opcji \fBCLONE_VM\fP (jeśli potomek \fIwspółdzieli\fP pamięć z
rodzicem ze względu na znacznik \fBCLONE_VM\fP, to nie zachodzi duplikacja z
kopiowaniem\-przy\-zapisie, co prawdopodobnie doprowadzi do chaotycznych
rezultatów).
.PP
Kolejność argumentów również różni się w surowym wywołaniu systemowym,
występuje także zmienność argumentów w zależności od architektury, zgodnie z
poniższym opisem.
.PP
Interfejsem surowego wywołania systemowego na x86\-64 i niektórych innych
architekturach (w tym sh, tile i alpha) jest:
.PP
.in +4n
.EX
\fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack\fP\fB,\fP
\fB           int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP
\fB           unsigned long \fP\fItls\fP\fB);\fP
.EE
.in
.PP
.\" CONFIG_CLONE_BACKWARDS
Na x86\-32 i wielu innych popularnych architekturach (w tym score, ARM, ARM
64, PA\-RISC, arc, Power PC, xtensa i MIPS), kolejność dwóch ostatnich
argumentów jest zamieniona:
.PP
.in +4n
.EX
\fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack\fP\fB,\fP
\fB          int *\fP\fIparent_tid\fP\fB, unsigned long \fP\fItls\fP\fB,\fP
\fB          int *\fP\fIchild_tid\fP\fB);\fP
.EE
.in
.PP
.\" CONFIG_CLONE_BACKWARDS2
Na architekturach cris i s390, kolejność pierwszych dwóch argumentów jest
zamieniona:
.PP
.in +4n
.EX
\fBlong clone(void *\fP\fIstack\fP\fB, unsigned long \fP\fIflags\fP\fB,\fP
\fB           int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP
\fB           unsigned long \fP\fItls\fP\fB);\fP
.EE
.in
.PP
.\" CONFIG_CLONE_BACKWARDS3
Na architekturze microblaze występuje dodatkowy argument:
.PP
.in +4n
.EX
\fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack\fP\fB,\fP
\fB           int \fP\fIstack_size\fP\fB,\fP         /* Rozmiar stosu */
\fB           int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP
\fB           unsigned long \fP\fItls\fP\fB);\fP
.EE
.in
.\"
.SS "blackfin, m68k i sparc"
.\" Mike Frysinger noted in a 2013 mail:
.\"     these arches don't define __ARCH_WANT_SYS_CLONE:
.\"     blackfin ia64 m68k sparc
Konwencje przekazywania argumentów na blackfin, m68k i sparc są odmienne od
powyższych opisów. Więcej szczegółów w źródle jądra (i glibc).
.SS ia64
Na ia64 używany jest inny interfejs:
.PP
.in +4n
.EX
\fBint __clone2(int (*\fP\fIfn\fP\fB)(void *),\fP
\fB             void *\fP\fIstack_base\fP\fB, size_t \fP\fIstack_size\fP\fB,\fP
\fB             int \fP\fIflags\fP\fB, void *\fP\fIarg\fP\fB, ...\fP
\fB          /* pid_t *\fP\fIparent_tid\fP\fB, struct user_desc *\fP\fItls\fP\fB,\fP
\fB             pid_t *\fP\fIchild_tid\fP\fB */ );\fP
.EE
.in
.PP
Powyższy prototyp jest do funkcji opakowującej z glibc; jeśli chodzi o samo
wywołanie systemowe, jego prototyp może być opisany w sposób następujący
(jest identyczny do prototypu \fBclone\fP() na microblaze):
.PP
.in +4n
.EX
\fBlong clone2(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack_base\fP\fB,\fP
\fB            int \fP\fIstack_size\fP\fB,\fP         /* Rozmiar stosu */
\fB            int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP
\fB            unsigned long \fP\fItls\fP\fB);\fP
.EE
.in
.PP
\fB__clone2\fP() działa w ten sam sposób co \fBclone\fP() z tym wyjątkiem, że
\fIstack_base\fP wskazuje na najniższy adres przestrzeni stosu potomka, a
\fIstack_size\fP określa rozmiar stosu, na który wskazuje \fIstack_base\fP.
.SS "Linux 2.4 i wcześniejsze"
W Linuksie 2.4 i wcześniejszych \fBclone\fP() nie przyjmowało argumentów
\fIparent_tid\fP, \fItls\fP ani \fIchild_tid\fP.
.SH USTERKI
Biblioteka GNU C w wersjach od 2.3.4 do 2.24 włącznie, zawierała funkcję
opakowującą \fBgetpid\fP(2), która przeprowadzała buforowanie PID\-ów. To
buforowanie zależało od obsługi opakowania \fBclone\fP() z glibc, jednak
ograniczenia w implementacji powodowały, że w niektórych przypadkach bufor
ten nie był aktualny. W szczególności, jeśli do potomka dostarczano sygnał
od razu po wywołaniu \fBclone\fP(), to wywołanie \fBgetpid\fP(2) w procedurze
obsługi sygnału mogło zwrócić PID procesu wywołującego (\[Bq]rodzica\[rq]),
jeśli opakowanie clone nie miało jeszcze szansy zaktualizowania bufora PID w
potomku (ten opis ignoruje sytuację, gdy potomka utworzono za pomocą
\fBCLONE_THREAD\fP; wówczas \fBgetpid\fP(2) \fIpowinno\fP zwracać tę samą wartość w
potomku jak w procesie wywołującym \fBclone\fP(), ponieważ wywołujący i potomek
znajdują się w tej samej grupie wątków. Problem nieaktualnego bufora nie
występuje również, gdy argument \fIflags\fP zawiera \fBCLONE_VM\fP). Do dotarcia
do prawdziwego PID, trzeba było czasem użyć kodu takiego jak poniższy:
.PP
.in +4n
.EX
#include <syscall.h>

pid_t mypid;

mypid = syscall(SYS_getpid);
.EE
.in
.\" See also the following bug reports
.\" https://bugzilla.redhat.com/show_bug.cgi?id=417521
.\" http://sourceware.org/bugzilla/show_bug.cgi?id=6910
.PP
Ze względu na kłopot z nieaktualnym buforem i inne problemy opisane w
\fBgetpid\fP(2), funkcjonalność buforowania PID\-ów usunięto w glibc 2.25.
.SH PRZYKŁADY
Poniższy program demonstruje użycie \fBclone\fP() do utworzenia procesu
potomnego, który wykonuje się w oddzielnej przestrzeni nazw UTS. Potomek
zmienia nazwę stacji w swojej przestrzeni nazw UTS. Rodzic i potomek
wyświetlają następnie systemową nazwę stacji, przez co widać, że różni się
ona w przestrzeniach nazw UTS rodzica i potomka. Przykład użycia tego
programu znajduje się w podręczniku \fBsetns\fP(2).
.PP
W programie przykładowym pamięć, która ma być użyta do stosu potomka,
przydzielamy za pomocą \fBmmap\fP(2), zamiast \fBmalloc\fP(3), z następujących
powodów:
.IP \[bu] 3
\fBmmap\fP(2) przydziela blok pamięci zaczynający się na granicy strony i
będący wielokrotnością rozmiaru strony. Przydaje się to, gdy chcemy ustawić
ochronę strony (stronę z ochroną \fBPROT_NONE\fP) na końcu stosu, za pomocą
\fBmprotect\fP(2).
.IP \[bu]
Możemy podać znacznik \fBMAP_STACK\fP, aby zażądać mapowania, które jest
odpowiednie do stosu. W tej chwili znacznik ten nie daje efektu na Linuksie,
ale istnieje i działa na niektórych innych systemach, dlatego należy go
podać ze względu na przenośność.
.SS "Kod źródłowy programu"
.\" SRC BEGIN (clone.c)
.EX
#define _GNU_SOURCE
#include <err.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <unistd.h>

static int              /* Początek funkcje klonowanego potomka */
childFunc(void *arg)
{
    struct utsname uts;

    /* Zmiana nazwy stacji w przestrzeni nazw UTS potomka. */

    if (sethostname(arg, strlen(arg)) == \-1)
        err(EXIT_FAILURE, "sethostname");

    /* Pobranie i wyświetlenie nazwy stacji. */

    if (uname(&uts) == \-1)
        err(EXIT_FAILURE, "uname");
    printf("uts.nodename u potomka:  %s\en", uts.nodename);

    /* Utrzymuje przestrzeń nazw otwartą przez chwilę, śpiąc.
       Daje to pole do eksperymentów \- do przestrzeni nazw
       może np. dołączyć inny proces. */

    sleep(200);

    return 0;           /* Potomek ulega zakończeniu */
}

#define STACK_SIZE (1024 * 1024)    /* Rozmiar stosu klon. potomka */

int
main(int argc, char *argv[])
{
    char            *stack;         /* Początek bufora stosu */
    char            *stackTop;      /* Koniec bufora stosu */
    pid_t           pid;
    struct utsname  uts;

    if (argc < 2) {
        fprintf(stderr, "Użycie: %s <child\-hostname>\en", argv[0]);
        exit(EXIT_SUCCESS);
    }

    /* Przydzielenie pamięci na stos potomka. */

    stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
                 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, \-1, 0);
    if (stack == MAP_FAILED)
        err(EXIT_FAILURE, "mmap");

    stackTop = stack + STACK_SIZE;  /* Założenie: stos rośnie w dół */

    /* Utworzenie potomka z własną przestrzenią nazw UTS;
       potomek rozpoczyna wykonanie w childFunc(). */

    pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]);
    if (pid == \-1)
        err(EXIT_FAILURE, "clone");
    printf("clone() zwróciło %jd\en", (intmax_t) pid);

    /* Rodzic przechodzi tutaj */

    sleep(1);           /* Czas na zmianę nazwy stacji przez potomka */

    /* Wyświetla nazwę stacji w przestrzeni nazw UTS rodzica. Będzie
       inna, od nazwy stacji w przestrzeni nazw UTS potomka. */

    if (uname(&uts) == \-1)
        err(EXIT_FAILURE, "uname");
    printf("uts.nodename u rodzica: %s\en", uts.nodename);

    if (waitpid(pid, NULL, 0) == \-1)    /* Czekanie na potomka */
        err(EXIT_FAILURE, "waitpid");
    printf("potomek zakończył działanie\en");

    exit(EXIT_SUCCESS);
}
.EE
.\" SRC END
.SH "ZOBACZ TAKŻE"
\fBfork\fP(2), \fBfutex\fP(2), \fBgetpid\fP(2), \fBgettid\fP(2), \fBkcmp\fP(2), \fBmmap\fP(2),
\fBpidfd_open\fP(2), \fBset_thread_area\fP(2), \fBset_tid_address\fP(2), \fBsetns\fP(2),
\fBtkill\fP(2), \fBunshare\fP(2), \fBwait\fP(2), \fBcapabilities\fP(7),
\fBnamespaces\fP(7), \fBpthreads\fP(7)
.PP
.SH TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika są:
Przemek Borys <pborys@dione.ids.pl>,
Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>
i
Michał Kułach <michal.kulach@gmail.com>
.
.PP
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach
licencji można uzyskać zapoznając się z
.UR https://www.gnu.org/licenses/gpl-3.0.html
GNU General Public License w wersji 3
.UE
lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
.PP
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy
dyskusyjnej
.MT manpages-pl-list@lists.sourceforge.net
.ME .
