From 39fd68b4edd01be7664153992dea276a4b9a3396 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sat, 27 Oct 2001 14:23:23 +0000 Subject: [PATCH] Aggiunte sezioni su problemi generici di programmazione, finita setfsuid --- process.tex | 286 +++++++++++++++++++++++++++++++++------------------ prochand.tex | 95 +++++++++++++++-- 2 files changed, 275 insertions(+), 106 deletions(-) diff --git a/process.tex b/process.tex index d048873..d3fa51d 100644 --- a/process.tex +++ b/process.tex @@ -6,7 +6,8 @@ sistema unix alloca ed utilizza le risorse. Questo capitolo tratter l'interfaccia base fra il sistema e i processi, su come vengono passati i parametri, come viene gestita e allocata la memoria, su come un processo può richiedere servizi al sistema, su cosa deve fare quando ha finito la sua -esecuzione. +esecuzione. Nella sezione finale acceneremo ad alcune problematiche generiche +di programmazione. In genere un programma viene eseguito quando un processo lo fa partire eseguendo una funzione della famiglia \func{exec}; torneremo su questo e @@ -591,32 +592,32 @@ puntatore ad una di queste variabili, che sar all'uscita della funzione, con gli stessi problemi appena citati per \func{alloca}. -\subsection{Le funzioni \texttt{brk} e \texttt{sbrk}} +\subsection{Le funzioni \func{brk} e \func{sbrk}} \label{sec:proc_mem_sbrk} L'uso di queste funzioni è necessario solo quando si voglia accedere alle analoghe system call a cui fanno da interfaccia (ad esempio per implementare -una propria versione di \texttt{malloc}. Le funzione sono: +una propria versione di \func{malloc}. Le funzione sono: \begin{prototype}{unistd.h}{int *brk(void end\_data\_segment)} Sposta la fine del segmento dei dati all'indirizzo specificato da - \texttt{end\_data\_segment}. + \var{end\_data\_segment}. La funzione restituisce 0 in caso di successo e -1 in caso di fallimento, - nel qual caso \texttt{errno} viene settata a \texttt{ENOMEM}. + nel qual caso \var{errno} viene settata a \macro{ENOMEM}. \end{prototype} \begin{prototype}{unistd.h}{int *sbrk(ptrdiff\_t increment)} - Incrementa lo spazio dati di un programma di \texttt{increment}. Un valore + Incrementa lo spazio dati di un programma di \var{increment}. Un valore zero restituisce l'attuale posizione della fine del segmento dati. La funzione restituisce il puntatore all'inizio della nuova zona di memoria - allocata in caso di successo e \texttt{NULL} in caso di fallimento, nel qual - caso \texttt{errno} viene settata a \texttt{ENOMEM}. + allocata in caso di successo e \macro{NULL} in caso di fallimento, nel qual + caso \macro{errno} viene settata a \macro{ENOMEM}. \end{prototype} Queste funzioni sono state deliberatamente escluse dallo standard POSIX.1 e per i programmi normali è opportuno usare le funzioni di allocazione standard descritte in precedenza, che sono costruite su di esse. In genere si usa -\texttt{sbrk} con un valore zero per ottenere l'attuale posizione della fine +\func{sbrk} con un valore zero per ottenere l'attuale posizione della fine del segmento dati. @@ -670,33 +671,50 @@ bloccata allora esso viene escluso dal meccanismo della paginazione. I blocchi non si accumulano, se si blocca due volte la stessa pagina non è necessario sbloccarla due volte, una pagina o è bloccata o no. -Il blocco di memoria persiste fintanto che il processo che lo detiene la +Il \textit{memory lock} persiste fintanto che il processo che detiene la memoria bloccata non la sblocca. Chiaramente la terminazione del processo comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di -tutti i blocchi di memoria. - -I memory lock non sono ereditati dai processi figli\footnote{ma siccome Linux - usa il copy on write gli indirizzi virtuali del figlio sono mantenuti sullo - stesso segmento di RAM del padre, quindi usufruiscono dei memory lock di - questo}. Siccome la presenza di memory lock ha un impatto sugli altri -processi solo root ha la capacità di bloccare una pagina, ogni processo può -però sbloccare le sue pagine. Il sistema pone dei limiti all'ammontare di +tutti i \textit{memory lock}. + +I \textit{memory lock} non sono ereditati dai processi figli\footnote{ma + siccome Linux usa il copy on write gli indirizzi virtuali del figlio sono + mantenuti sullo stesso segmento di RAM del padre, quindi fintanto che un + figlio non scrive su un segmento, può usufruire dei memory lock del padre}. +Siccome la presenza di \textit{memory lock} ha un impatto sugli altri processi +solo l'amministratore ha la capacità di bloccare una pagina; ogni processo +però può sbloccare le sue pagine. Il sistema pone dei limiti all'ammontare di memoria di un processo che può essere bloccata e al totale di memoria fisica che può dedicare a questo. +Le funzioni per bloccare e sbloccare singole sezioni di memoria sono +\func{mlock} e \func{munlock}; i loro prototipi sono: -\section{Il controllo di flusso non locale} -\label{sec:proc_longjmp} +\begin{functions} +\headdecl{stdlib.h} +\funcdecl{void *calloc(size\_t size)} + Alloca \var{size} byte nello heap. La memoria viene inizializzata a 0. + + La funzione restituisce il puntatore alla zona di memoria allocata in caso + di successo e \macro{NULL} in caso di fallimento, nel qual caso + \var{errno} viene settata a \macro{ENOMEM}. +\funcdecl{void *malloc(size\_t size)} + Alloca \var{size} byte nello heap. La memoria non viene inizializzata. -Il controllo del flusso di un programma in genere viene effettuato con le -varie istruzioni del linguaggio C, la più bistrattata delle quali è il -\func{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste -però un caso in l'uso di questa istruzione porta all'implementazione più -efficiente, quello dell'uscita in caso di errore. + La funzione restituisce il puntatore alla zona di memoria allocata in caso + di successo e \macro{NULL} in caso di fallimento, nel qual caso + \var{errno} viene settata a \macro{ENOMEM}. +\funcdecl{void *realloc(void *ptr, size\_t size)} + Cambia la dimensione del blocco allocato all'indirizzo \var{ptr} + portandola a \var{size}. -Il C però non consente di effettuare un salto ad una label definita in -un'altra funzione, per cui se l'errore avviene in funzioni profondamente -annidate occorre usare la funzione \func{longjump}. + La funzione restituisce il puntatore alla zona di memoria allocata in caso + di successo e \macro{NULL} in caso di fallimento, nel qual caso + \var{errno} viene settata a \macro{ENOMEM}. +\funcdecl{void free(void *ptr)} + Disalloca lo spazio di memoria puntato da \var{ptr}. + + La funzione non ritorna nulla. +\end{functions} @@ -727,7 +745,7 @@ questo modo il primo parametro \subsection{La gestione delle opzioni} \label{sec:proc_opt_handling} -In generale un programma unix riceve da linea di comando sia i parametri che +In generale un programma unix riceve da linea di comando sia gli argomenti che le opzioni, queste ultime sono standardizzate per essere riconosciute come tali: un elemento di \var{argv} che inizia con \texttt{-} e che non sia un singolo \texttt{-} o \texttt{--} viene considerato un'opzione. In in genere @@ -739,89 +757,67 @@ touch -r riferimento.txt -m questofile.txt \end{verbatim} ed in questo caso le opzioni sono \texttt{m} ed \texttt{r}. -Per gestire le opzioni all'interno dei parametri passati in \func{argv} le -librerie standard del C forniscono la funzione \func{getopt} che ha il -prototipo: +Per gestire le opzioni all'interno dei argomenti a linea di comando passati in +\func{argv} le librerie standard del C forniscono la funzione \func{getopt} +che ha il seguente prototipo: \begin{prototype}{unistd.h} {int getopt(int argc, char * const argv[], const char * optstring)} La funzione esegue il parsing degli argomenti passati da linea di comando riconoscendo le possibili opzioni segnalate con \var{optstring}. -Ritorna il carattere che segue l'opzione, \cmd{:} se manca un parametro -all'opzione, \cmd{?} se l'opzione è sconosciuta, e -1 se non esistono altre +Ritorna il carattere che segue l'opzione, \cmd{':'} se manca un parametro +all'opzione, \cmd{'?'} se l'opzione è sconosciuta, e -1 se non esistono altre opzioni. \end{prototype} -Questa funzione prende come argomenti le due variabili \var{argc} e -\var{argv} ed una stringa che indica quali sono le opzioni valide; la -funzione effettua la scansione della lista dei parametri ricercando ogni -stringa che comincia con \cmd{-} e ritorna ogni volta che trova una opzione -valida. +Questa funzione prende come argomenti le due variabili \var{argc} e \var{argv} +passate a \func{main} (vedi \secref{sec:proc_main}) ed una stringa che indica +quali sono le opzioni valide; la funzione effettua la scansione della lista +degli argomenti ricercando ogni stringa che comincia con \cmd{-} e ritorna ogni +volta che trova una opzione valida. La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è costituita da tutti i caratteri usati per identificare le singole opzioni, se l'opzione ha un parametro al carattere deve essere fatto seguire un segno di -due punti \texttt{:} nel caso appena accennato ad esempio la stringa di -opzioni sarebbe \texttt{"r:m"}. - -La modalità di uso è pertanto quella di chiamare più volte la funzione -all'interno di un ciclo di while fintanto che essa non ritorna il valore -\texttt{-1} che indica che non ci sono più opzioni. Nel caso si incontri -un'opzione non dichiarata in \texttt{optstring} viene ritornato un \texttt{?} -mentre se l'opzione non è seguita da un parametro viene ritornato un -\texttt{:} infine se viene incontrato il valore \texttt{--} la scansione viene -considerata conclusa, anche se vi sono altri parametri che cominciano con -\texttt{-}. +due punti \var{':'}, nel caso appena accennato ad esempio la stringa di +opzioni sarebbe \var{"r:m"}. + +La modalità di uso di \func{getopt} è pertanto quella di chiamare più volte la +funzione all'interno di un ciclo fintanto che essa non ritorna il valore -1 +che indica che non ci sono più opzioni. Nel caso si incontri un'opzione non +dichiarata in \var{optstring} viene ritornato il carattere \texttt{'?'} +mentre se un opzione che lo richiede non è seguita da un parametro viene +ritornato il carattere \texttt{':'}, infine se viene incontrato il valore +\cmd{--} la scansione viene considerata conclusa, anche se vi sono altri +elementi di \var{argv} che cominciano con il carattere \texttt{'-'}. -Quando la funzione trova un'opzione essa ritorna il valore numerico del -carattere, in questo modo si possono prendere le azioni relative usando un -case; la funzione inizializza inoltre alcune variabili globali: -\begin{itemize*} -\item \var{char * optarg} contiene il puntatore alla stringa argomento - dell'opzione. -\item \var{int optind} alla fine della scansione restituisce l'indice del - primo argomento che non è un'opzione. -\item \var{int opterr} previene, se posto a zero, la stampa di un messaggio - di errore in caso di riconoscimento di opzioni non definite. -\item \var{int optopt} contiene il carattere dell'opzione non riconosciuta. -\end{itemize*} - -In \nfig\ è mostrato un programma di esempio: \begin{figure}[htbp] \footnotesize \begin{lstlisting}{} opterr = 0; /* don't want writing to stderr */ - while ( (i = getopt(argc, argv, "o:a:i:hve")) != -1) { + while ( (i = getopt(argc, argv, "hp:c:e:")) != -1) { switch (i) { - case 'i': /* input file */ - in_file=open(optarg,O_RDONLY); - if (in_file<0) { - perror("Cannot open input file"); - exit(1); - } - break; - case 'o': /* output file (overwrite) */ - out_file=open(optarg,O_WRONLY|O_CREAT); - if (out_file<0) { - perror("Cannot open output file"); - exit(1); - } + /* + * Handling options + */ + case 'h': /* help option */ + printf("Wrong -h option use\n"); + usage(); + return -1; break; - case 'a': /* output file (append) */ - out_file=open(optarg,O_WRONLY|O_CREAT|O_APPEND); + case 'c': /* take wait time for childen */ + wait_child = strtol(optarg, NULL, 10); /* convert input */ break; - case 'h': /* print help usage */ - usage(); + case 'p': /* take wait time for childen */ + wait_parent = strtol(optarg, NULL, 10); /* convert input */ break; - case 'v': /* set verbose mode */ - debug("Option -v active\n"); - verbose=1; + case 'e': /* take wait before parent exit */ + wait_end = strtol(optarg, NULL, 10); /* convert input */ break; case '?': /* unrecognized options */ printf("Unrecognized options -%c\n",optopt); usage(); default: /* should not reached */ - debug("default option\n"); usage(); } } @@ -831,13 +827,56 @@ In \nfig\ \label{fig:proc_options_code} \end{figure} +Quando la funzione trova un'opzione essa ritorna il valore numerico del +carattere, in questo modo si possono prendere le azioni relative usando uno +\func{switch}; la funzione inizializza inoltre alcune variabili globali: +\begin{itemize*} +\item \var{char * optarg} contiene il puntatore alla stringa parametro + dell'opzione. +\item \var{int optind} alla fine della scansione restituisce l'indice del + primo elemento di \var{argv} che non è un'opzione. +\item \var{int opterr} previene, se posto a zero, la stampa di un messaggio + di errore in caso di riconoscimento di opzioni non definite. +\item \var{int optopt} contiene il carattere dell'opzione non riconosciuta. +\end{itemize*} + +In \figref{fig:proc_options_code} è mostrata la sezione del programma +\file{ForkTest.c} (che useremo nel prossimo capitolo per effettuare dei test +sulla creazione dei processi) deputata alla decodifica delle opzioni a riga di +comando. + +Anzitutto si può notare che si è anzitutto (\texttt{\small 1}) disabilitata la +stampa di messaggi di errore per opzioni non riconosciute, per poi passare al +ciclo per la verifica delle opzioni (\texttt{\small 2-27}); per ciascuna delle +opioni possibili si è poi provveduto ad una opportuna azione, ad esempio per +le tre opzioni che prevedono un parametro si è effettuata la decodifica del +medesimo, il cui indirizzo è contenuto nella variabile \var{optarg}, +avvalorando la relativa variabile (\texttt{\small 12-14}, \texttt{\small + 15-17} e \texttt{\small 18-20}). Completato il ciclo troveremo in +\var{optind} l'indice in \var{argv[]} del primo degli argomenti a linea di +comando restanti. + +Normalmente \func{getopt} compie una permutazione degli elementi di \var{argv} +così che alla fine della scansione gli elementi che non sono opzioni sono +spostati in coda al vettore. Oltre a questa esistono altre due modalità di +gestire gli elementi di \var{argv}; se \var{optstring} inizia con il carattere +\texttt{'+'} (o è settata la variabile di ambiente \macro{POSIXLY\_CORRECT}) +la scansione viene fermata non appena si incontra un elemento che non è +un'opzione. L'ultima modalità, usata quando un programma può gestire la +mescolanza fra opzioni e argomenti, ma se li aspetta in un ordine definito, si +attiva quando \var{optstring} inizia con il carattere \texttt{'-'}. In questo +caso ogni elemento che non è un'opzione viene considerato comunque un'opzione +e associato ad un valore di ritorno pari ad 1, questo permette di identificare +gli elementi che non sono opzioni, ma non effettua il riordinamento del +vettore \var{argv}. + \subsection{Opzioni in formato esteso} \label{sec:proc_opt_extended} Un'estensione di questo schema è costituito dalle cosiddette -\textit{long-options} espresse nella forma \texttt{--option=parameter}, anche -la gestione di queste ultime è stata standardizzata attraverso l'uso di una +\textit{long-options} espresse nella forma \cmd{--option=parameter}, anche la +gestione di queste ultime è stata standardizzata attraverso l'uso di una versione estesa di \func{getopt}. (NdA: da finire). @@ -846,16 +885,16 @@ versione estesa di \func{getopt}. \subsection{Le variabili di ambiente} \label{sec:proc_environ} -Oltre ai parametri passati da linea di comando ogni processo riceve dal +Oltre agli argomenti passati a linea di comando ogni processo riceve dal sistema un \textsl{ambiente}, nella forma di una lista di variabili -(\textit{environment list}) messa a disposizione dal processo costruita nella -chiamata ad \func{exec} che lo ha lanciato. +(\textit{environment list}) messa a disposizione dal processo, e costruita +nella chiamata alla funzione \func{exec} quando questo viene lanciato. Come per la lista dei parametri anche questa lista è un array di puntatori a -caratteri, ciascuno dei quali punta ad una stringa (terminata da un NULL). A -differenza di \var{argv[]} però in questo caso non si ha la lunghezza -dell'array dato da un equivalente di \var{argc}, ma la lista è terminata da un -puntatore nullo. +caratteri, ciascuno dei quali punta ad una stringa (terminata da un +\macro{NULL}). A differenza di \var{argv[]} però in questo caso non si ha una +lunghezza dell'array data da un equivalente di \var{argc}, ma la lista è +terminata da un puntatore nullo. L'indirizzo della lista delle variabili di ambiente è passato attraverso la variabile globale \var{environ}, a cui si può accedere attraverso una semplice @@ -874,8 +913,9 @@ variabili che normalmente sono definite dal sistema, Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo \textsl{\texttt{nome=valore}}. Inoltre alcune variabili, come quelle elencate -in \curfig, sono definite dal sistema per queste c'è la convezione di usare -nomi espressi in caratteri maiuscoli. +in \curfig, sono definite dal sistema per essere usate da diversi programmi e +funzioni: per queste c'è l'ulteriore convezione di usare nomi espressi in +caratteri maiuscoli. Il kernel non usa mai queste variabili, il loro uso e la loro interpretazione è riservata alle applicazioni e ad alcune funzioni di libreria; in genere esse @@ -892,11 +932,61 @@ l'editor preferito da invocare in caso di necessit Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più comuni), come riportato in \ntab. GNU/Linux le supporta tutte e ne definisce -anche altre per una lista parziale si può controllare \cmd{man environ}. +anche altre: per una lista parziale si può controllare \cmd{man environ}. + + + +\section{Problematiche di programmazione generica} +\label{sec:proc_gen_prog} +Benché questo non sia un libro di C, è opportuno affrontare alcune delle +problematiche generali che possono emergere nella programmazione e di quali +precauzioni o accorgimenti occorre prendere per risolverle. Queste +problematiche non sono specifiche di sistemi unix-like o multitasking, ma +avendo trattato in questo capitolo il comportamento dei processi visti come +entità a se stanti, le riportiamo qui. +\subsection{Il passaggio delle variabili e dei valori di ritorno} +\label{sec:proc_var_passing} +Una delle caratteristiche standard del C è che le variabili vengono passate +alle subroutine attraverso un meccanismo che viene chiamato \textit{by value} +(diverso ad esempio da quanto avviene con il Fortran, dove le variabli sono +passate, come suol dirsi, \textit{by reference}, o dal C++ dove la modalità del +passaggio può essere controllata con l'operatore \cmd{\&}). + +Il passaggio di una variabile \textit{by value} significa che in realtà quello +che viene passato alla subroutine è una copia del valore attuale di quella +variabile, copia che la subroutine potrà modificare a piacere, senza che il +valore originale nella routine chiamante venga toccato. In questo modo non +occorre preoccuparsi di eventuali effetti delle operazioni della subroutine. + +La maggior parte delle funzioni di libreria e delle system call funziona +esattamente in questo modo restituendo eventuali risultati alla routine +chiamante attraverso il valore di ritorno. Talvolta però è necessario che la +funzione possa restituire indietro alla funzione chiamate un valore relativo +ad uno dei sui parametri. + + + + +\subsection{Potenziali problemi con le variabili automatiche} +\label{sec:proc_auto_var} + + +\subsection{Il controllo di flusso non locale} +\label{sec:proc_longjmp} + +Il controllo del flusso di un programma in genere viene effettuato con le +varie istruzioni del linguaggio C, la più bistrattata delle quali è il +\func{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste +però un caso in l'uso di questa istruzione porta all'implementazione più +efficiente, quello dell'uscita in caso di errore. + +Il C però non consente di effettuare un salto ad una label definita in +un'altra funzione, per cui se l'errore avviene in funzioni profondamente +annidate occorre usare la funzione \func{longjump}. diff --git a/prochand.tex b/prochand.tex index def3864..90e2e9f 100644 --- a/prochand.tex +++ b/prochand.tex @@ -8,16 +8,20 @@ base per l'allocazione e l'uso delle risorse del sistema. Nel precedente capitolo abbiamo visto come funziona un singolo processo, in questo capitolo affronteremo i dettagli della creazione e della distruzione dei processi, della gestione dei loro attributi e privilegi, e di tutte le -funzioni a questo connesse. +funzioni a questo connesse. Infine nella sezione finale affronteremo alcune +problematiche generiche della programmazione in ambiente multitasking. + \section{Introduzione} \label{sec:proc_gen} Partiremo con una introduzione generale ai concetti che stanno alla base della -gestione dei processi in unix. Introdurremo in questa sezione l'architettura -della gestione dei processi e le sue principali caratteristiche, e daremo una -panoramica sull'uso delle principali funzioni per la gestione dei processi. +gestione dei processi in un sitema unix-like. Introdurremo in questa sezione +l'architettura della gestione dei processi e le sue principali +caratteristiche, e daremo una panoramica sull'uso delle principali funzioni +per la gestione dei processi. + \subsection{La gerarchia dei processi} \label{sec:proc_hierarchy} @@ -1578,6 +1582,8 @@ identificatori usando uno qualunque dei valori correnti di \textit{real id}, valori che vuole; un valore di -1 per un qualunque parametro lascia inalterato l'dentificatore corrispondente. + + \subsection{Le funzioni \func{seteuid} e \func{setegid}} \label{sec:proc_seteuid} @@ -1590,10 +1596,10 @@ supportate dalla maggior parte degli unix) e usate per cambiare gli \headdecl{sys/types.h} \funcdecl{int seteuid(uid\_t uid)} setta l'\textit{effective user ID} del -processo corrente. +processo corrente a \var{uid}. \funcdecl{int setegid(gid\_t gid)} setta l'\textit{effective group ID} del -processo corrente. +processo corrente a \var{gid}. Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento: l'unico errore possibile è \macro{EPERM}. @@ -1601,13 +1607,84 @@ l'unico errore possibile Gli utenti normali possono settare l'\textit{effective id} solo al valore del \textit{real id} o del \textit{saved id}, l'amministratore può specificare -qualunque valore. - +qualunque valore. Queste funzioni sono usate per permettere a root di settare +solo l'\textit{effective id}, dato che l'uso normale di \func{setuid} comporta +il settagio di tutti gli identificatori. + \subsection{Le funzioni \func{setfsuid} e \func{setfsgid}} \label{sec:proc_setfsuid} +Queste funzioni sono usate per settare gli identificatori usati da Linux per +il controllo dell'accesso ai file. Come già accennato in +\secref{sec:proc_user_group} Linux definisce questo ulteriore gruppo di +identificatori che di norma sono assolutamente equivalenti agli +\textit{effective id} (ed in seguito faremo sempre riferimento a questi +ultimi), dato che ogni cambiamento di questi ultimi viene immediatamente +riportato sui \textit{filesystem id}. + +C'è un solo caso in cui si ha necessità di introdurre una differenza fra +\textit{effective id} e i \textit{filesystem id}, che è per ovviare ad un +problema di sicurezza che si presneta quando si deve implementare un server +NFS. Il server NFS infatti deve poter cambiare l'identificatore con cui accede +ai file per assumere l'identità del singolo utente remoto, ma se questo viene +fatto cambiando l'\textit{effective id} o il \textit{real id} il server si +espone alla ricezione di eventuali segnali ostili da parte dell'utente di cui +ha temporaneamente assunto l'identità. Cambiando solo il \textit{filesystem + id} si ottengono i privilegi necessari per accedere ai file, mantenendo +quelli originari per quanto riguarda tutti gli altri controlli di accesso. + +Le due funzioni usate per cambiare questi identificatori sono \func{setfsuid} +e \func{setfsgid}, sono specifiche di Linux e non devono essere usate se si +intendono scrivere programmi portabili; i loro prototipi sono: + +\begin{functions} +\headdecl{sys/fsuid.h} + +\funcdecl{int setfsuid(uid\_t fsuid)} setta il \textit{filesystem user ID} del +processo corrente a \var{fsuid}. + +\funcdecl{int setfsgid(gid\_t fsgid)} setta l'\textit{filesystem group ID} del +processo corrente a \var{fsgid}. + +Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento: +l'unico errore possibile è \macro{EPERM}. +\end{functions} + +Queste funzioni hanno successo solo se il processo chiamante ha i privilegi di +amministratore o se il valore specificato coincide con uno dei +\textit{real}, \textit{effective} o \textit{saved id}. + + + + +\section{Problematiche di programmazione multitasking} +\label{sec:proc_multi_prog} + +Benché i processi siano strutturati in modo da apparire il più possibile come +independenti l'uno dall'altro, nella programmazione in un sistema multiutente +occorre tenere conto di tutta una serie di problematiche che normalmente non +esistono quando si ha a che fare con un sistema in cui viene eseguito un solo +programma alla volta. + + +Pur non essendo tutto questo direttamente legato alla modalità specifica in +cui il multitasking è implementato in un sistema unix-like, avendo affrontato +la gestione dei processi in questo capitolo, tratteremo queste problematiche, +e relative precauzioni ed accorgimenti, in questa sezione conclusiva. + + +\subsection{Le funzioni rientranti} +\label{sec:proc_reentrant} + + +\subsection{I \textit{deadlock}} +\label{sec:proc_deadlock} + + +\subsection{Le operazioni atomiche} +\label{sec:proc_atom_oper} \subsection{Le \textit{race condition}} @@ -1620,3 +1697,5 @@ l'ordine di esecuzione di un processo, senza appositi meccanismi di sincronizzazione, non è assolutamente prevedibile, queste situazioni sono fonti di errori molto subdoli, che possono verificarsi solo in condizioni particolari e quindi difficilmente riproducibili. + + -- 2.30.2