From: Simone Piccardi Date: Thu, 14 Mar 2002 19:55:03 +0000 (+0000) Subject: Sistemate alcune citazioni, aggiunti alcuni esempi. X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=86de518c1856b983608c791e0bbbc265aaf8e9b4;hp=e63a5e53036597d8027e2bf727c606698863a5d6 Sistemate alcune citazioni, aggiunti alcuni esempi. --- diff --git a/biblio.bib b/biblio.bib index 3636d7a..0b059da 100644 --- a/biblio.bib +++ b/biblio.bib @@ -46,7 +46,7 @@ OPTnote = {}, OPTannote = {} } -@Book{libc, +@Book{glibc, author = {Sandra Loosemore with Richard M. Stallman, Roland McGrath, Andrew Oram, and Ulrich Drepper}, editor = {Free Software Foundation}, diff --git a/prochand.tex b/prochand.tex index 9d07969..96297d7 100644 --- a/prochand.tex +++ b/prochand.tex @@ -895,18 +895,18 @@ specchietto riportato in \ntab: \begin{table}[!htb] \centering \footnotesize - \begin{tabular}[c]{|c|p{10cm}|} + \begin{tabular}[c]{|c|c|p{8cm}|} \hline - \textbf{Valore} & \textbf{Significato}\\ + \textbf{Valore} & \textbf{Macro} &\textbf{Significato}\\ \hline \hline - $<-1$& attende per un figlio il cui \textit{process group} è uguale al + $<-1$& -- & attende per un figlio il cui \textit{process group} è uguale al valore assoluto di \var{pid}. \\ - $-1$ & attende per un figlio qualsiasi, usata in questa maniera è - equivalente a \func{wait}.\\ - $0$ & attende per un figlio il cui \textit{process group} è uguale a - quello del processo chiamante. \\ - $>0$ & attende per un figlio il cui \acr{pid} è uguale al + $-1$ & \macro{WAIT\_ANY} & attende per un figlio qualsiasi, usata in + questa maniera è equivalente a \func{wait}.\\ + $0$ & \macro{WAIT\_MYPGRP} & attende per un figlio il cui \textit{process + group} è uguale a quello del processo chiamante. \\ + $>0$ & -- &attende per un figlio il cui \acr{pid} è uguale al valore di \var{pid}.\\ \hline \end{tabular} diff --git a/signal.tex b/signal.tex index 95974f3..eeefd98 100644 --- a/signal.tex +++ b/signal.tex @@ -314,62 +314,6 @@ Ciascun segnale diretto di questo numero da parte dei programmi è da evitare, in quanto esso può variare a seconda dell'implementazione del sistema, e nel caso si Linux, anche a seconda dell'architettura hardware. - -\begin{table}[htb] - \footnotesize - \centering - \begin{tabular}[c]{|l|c|c|p{8cm}|} - \hline - \textbf{Segnale}&\textbf{Standard}&\textbf{Azione}&\textbf{Descrizione} \\ - \hline - \hline - \macro{SIGHUP} &PL & A & Hangup o fine del processo di controllo \\ - \macro{SIGINT} &PL & A & Interrupt da tastiera (\cmd{C-c}) \\ - \macro{SIGQUIT} &PL & C & Quit da tastiera (\cmd{C-y}) \\ - \macro{SIGILL} &PL & C & Istruzione illegale \\ - \macro{SIGABRT} &PL & C & Segnale di abort da \func{abort} \\ - \macro{SIGFPE} &PL & C & Errore aritmetico \\ - \macro{SIGKILL} &PL &AEF& Segnale di terminazione forzata \\ - \macro{SIGSEGV} &PL & C & Errore di accesso in memoria \\ - \macro{SIGPIPE} &PL & A & Pipe spezzata \\ - \macro{SIGALRM} &PL & A & Segnale del timer da \func{alarm} \\ - \macro{SIGTERM} &PL & A & Segnale di terminazione \verb|C-\| \\ - \macro{SIGUSR1} &PL & A & Segnale utente numero 1 \\ - \macro{SIGUSR2} &PL & A & Segnale utente numero 2 \\ - \macro{SIGCHLD} &PL & B & Figlio terminato o fermato \\ - \macro{SIGCONT} &PL & & Continua se fermato \\ - \macro{SIGSTOP} &PL &DEF& Ferma il processo \\ - \macro{SIGTSTP} &PL & D & Stop typed at tty \\ - \macro{SIGTTIN} &PL & D & Input sul terminale per un processo - in background \\ - \macro{SIGTTOU} &PL & D & Output sul terminale per un processo - in background \\ - \macro{SIGBUS} &SL & C & Errore sul bus (bad memory access) \\ - \macro{SIGPOLL} &SL & A & Pollable event (Sys V). - Sinonimo di \macro{SIGIO} \\ - \macro{SIGPROF} &SL & A & Timer del profiling scaduto \\ - \macro{SIGSYS} &SL & C & Bad argument to routine (SVID) \\ - \macro{SIGTRAP} &SL & C & Trace/breakpoint trap \\ - \macro{SIGURG} &SLB& B & Urgent condition on socket \\ - \macro{SIGVTALRM}&SLB& A & Virtual alarm clock \\ - \macro{SIGXCPU} &SLB& C & Ecceduto il limite sul CPU time \\ - \macro{SIGXFSZ} &SLB& C & Ecceduto il limite sulla dimensione dei file \\ - \macro{SIGIOT} &L & C & IOT trap. A synonym for \macro{SIGABRT} \\ - \macro{SIGEMT} &L & & \\ - \macro{SIGSTKFLT}&L & A & Stack fault on coprocessor \\ - \macro{SIGIO} &LB & A & I/O now possible (4.2 BSD) \\ - \macro{SIGCLD} &L & & A synonym for \macro{SIGCHLD} \\ - \macro{SIGPWR} &L & A & Fallimento dell'alimentazione \\ - \macro{SIGINFO} &L & & A synonym for \macro{SIGPWR} \\ - \macro{SIGLOST} &L & A & Perso un lock sul file (per NFS) \\ - \macro{SIGWINCH} &LB & B & Window resize signal (4.3 BSD, Sun) \\ - \macro{SIGUNUSED}&L & A & Unused signal (will be SIGSYS) \\ - \hline - \end{tabular} - \caption{Lista dei segnali in Linux.} - \label{tab:sig_signal_list} -\end{table} - Per questo motivo ad ogni segnale viene associato un nome, definendo con una macro di preprocessore una costante uguale al suddetto numero. Sono questi nomi, che sono standardizzati e sostanzialmente uniformi rispetto alle varie @@ -383,12 +327,6 @@ In \tabref{tab:sig_signal_list} si definiti in Linux (estratto dalle man page), comparati con quelli definiti in vari standard. -In \tabref{tab:sig_signal_list} si sono anche riportate le azioni di default -di ciascun segnale (riassunte con delle lettere, la cui legenda completa è in -\tabref{tab:sig_action_leg}), quando nessun manipolatore è installato un -segnale può essere ignorato o causare la terminazione del processo. Nella -colonna standard sono stati indicati anche gli standard in cui ciascun segnale -è definito, secondo lo schema di \tabref{tab:sig_standard_leg}. \begin{table}[htb] \footnotesize @@ -412,11 +350,13 @@ colonna standard sono stati indicati anche gli standard in cui ciascun segnale \label{tab:sig_action_leg} \end{table} -In alcuni casi alla terminazione del processo è associata la creazione di un -file (posto nella directory corrente del processo e chiamato \file{core}) su -cui viene salvata un'immagine della memoria del processo (il cosiddetto -\textit{core dump}), che può essere usata da un debugger per esaminare lo -stato dello stack e delle variabili al momento della ricezione del segnale. +In \tabref{tab:sig_signal_list} si sono anche riportate le azioni di default +di ciascun segnale (riassunte con delle lettere, la cui legenda completa è in +\tabref{tab:sig_action_leg}), quando nessun manipolatore è installato un +segnale può essere ignorato o causare la terminazione del processo. Nella +colonna standard sono stati indicati anche gli standard in cui ciascun segnale +è definito, secondo lo schema di \tabref{tab:sig_standard_leg}. + \begin{table}[htb] \footnotesize @@ -437,6 +377,67 @@ stato dello stack e delle variabili al momento della ricezione del segnale. \label{tab:sig_standard_leg} \end{table} +In alcuni casi alla terminazione del processo è associata la creazione di un +file (posto nella directory corrente del processo e chiamato \file{core}) su +cui viene salvata un'immagine della memoria del processo (il cosiddetto +\textit{core dump}), che può essere usata da un debugger per esaminare lo +stato dello stack e delle variabili al momento della ricezione del segnale. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|c|c|p{8cm}|} + \hline + \textbf{Segnale}&\textbf{Standard}&\textbf{Azione}&\textbf{Descrizione} \\ + \hline + \hline + \macro{SIGHUP} &PL & A & Hangup o fine del processo di controllo \\ + \macro{SIGINT} &PL & A & Interrupt da tastiera (\cmd{C-c}) \\ + \macro{SIGQUIT} &PL & C & Quit da tastiera (\cmd{C-y}) \\ + \macro{SIGILL} &PL & C & Istruzione illegale \\ + \macro{SIGABRT} &PL & C & Segnale di abort da \func{abort} \\ + \macro{SIGFPE} &PL & C & Errore aritmetico \\ + \macro{SIGKILL} &PL &AEF& Segnale di terminazione forzata \\ + \macro{SIGSEGV} &PL & C & Errore di accesso in memoria \\ + \macro{SIGPIPE} &PL & A & Pipe spezzata \\ + \macro{SIGALRM} &PL & A & Segnale del timer da \func{alarm} \\ + \macro{SIGTERM} &PL & A & Segnale di terminazione \verb|C-\| \\ + \macro{SIGUSR1} &PL & A & Segnale utente numero 1 \\ + \macro{SIGUSR2} &PL & A & Segnale utente numero 2 \\ + \macro{SIGCHLD} &PL & B & Figlio terminato o fermato \\ + \macro{SIGCONT} &PL & & Continua se fermato \\ + \macro{SIGSTOP} &PL &DEF& Ferma il processo \\ + \macro{SIGTSTP} &PL & D & Stop typed at tty \\ + \macro{SIGTTIN} &PL & D & Input sul terminale per un processo + in background \\ + \macro{SIGTTOU} &PL & D & Output sul terminale per un processo + in background \\ + \macro{SIGBUS} &SL & C & Errore sul bus (bad memory access) \\ + \macro{SIGPOLL} &SL & A & Pollable event (Sys V). + Sinonimo di \macro{SIGIO} \\ + \macro{SIGPROF} &SL & A & Timer del profiling scaduto \\ + \macro{SIGSYS} &SL & C & Bad argument to routine (SVID) \\ + \macro{SIGTRAP} &SL & C & Trace/breakpoint trap \\ + \macro{SIGURG} &SLB& B & Urgent condition on socket \\ + \macro{SIGVTALRM}&SLB& A & Virtual alarm clock \\ + \macro{SIGXCPU} &SLB& C & Ecceduto il limite sul CPU time \\ + \macro{SIGXFSZ} &SLB& C & Ecceduto il limite sulla dimensione dei file \\ + \macro{SIGIOT} &L & C & IOT trap. A synonym for \macro{SIGABRT} \\ + \macro{SIGEMT} &L & & \\ + \macro{SIGSTKFLT}&L & A & Stack fault on coprocessor \\ + \macro{SIGIO} &LB & A & I/O now possible (4.2 BSD) \\ + \macro{SIGCLD} &L & & A synonym for \macro{SIGCHLD} \\ + \macro{SIGPWR} &L & A & Fallimento dell'alimentazione \\ + \macro{SIGINFO} &L & & A synonym for \macro{SIGPWR} \\ + \macro{SIGLOST} &L & A & Perso un lock sul file (per NFS) \\ + \macro{SIGWINCH} &LB & B & Window resize signal (4.3 BSD, Sun) \\ + \macro{SIGUNUSED}&L & A & Unused signal (will be SIGSYS) \\ + \hline + \end{tabular} + \caption{Lista dei segnali in Linux.} + \label{tab:sig_signal_list} +\end{table} + La descrizione dettagliata del significato dei vari segnali, raggruppati per tipologia, verrà affrontate nel seguito. @@ -795,10 +796,10 @@ recapitati solo al padre, al figlio dovranno arrivare solo i segnali dovuti alle sue azioni. Quando si mette in esecuzione un nuovo programma con \func{exec} (si ricordi -quanto detto in \secref{sec:prog_exec}) tutti i segnali per i quali è stato +quanto detto in \secref{sec:proc_exec}) tutti i segnali per i quali è stato installato un manipolatore vengono resettati a \macro{SIG\_DFL}. Non ha più senso infatti fare riferimento a funzioni definite nel programma originario, -che non sono nemmeno presenti nello spazio di indirizzi del nuovo programma. +che non sono presenti nello spazio di indirizzi del nuovo programma. Si noti che questo vale solo per le azioni per le quali è stato installato un manipolatore; viene mantenuto invece ogni eventuale settaggio dell'azione a @@ -985,9 +986,9 @@ la funzione \func{kill}; il suo prototipo \end{functions} La funzione \code{raise(sig)} è sostanzialmente equivalente ad una -\code{kill(getpid(), sig)}. Siccome \func{raise} è definita nello standard ISO -C non esiste in alcune vecchie versioni di Unix, per cui in generale l'uso di -\func{kill} è più portabile. +\code{kill(getpid(), sig)}. Siccome \func{raise}, che è definita nello +standard ISO C, non esiste in alcune vecchie versioni di Unix, in generale +l'uso di \func{kill} finisce per essere più portabile. Lo standard POSIX poi prevede che il valore 0 sia usato per specificare il segnale nullo. Se le funzioni vengono chiamate con questo valore non viene @@ -998,18 +999,29 @@ conto per \secref{sec:proc_pid}) per cui l'esistenza di un processo non significa che esso sia realmente quello a cui si intendeva mandare il segnale. -Il valore dell'argomento \param{pid} specifica la destinazione a cui inviare -il segnale e può assumere i seguenti significati: -\begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}} -\item[$\texttt{pid}>0$] il segnale è mandato al processo con il \acr{pid} - indicato. -\item[$\texttt{pid}=0$] il segnale è mandato ad ogni processo del - \textit{process group} del chiamante. -\item[$\texttt{pid}=-1$] il segnale è mandato ad ogni processo (eccetto - \cmd{init}). -\item[$\texttt{pid}<-1$] il segnale è mandato ad ogni processo del process - group $|\code{pid}|$. -\end{basedescript} +Il valore dell'argomento \param{pid} specifica il processo (o i processi) di +destinazione a cui il segnale deve essere inviato e può assumere i valori +riportati in \tabref{tab:sig_kill_values}. +\begin{table}[htb] + \centering + \begin{tabular}[c]{|r|l|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + $>0$ & il segnale è mandato al processo con il \acr{pid} indicato.\\ + 0 & il segnale è mandato ad ogni processo del \textit{process group} + del chiamante.\\ + $-1$ & il segnale è mandato ad ogni processo (eccetto \cmd{init}).\\ + $<-1$ & il segnale è mandato ad ogni processo del process group + $|\code{pid}|$.\\ + \hline + \end{tabular} + \caption{Valori dell'argomento \param{pid} per la funzione + \func{kill}.} + \label{tab:sig_kill_values} +\end{table} + Solo l'amministratore può inviare un segnale ad un processo qualunque, in tutti gli altri casi il \textit{real user id} o l'\textit{effective user id} @@ -1057,8 +1069,8 @@ effettuare delle scelte in caso di necessit In \secref{sec:sys_unix_time} abbiamo visto che ad ogni processo sono associati tre tempi diversi: \textit{clock time}, \textit{user time} e -\textit{system time}. Per poterli calcolare il kernel mantiene tre diversi -timer per ciascun processo: +\textit{system time}. Per poterli calcolare il kernel mantiene per ciascun +processo tre diversi timer: \begin{itemize} \item un \textit{real-time timer} che calcola il tempo reale trascorso (che corrisponde al \textit{clock time}). La scadenza di questo timer provoca @@ -1151,7 +1163,7 @@ L'uso di \func{setitimer} consente dunque un controllo completo di tutte le caratteristiche dei timer, ed in effetti la stessa \func{alarm}, benché definita direttamente nello standard POSIX.1, può a sua volta essere espressa in termini di \func{setitimer}, come evidenziato dal manuale delle \acr{glibc} -\cite[glibc] che ne riporta la definizione in \figref{fig:sig_alarm_def}. +\cite{glibc} che ne riporta la definizione in \figref{fig:sig_alarm_def}. \begin{figure}[!htb] \footnotesize \centering @@ -1355,11 +1367,11 @@ viene evitato, e si raggiungono pause fino ai 2~ms con precisioni del $\mu$s. -\subsection{La gestione di \macro{SIGCHLD}} +\subsection{Un esempio elementare} \label{sec:sig_sigchld} Un semplice esempio per illustrare il funzionamento di un manipolatore di -segnale è quello della gestione di \macro{SIGCHLD}. Abbiamo visto in +segnale è quello della gestione di \macro{SIGCHLD}. Abbiamo visto in \secref{sec:proc_termination} che una delle azioni eseguite dal kernel alla conclusione di un processo è quella di inviare questo segnale al padre;\footnote{in realtà in SRV4 eredita la semantica di System V, in cui il @@ -1369,10 +1381,57 @@ padre;\footnote{in realt terminazione viene scartato senza dover chiamare una \func{wait}). L'azione di default è sempre quella di ignorare il segnale, ma non attiva questo comportamento. Linux, come BSD e POSIX, non supporta questa semantica ed usa - il nome di \macro{SIGCLD} come sinonimo di \macro{SIGCHLD}.} è pertanto -naturale completare qui la trattazione della terminazione dei processi -illustrando le modalità per gestire questo segnale. + il nome di \macro{SIGCLD} come sinonimo di \macro{SIGCHLD}.} in questo caso +tutto quello che dovrà fare il manipolatore è ricevere lo stato di +terminazione in modo da evitare la formazione di zombie. + +% è pertanto +% naturale usare un esempio che ci permette di concludere la trattazione della +% terminazione dei processi. +% In questo caso si è tratterà di illustrare un esempio relativo ad un +% manipolatore per che è previsto ritornare, + +In + + + + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} +#include /* error simbol definitions */ +#include /* signal handling declarations */ +#include +#include +#include "macro.h" +void Hand_CHLD(int sig) +{ + int errno_save; + int status; + pid_t pid; + /* save errno current value */ + errno_save = errno; + /* loop until no */ + do { + errno = 0; + pid = waitpid(WAIT_ANY, &status, WNOHANG); + if (pid > 0) { + debug("child %d terminated with status %x\n", pid, status); + } + } while ((pid > 0) && (errno == EINTR)); + /* restore errno value*/ + errno = errno_save; + /* return */ + return; +} + \end{lstlisting} + \end{minipage} + \normalsize + \caption{Una implementazione sbagliata di \func{sleep}.} + \label{fig:sig_timespec_def} +\end{figure} diff --git a/sources/Hand_CHLD.c b/sources/Hand_CHLD.c new file mode 100644 index 0000000..c5113ee --- /dev/null +++ b/sources/Hand_CHLD.c @@ -0,0 +1,26 @@ +#include /* error simbol definitions */ +#include /* signal handling declarations */ +#include +#include +#include "macro.h" + +void Hand_CHLD(int sig) +{ + int errno_save; + int status; + pid_t pid; + /* save errno current value */ + errno_save = errno; + /* loop until no */ + do { + errno = 0; + pid = waitpid(WAIT_ANY, &status, WNOHANG); + if (pid > 0) { + debug("child %d terminated with status %x\n", pid, status); + } + } while ((pid > 0) && (errno == EINTR)); + /* restore errno value*/ + errno = errno_save; + /* return */ + return; +} diff --git a/sources/macros.h b/sources/macros.h new file mode 100644 index 0000000..4686292 --- /dev/null +++ b/sources/macros.h @@ -0,0 +1,39 @@ +/* + * Endianess conversion for int and short types + */ +#define BE32_TO_LE32(val) ({typeof (val) v= (val); \ + (v>>24) | ((v>>8)&0xFF00) | (v<<24) | ((v<<8)&0xFF0000); } ) +#define BE16_TO_LE16(val) ({typeof (val) v= (val); (v>>8) | (v<<8); } ) +/* + * Define a protected, right typed, no side effects macro for min + */ +#define min(x, y) ({typeof (x) x_ = (x); typeof (y) y_ = (y); \ + x_ < y_ ? x_ : y_;}) +/* + * debugging print definition + */ +#define report(fmt, args...) printf(fmt,##args) +#ifdef DEBUG /* done only on debugging */ +#define debug report +#else +#define debug(fmt, arg...) +#endif + + +/* + * Just to print an hex dump of a buffer, + * ptr is the address, m is how many word per line + * and l how many lines + */ +#define PRINT_BUF(ptr, l, m) ({ \ + int _i, _j; \ + unsigned short *_ptr= (unsigned short *)(ptr); \ + for (_i = 0; _i< (int) l; _i++) { \ + printf("Val[%d]=", m * _i); \ + for (_j = 0; _j < (int) m; _j++) { \ + printf("%x ", *_ptr);\ + _ptr++;\ + }\ + printf("\n"); \ + }\ +}) diff --git a/sources/sleep1.c b/sources/sleep1.c new file mode 100644 index 0000000..224b726 --- /dev/null +++ b/sources/sleep1.c @@ -0,0 +1,59 @@ +/* sleep1.c + * + * Copyright (C) 2002 Simone Piccardi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/**************************************************************** + * + * Program sleep1.c: + * Example of a broken implementation for sleep + * + * Author: Simone Piccardi + * Sep. 2002 + * + ****************************************************************/ +/* + * Include needed headers + */ +#include /* unix standard library */ + +unsigned int sleep(unsigned int seconds) +{ +/* + * Variables definition + */ + signandler_t prev_handler; + + if ((prev_handler = signal(SIGALRM, alarm_hand)) == SIG_ERR) { + printf("Cannot set handler for alarm\n"); + exit(1); + } + alarm(second); + pause(); + /* restore previous signal handler */ + signal(SIGALRM, prev_handler); + /* remove alarm, return remaining time */ + return alarm(0); +} +void alarm_hand(int sig) { + /* check if the signal is the right one */ + if (sig != SIGALRM) { /* if not exit with error */ + printf("Something wrong, handler for SIGALRM\n"); + exit(1); + } else { /* do nothing, just interrupt pause */ + return; + } +} diff --git a/system.tex b/system.tex index 062b90d..ca1fa7a 100644 --- a/system.tex +++ b/system.tex @@ -168,7 +168,7 @@ file, riportate in \tabref{tab:sys_file_macro}). \hline \hline \end{tabular} - \caption{Macro .} + \caption{Costanti per i limiti del sistema.} \label{tab:sys_generic_macro} \end{table} @@ -868,7 +868,7 @@ relative a \file{/etc/mtab}), quando si debba scrivere un programma che effettua il montaggio di un filesystem; in realtà in questi casi è molto più semplice invocare direttamente il programma \cmd{mount}, per cui ne tralasceremo la trattazione, rimandando al manuale delle \acr{glibc} -\cite{libc} per la documentazione completa. +\cite{glibc} per la documentazione completa. \subsection{La gestione di utenti e gruppi}