1 \chapter{La gestione dei processi}
2 \label{cha:process_handling}
4 Come accennato nell'introduzione in un sistema unix ogni attività del sistema
5 viene svolta tramite i processi. In sostanza i processi costituiscono l'unità
6 base per l'allocazione e l'uso delle risorse del sistema.
8 Nel precedente capitolo abbiamo visto come funziona un singolo processo, in
9 questo capitolo affronteremo i dettagli della creazione e della distruzione
10 dei processi, della gestione dei loro attributi e privilegi, e di tutte le
11 funzioni a questo connesse.
14 \section{Introduzione}
17 Partiremo con una introduzione generale ai concetti che stanno alla base della
18 gestione dei processi in unix. Introdurremo in questa sezione l'architettura
19 della gestione dei processi e le sue principali caratteristiche, e daremo una
20 panoramica sull'uso delle principali funzioni per la gestione dei processi.
22 \subsection{La gerarchia dei processi}
23 \label{sec:proc_hierarchy}
25 A differenza di quanto avviene in altri sistemi (ad esempio nel VMS la
26 generazione di nuovi processi è un'operazione privilegiata) una delle
27 caratteristiche di unix (che esamineremo in dettaglio più avanti) è che
28 qualunque processo può a sua volta generarne altri, detti processi figli
29 (\textit{child process}). Ogni processo è identificato presso il sistema da un
30 numero unico, il \acr{pid} (da \textit{process identifier}).
32 Una seconda caratteristica è che la generazione di un processo è una
33 operazione separata rispetto al lancio di un programma. In genere la sequenza
34 è sempre quella di creare un nuovo processo, il quale si eseguirà, in un passo
35 successivo, il programma voluto: questo è ad esempio quello che fa la shell
36 quando mette in esecuzione il programma che gli indichiamo nella linea di
39 Una terza caratteristica è che ogni processo viene sempre generato da un altro
40 che viene chiamato processo genitore (\textit{parent process}). Questo vale
41 per tutti i processi, con una eccezione (dato che ci deve essere un punto di
42 partenza), esiste sempre infatti un processo speciale, che normalmente è
43 \cmd{/sbin/init}, che viene lanciato dal kernel quando questo ha finito la
44 fase di avvio, esso essendo il primo processo lanciato ha sempre il \acr{pid}
45 uguale a 1 e non è figlio di nessuno.
47 Questo è ovviamente un processo speciale, che in genere si occupa di far
48 partire tutti gli processi altri necessari al funzionamento del sistema,
49 inoltre \cmd{init} è essenziale per svolgere una serie di compiti
50 amministrativi nelle operazioni ordinarie del sistema (torneremo si alcuni di
51 essi in \secref{}) e non può mai essere terminato. La struttura del sistema
52 comunque consente di lanciare al posto di \cmd{init} qualunque altro programma
53 (e in casi di emergenza, ad esempio se il file di \cmd{init} si fosse
54 corrotto, è possibile farlo ad esempio passando la riga \cmd{init=/bin/sh}
57 Dato che tutti i processi successivi sono comunque generati da \cmd{init} o da
58 suoi figli tutto ciò comporta che, i processi sono organizzati gerarchicamente
59 dalla relazione fra genitori e figli, in maniera analoga a come i file sono
60 organizzati in un albero di directory con alla base \file{/} (si veda
61 \secref{sec:file_file_struct}); in questo caso alla base dell'albero c'è il
62 processo \cmd{init} che è progenitore di ogni altro processo\footnote{in
63 realtà questo non è del tutto vero, in Linux ci sono alcuni processi che pur
64 comparendo come figli di init (ad esempio in \cmd{pstree}) sono generati
65 direttamente dal kernel, come \cmd{keventd}, \cmd{kswapd}, etc.}.
68 \subsection{Una panoramica sulle funzioni di gestione}
69 \label{sec:proc_handling_intro}
71 I processi vengono creati dalla funzione \func{fork}; in molti unix questa è
72 una system call, Linux però usa un'altra nomenclatura, e la funzione fork è
73 basata a sua volta sulla system call \func{\_\_clone}, che viene usata anche
74 per generare i \textit{thread}. Il processo figlio creato dalla \func{fork} è
75 una copia identica del processo processo padre, ma ha nuovo \acr{pid} e viene
76 eseguito in maniera indipendente (le differenze fra padre e figlio sono
77 affrontate in dettaglio in \secref{sec:proc_fork}).
79 Se si vuole che il processo padre si fermi fino alla conclusione del processo
80 figlio questo deve essere specificato subito dopo la \func{fork} chiamando la
81 funzione \func{wait} o la funzione \func{waitpid}; queste funzioni
82 restituiscono anche una informazione abbastanza limitata (il codice di uscita)
83 sulle cause della terminazione del processo.
85 Quando un processo ha concluso il suo compito o ha incontrato un errore non
86 risolvibile esso può essere terminato con la funzione \func{exit} (si veda
87 quanto discusso in \secref{sec:proc_termination}). La vita del processo però
88 termina solo quando la notifica della sua conclusione viene ricevuta dal
89 processo padre, a quel punto tutte le risorse allocate nel sistema ad esso
90 associate vengono rilasciate.
92 Avere due processi che eseguono esattamente lo stesso codice non è molto
93 utile, normalmente si genera un secondo processo per affidargli l'esecuzione
94 di un compito specifico (ad esempio gestire una connessione dopo che questa è
95 stata stabilita), o fargli eseguire (come fa la shell) un altro programma. Per
96 quest'ultimo caso si usa la seconda funzione fondamentale per programmazione
97 coi processi che è la \func{exec}.
99 Il programma che un processo sta eseguendo si chiama immagine del processo (o
100 \textit{process image}), le funzioni della famiglia \func{exec} permettono di
101 caricare un'altro programma da disco sostituendo quest'ultimo all'immagine
102 corrente; questo fa si che l'immagine precedente venga completamente
103 cancellata. Questo significa che quando il nuovo programma esce anche il
104 processo termina, e non si può tornare alla precedente immagine.
106 Per questo motivo la \func{fork} e la \func{exec} sono funzioni molto
107 particolari con caratteristiche uniche rispetto a tutte le altre, infatti la
108 prima ritorna due volte (nel processo padre e nel figlio) mentre la seconda
109 non ritorna mai (in quanto con essa viene eseguito un altro programma).
113 \section{La gestione dei processi}
114 \label{sec:proc_handling}
116 In questa sezione tratteremo le funzioni per la gestione dei processi, a
117 partire dalle funzioni elementari che permettono di leggerne gli
118 identificatori, alle varie funzioni di manipolazione dei processi, che
119 riguardano la lore creazione, terminazione, e la messa in esecuzione di altri
123 \subsection{Gli identificatori dei processi}
126 Come accennato nell'introduzione ogni processo viene identificato dal sistema
127 da un numero identificativo unico, il \textit{process id} o \acr{pid};
128 quest'ultimo è un tipo di dato standard, il \type{pid\_t} che in genere è un
129 intero con segno (nel caso di Linux e delle glibc il tipo usato è \type{int}).
131 Il \acr{pid} viene assegnato in forma progressiva ogni volta che un nuovo
132 processo viene creato, fino ad un limite massimo (in genere essendo detto
133 numero memorizzato in un intero a 16 bit si arriva a 32767) oltre il quale si
134 riparte dal numero più basso disponibile (FIXME: verificare, non sono sicuro).
135 Per questo motivo processo il processo di avvio (\cmd{init}) ha sempre il
136 \acr{pid} uguale a uno.
138 Tutti i processi inoltre memorizzano anche il \acr{pid} del genitore da cui
139 sono stati creati, questo viene chiamato in genere \acr{ppid} (da
140 \textit{parent process id}) ed è normalmente utilizzato per il controllo di
141 sessione. Questi due identificativi possono essere ottenuti da programma
144 \headdecl{sys/types.h}
146 \funcdecl{pid\_t getpid(void)} restituisce il pid del processo corrente.
147 \funcdecl{pid\_t getppid(void)} restituisce il pid del padre del processo
150 Entrambe le funzioni non riportano condizioni di errore.
153 Il fatto che il \acr{pid} sia un numero univoco per il sistema lo rende il
154 candidato ideale per generare ultieriori indicatori associati al processo di
155 cui diventa possibile garantire l'unicità: ad esempio la funzione
156 \func{tmpname} (si veda \secref{sec:file_temp_file}) usa il \acr{pid} per
157 generare un pathname univoco, che non potrà essere replicato da un'altro
158 processo che usi la stessa funzione.
160 Tutti i processi figli dello stesso processo padre sono detti
161 \textit{sibling}, questa è un'altra delle relazioni usate nel controllo di
162 sessione, in cui si raggruppano tutti i processi creati su uno stesso
163 terminale una volta che si è effettuato il login. Torneremo su questo
164 argomento in \secref{cap:terminal}, dove esamineremo tutti gli altri
165 identificativi associati ad un processo relativi al controllo di sessione.
168 \subsection{La funzione \func{fork}}
169 \label{sec:proc_fork}
171 La funzione \func{fork} è la funzione fondamentale della gestione dei processi
172 in unix; come si è detto l'unico modo di creare un nuovo processo è attraverso
173 l'uso di questa funzione, che è quindi la base per il multitasking; il protipo
177 \headdecl{sys/types.h}
180 \funcdecl{pid\_t fork(void)}
182 Restituisce zero al padre e il \acr{pid} al figlio in caso di successo,
183 ritorna -1 al padre (senza creare il figlio) in caso di errore;
184 \texttt{errno} può assumere i valori:
186 \item \macro{EAGAIN} non ci sono risorse sufficienti per creare un'altro
187 processo (per allocare la tabella delle pagine e le strutture del task) o
188 si è esaurito il numero di processi disponibili.
189 \item \macro{ENOMEM} non è stato possibile allocare la memoria per le
190 strutture necessarie al kernel per creare il nuovo processo.
194 Dopo l'esecuzione di una \func{fork} sia il processo padre che il processo
195 figlio continuano ad essere eseguiti normalmente alla istruzione seguente la
196 \func{fork}; il processo figlio è però una copia del padre, e riceve una copia
197 dei segmenti di testo, stack e dati (vedi \secref{sec:proc_mem_layout}), ed
198 esegue esattamente lo stesso codice del padre, ma la memoria è copiata, non
199 condivisa\footnote{In generale il segmento di testo, che è identico, è
200 condiviso e tenuto in read-only, linux poi utilizza la tecnica del
201 \textit{copy-on-write}, per cui la memoria degli altri segmenti viene
202 copiata dal kernel per il nuovo processo solo in caso di scrittura, rendendo
203 molto più efficiente il meccanismo} pertanto padre e figlio vedono variabili
206 La differenza che si ha nei due processi è che nel processo padre il valore di
207 ritorno della funzione fork è il \acr{pid} del processo figlio, mentre nel
208 figlio è zero; in questo modo il programma può identificare se viene eseguito
209 dal padre o dal figlio.
214 #include <errno.h> /* error definitions and routines */
215 #include <stdlib.h> /* C standard library */
216 #include <unistd.h> /* unix standard library */
217 #include <stdio.h> /* standard I/O library */
218 #include <string.h> /* string functions */
220 /* Help printing routine */
223 int main(int argc, char *argv[])
226 * Variables definition
233 ... /* handling options */
235 /* There must be remaing parameters */
236 if (optind == argc) {
239 nchild = atoi(argv[optind]);
240 printf("Test for forking %d child\n", nchild);
241 /* loop to fork children */
242 for (i=0; i<nchild; i++) {
243 if ( (pid = fork()) < 0) {
244 printf("Error on %d child creation, %s\n", i, strerror(errno));
246 if (pid == 0) { /* child */
247 printf("Child %d successfully executing\n", ++i);
248 if (wait_child) sleep(wait_child);
249 printf("Child %d exiting\n", i);
251 } else { /* parent */
252 printf("Spawned %d child, pid %d \n", i+1, pid);
253 if (wait_parent) sleep(wait_parent);
254 printf("Go to next child \n");
261 \caption{Esempio di codice per la creazione di nuovi processi.}
262 \label{fig:proc_fork_code}
265 Si noti come la funzione \func{fork} ritorni \textbf{due} volte: una nel padre
266 e una nel figlio. La sola differenza che si ha nei due processi è il valore di
267 ritorno restituito dalla funzione, che nel padre è il \acr{pid} del figlio
268 mentre nel figlio è zero; in questo modo il programma può identificare se
269 viene eseguito dal padre o dal figlio.
271 La scelta di questi valori non è casuale, un processo infatti può avere più
272 figli, ed il valore di ritorno di \func{fork} è l'unico modo che permette di
273 identificare quello appena creato; al contrario un figlio ha sempre un solo
274 padre (il cui \acr{pid} può sempre essere ottenuto con \func{getppid}, vista
275 in \secref{sec:proc_pid}) e si usa il valore nullo, che non può essere il
276 \acr{pid} di nessun processo.
278 In \curfig\ si è riportato il corpo del codice del programma di esempio
279 \cmd{forktest}, che ci permette di illustrare l'uso della funzione
280 \func{fork}. Il programma permette di creare un numero di figli specificato a
281 linea di comando, e prende anche due opzioni \cmd{-p} e \cmd{-c} per indicare
282 degli eventuali tempi di attesa (in secondi, ottenuti tramite la funzione
283 \func{sleep}) per il padre ed il figlio; il codice completo, compresa la parte
284 che gestisce le opzioni a riga di comando, è disponibile nel file
287 Decifrato il numero di figli da creare, il ciclo principale del programma
288 (\texttt{\small 28--40}) esegue in successione la creazione dei processi figli
289 controllando il successo della chiamata a \func{fork} (\texttt{\small
290 29--31}); ciascun figlio (\texttt{\small 29--31}) si limita a stampare il
291 suo numero di successione, evantualmente attendere il numero di secondi
292 specificato e scrivere un messaggio prima di uscire. Il processo padre invece
293 (\texttt{\small 29--31}) stampa un messaggio di creazione, eventualmente
294 attende il numero di secondi specificato e procede nell'esecuzione del ciclo.
295 Se eseguiamo il comando senza specificare attese (il default è non attendere),
296 otterremo come output sul terminale:
298 [piccardi@selidor sources]$ ./forktest 3
299 Test for forking 3 child
300 Spawned 1 child, pid 2038
301 Child 1 successfully executing
304 Spawned 2 child, pid 2039
305 Child 2 successfully executing
308 Child 3 successfully executing
310 Spawned 3 child, pid 2040
314 Esaminiamo questo risultato; una prima conclusione che si può trarre è non si
315 può dire quale processo fra il padre ed il figlio venga eseguito per
316 primo\footnote{anche se nel kernel 2.4.x era stato introdotto un meccanismo
317 che metteva in esecuzione sempre il xxx per primo (TODO recuperare le
318 informazioni esatte)} dopo la chiamata a \func{fork}; dall'esempio si può
319 notare infatti come nei primi due cicli sia stato eseguito per primo il padre
320 (con la stampa del \acr{pid} del nuovo processo) per poi passare
321 all'esecuzione del figlio (completata con i due avvisi di esecuzione ed
322 uscita), e tornare all'esecuzione del padre (con la stampa del passaggio al
323 ciclo successivo), mentre la terza volta è stato prima eseguito il figlio (in
324 maniera completa) e poi il padre.
326 In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di
327 scheduling usato dal kernel, dalla particolare situazione in si trova la
328 macchina al momento della chiamata, risultando del tutto impredicibile.
329 Eseguendo più volte il programma di prova e producendo un numero diverso di
330 figli, si sono ottenute situazioni completamente diverse, compreso il caso in
331 cui il processo padre ha eseguito più di una \func{fork} prima che uno dei
332 figli venisse messo in esecuzione.
334 Pertanto non si può fare nessuna assunzione sulla sequenza di esecuzione delle
335 istruzioni del codice fra padre e figli, e se è necessaria una qualche forma
336 di precedenza occorrerà provvedere ad espliciti meccanismi di
337 sincronizzazione, pena il rischio di incorrere nelle cosiddette \textit{race
340 Si noti inoltre che, come accennato, essendo i segmenti di memoria utilizzati
341 dai singoli processi completamente separati, le modifiche delle variabili nei
342 processi figli (come l'incremento di \var{i} in \texttt{\small 33}) sono
343 visibili solo al loro interno, e non hanno alcun effetto sul valore che le
344 stesse variabili hanno nel processo padre (ed in eventuali altri processi
345 figli che eseguano lo stesso codice).
347 Un secondo aspetto molto importante nella creazione dei processi figli è
348 quello dell'interazione dei vari processi con i file; per illustrarlo meglio
349 proviamo a redirigere su un file l'output del nostro programma di test, quello
352 [piccardi@selidor sources]$ ./forktest 3 > output
353 [piccardi@selidor sources]$ cat output
354 Test for forking 3 child
355 Child 1 successfully executing
357 Test for forking 3 child
358 Spawned 1 child, pid 836
360 Child 2 successfully executing
362 Test for forking 3 child
363 Spawned 1 child, pid 836
365 Spawned 2 child, pid 837
367 Child 3 successfully executing
369 Test for forking 3 child
370 Spawned 1 child, pid 836
372 Spawned 2 child, pid 837
374 Spawned 3 child, pid 838
377 che come si vede è completamente diverso da quanto ottenevamo sul terminale.
379 Analizzeremo in gran dettaglio in \capref{cha:file_unix_interface} e in
380 \secref{cha:files_std_interface} il comportamento delle varie funzioni di
381 interfaccia con i file. Qui basta ricordare che si sono usate le funzioni
382 standard della libreria del C che prevedono l'output bufferizzato; e questa
383 bufferizzazione varia a seconda che si tratti di un file su disco (in cui il
384 buffer viene scaricato su disco solo quando necessario) o di un terminale (nel
385 qual caso il buffer viene scaricato ad ogni a capo).
387 Nel primo esempio allora avevamo che ad ogni chiamata a \func{printf} il
388 buffer veniva scaricato, e le singole righe erano stampate a video volta a
389 volta. Quando con la redirezione andiamo a scrivere su un file, questo non
390 avviene più, e dato che ogni figlio riceve una copia della memoria del padre,
391 esso riceverà anche quanto c'è nel buffer delle funzioni di I/O, comprese le
392 linee scritte dal padre fino allora. Così quando all'uscita di un figlio il
393 buffer viene scritto su disco, troveremo nel file anche tutto quello che il
394 processo padre aveva scritto prima della sua creazione. Alla fine, dato che
395 in questo caso il padre esce per ultimo, troviamo anche l'output del padre.
397 Ma l'esempio ci mostra un'altro aspetto fondamentale dell'interazione con i
398 file, che era valido anche per l'esempio precedente, ma meno evidente; il
399 fatto cioè che non solo processi diversi possono scrivere in contemporanea
400 sullo stesso file (l'argomento della condivisione dei file in unix è trattato
401 in dettaglio in \secref{sec:file_sharing}), ma anche che, a differenza di
402 quanto avviene per le variabili, la posizione corrente sul file è condivisa
403 fra il padre e tutti i processi figli.
405 Quello che succede è che quando lo standard output del padre viene rediretto,
406 lo stesso avviene anche per tutti i figli; la funzione \func{fork} infatti ha
407 la caratteristica di duplicare (allo stesso modo in cui lo fa la funzione
408 \func{dup}, trattata in \secref{sec:file_dup}) nei figli tutti i file
409 descriptor aperti nel padre, il che comporta che padre e figli condividono
410 le stesse voci della file table (per la spiegazione di questi termini si veda
411 \secref{sec:file_sharing} e referenza a figura da fare) e quindi anche
412 l'offset corrente nel file.
414 In questo modo se un processo scrive sul file aggiornerà l'offset sulla file
415 table, e tutti gli altri vedranno il nuovo valore; in questo modo si evita, in
416 casi come quello appena mostrato, in cui diversi processi scrivono sullo
417 stesso file, che l'output successivo di un processo vada a sovrascrivere
418 quello dei precedenti (l'output potrà risultare mescolato, ma non ci saranno
419 parti perdute per via di una sovrapposizione).
421 Questo tipo di comportamento è essenziale in tutti quei casi in cui il padre
422 crea un figlio ed attende la sua conclusione per proseguire, ed entrambi
423 scrivono sullo stesso file (ad esempio lo standard output). Se l'output viene
424 rediretto con questo comportamento avremo che il padre potrà continuare a
425 scrivere automaticamente in coda a quanto scritto dal figlio; se così non
426 fosse ottenere questo comportamento sarebbe estremamente complesso
427 necessitando di una qualche forma di comunicazione fra i due processi.
429 In generale comunque non è buona norma far scrivere più processi sullo stesso
430 file senza una qualche forma di sincronizzazione in quanto, come visto con il
431 nostro esempio, le varie scritture risulteranno mescolate fra loro in una
432 sequenza impredicibile. Le modalità generali con cui si usano i file dopo una
433 \func{fork} sono sostanzialmente due:
435 \item Il processo padre aspetta la conclusione del figlio. In questo caso non
436 è necessaria nessuna azione riguardo ai file, in quanto la sincronizzazione
437 degli offset dopo eventuali operazioni di lettura e scrittura effettuate dal
439 \item L'esecuzione di padre e figlio procede indipendentemente. In questo caso
440 entrambi devono chiudere i file che non servono, per evitare ogni forma
443 \subsection{Le funzioni \texttt{wait} e \texttt{waitpid}}
444 \label{sec:proc_wait}
447 \subsection{Le funzioni \texttt{exec}}
448 \label{sec:proc_exec}
453 \section{Il controllo di accesso}
454 \label{sec:proc_perms}
456 In questa sezione esamineremo le problematiche relative al controllo di
457 accesso dal punto di vista del processi; gli identificativi usati, come questi
458 vengono modificati nella creazione e nel lancio di nuovi processi, e le varie
459 funzioni per la loro manipolazione diretta.
462 \subsection{Utente e gruppo di un processo}
463 \label{sec:proc_user_group}
465 Abbiamo già accennato in \secref{sec:intro_multiuser} ad ogni utente ed gruppo
466 sono associati due identificatori univoci, lo \acr{uid} e il \acr{gid} che li
467 contraddistinguono nei confonti del kernel. Questi identificatori stanno alla
468 base del sistema di permessi e protezioni di un sistema unix, e vengono usati
469 anche nella gestione dei privilegi di accesso dei processi.
471 In realtà ad ogni processo è associato un certo numero di identificatori, il
472 cui elenco è riportato \ntab, in genere questi derivano direttamente
473 dall'utente che ha lanciato il processo (attraverso i valori di \acr{uid} e
474 \acr{gid}), e vengono usati sia per il controllo di accesso ai file che per la
475 gestione dei privilegi associati ai processi stessi.
478 \begin{tabular}[c]{|c|l|l|}
480 Sigla & Significato & Utilizzo \\
483 \acr{ruid} & \textit{real user id} & indica l'utente reale che ha lanciato
485 \acr{rgid} & \textit{real group id} & indica il gruppo reale dell'utente
486 che ha lanciato il programma \\
487 \acr{euid} & \textit{effective user id} & indica l'utente effettivo usato
489 \acr{egid} & \textit{effective group id} & indica il gruppo effettivo usato
491 & \textit{supplementary group id} & indica i gruppi cui
492 l'utente appartiene \\
493 \acr{suid} & \textit{saved user id} & indica l'utente \\
494 \acr{sgid} & \textit{daved group id} & indica il gruppo \\
495 \acr{fsuid} & \textit{filesystem user id} & indica l'utente effettivo per
497 \acr{fsgid} & \textit{filesystem group id} & indica il gruppo effettivo
501 \caption{Identificatori di utente e gruppo associati a ciascun processo.}
502 \label{tab:proc_uid_gid}
505 Il \textit{real user id} e il \textit{real group id} indicano l'utente che ha
506 lanciato il processo, e vengono settati al login al valore standard di
507 \acr{uid} e \acr{gid} dell'utente letti direttamente da \file{/etc/passwd}.
508 Questi non vengono mai cambiati nella creazione di nuovi processi e restano
509 sempre gli stessi per tutti i processi avviati in una sessione. In realtà è
510 possibile modificarli (vedi \secref{sec:proc_setuid}), ma solo per un processo
511 che abbia i privilegi di amministratore (ed è così infatti che \cmd{login},
512 che gira con i privilegi di amministratore, li setta ai valori corrispondenti
513 all'utente che entra nel sistema).
515 L'\textit{effective user id}, l'\textit{effective group id} e gli eventuali
516 \textit{supplementary group id} sono gli identificativi usati per il controllo
517 di accesso ai file secondo quanto descritto in dettaglio in
518 \secref{sec:file_perm_overview}. Normalmente sono uguali al \textit{real user
519 id} e al \textit{real group id}, a meno che il file posto in esecuzione non
520 abbia i bit \acr{suid} o \acr{sgid} settati, nel qual caso vengono settati
521 rispettivamente all'\acr{uid} e \acr{gid} del file.
523 Il \textit{saved user id} e il \textit{saved group id} sono copie
524 dell'\textit{effective user id} e dell'\textit{effective group id} del
525 processo padre, e vengono settati all'avvio del processo, prima che
526 \textit{effective user id} e \textit{effective group id} vengano modificati
527 per tener conto di eventuali \acr{suid} o \acr{sgid}.
530 \subsection{Le funzioni \texttt{setuid} e \texttt{setgid}}
531 \label{sec:proc_setuid}
534 \subsection{Le funzioni \texttt{seteuid} e \texttt{setegid}}
535 \label{sec:proc_seteuid}