Si prosegue con le modifiche per l'inclusione degli esempi di codice.
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 4 Apr 2003 11:42:03 +0000 (11:42 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 4 Apr 2003 11:42:03 +0000 (11:42 +0000)
28 files changed:
filestd.tex
listati/WriteStruct.c [new file with mode: 0644]
listati/WriteVect.c [new file with mode: 0644]
listati/errcode_mess.c [new file with mode: 0644]
listati/errlist.c [new file with mode: 0644]
listati/get_child_max.c [new file with mode: 0644]
listati/getline.c [new file with mode: 0644]
listati/group.h [new file with mode: 0644]
listati/itimerval.h [new file with mode: 0644]
listati/passwd.h [new file with mode: 0644]
listati/redir_stdout.c [new file with mode: 0644]
listati/rlimit.h [new file with mode: 0644]
listati/rusage.h [new file with mode: 0644]
listati/sighandler_t.c [new file with mode: 0644]
listati/siglist.c [new file with mode: 0644]
listati/signal.c [new file with mode: 0644]
listati/statfs.h [new file with mode: 0644]
listati/time_zone_var.c [new file with mode: 0644]
listati/timeval.h [new file with mode: 0644]
listati/timex.h [new file with mode: 0644]
listati/tm.h [new file with mode: 0644]
listati/tms.h [new file with mode: 0644]
listati/unreliable_sig.c [new file with mode: 0644]
listati/ustname.h [new file with mode: 0644]
listati/utmp.h [new file with mode: 0644]
prochand.tex
signal.tex
system.tex

index d69d7d4..b928e0d 100644 (file)
@@ -117,10 +117,7 @@ Nelle \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono
 effettivamente tre variabili di tipo \ctyp{FILE *} che possono essere
 usate come tutte le altre, ad esempio si può effettuare una redirezione
 dell'output di un programma con il semplice codice:
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    fclose(stdout);
-    stdout = fopen("standard-output-file", "w");
-\end{lstlisting}
+\includecodesnip{listati/redir_stdout.c}
 ma in altri sistemi queste variabili possono essere definite da macro, e
 se si hanno problemi di portabilità e si vuole essere sicuri, diventa
 opportuno usare la funzione \func{freopen}.
@@ -487,40 +484,12 @@ In genere si usano queste funzioni quando si devono trasferire su file
 blocchi di dati binari in maniera compatta e veloce; un primo caso di uso
 tipico è quello in cui si salva un vettore (o un certo numero dei suoi
 elementi) con una chiamata del tipo:
-%\footnotesize
-\begin{lstlisting}[stepnumber=0,frame=]{}
-int WriteVect(FILE *stream, double *vec, size_t nelem) 
-{
-    int size, nread;
-    size = sizeof(*vec);
-    if ( (nread = fwrite(vec, size, nelem, stream)) != nelem) {
-        perror("Write error");
-    }
-    return nread;
-}
-\end{lstlisting}
-%\normalsize
+\includecodesnip{listati/WriteVect.c}
 in questo caso devono essere specificate le dimensioni di ciascun
 elemento ed il numero di quelli che si vogliono scrivere. Un secondo
 caso è invece quello in cui si vuole trasferire su file una struttura;
 si avrà allora una chiamata tipo:
-%\footnotesize
-\begin{lstlisting}[stepnumber=0,frame=]{}
-struct histogram {
-    int nbins; 
-    double max, min;
-    double *bin;
-} histo; 
-
-int WriteStruct(FILE *stream, struct histogram *histo) 
-{
-    if ( fwrite(histo, sizeof(*histo), 1, stream) !=1) {
-        perror("Write error");
-    }
-    return nread;
-}
-\end{lstlisting}
-%\normalsize
+\includecodesnip{listati/WriteStruct.c}
 in cui si specifica la dimensione dell'intera struttura ed un solo
 elemento. 
 
@@ -906,14 +875,7 @@ e \var{*n} 
 necessaria a contenere la linea. In tutti i casi si ottiene dalla funzione un
 puntatore all'inizio del testo della linea letta. Un esempio di codice può
 essere il seguente:
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    size_t n = 0; 
-    char *ptr = NULL;
-    int nread;
-    FILE * file;
-    ...    
-    nread = getline(&ptr, &n, file);
-\end{lstlisting}
+\includecodesnip{listati/getline.c}
 e per evitare memory leak\index{memory leak} occorre ricordarsi di liberare
 \var{ptr} con una \func{free}.
 
diff --git a/listati/WriteStruct.c b/listati/WriteStruct.c
new file mode 100644 (file)
index 0000000..60b0025
--- /dev/null
@@ -0,0 +1,13 @@
+struct histogram {
+    int nbins; 
+    double max, min;
+    double *bin;
+} histo; 
+
+int WriteStruct(FILE *stream, struct histogram *histo) 
+{
+    if ( fwrite(histo, sizeof(*histo), 1, stream) !=1) {
+        perror("Write error");
+    }
+    return nread;
+}
diff --git a/listati/WriteVect.c b/listati/WriteVect.c
new file mode 100644 (file)
index 0000000..98cfd18
--- /dev/null
@@ -0,0 +1,9 @@
+int WriteVect(FILE *stream, double *vec, size_t nelem) 
+{
+    int size, nread;
+    size = sizeof(*vec);
+    if ( (nread = fwrite(vec, size, nelem, stream)) != nelem) {
+        perror("Write error");
+    }
+    return nread;
+}
diff --git a/listati/errcode_mess.c b/listati/errcode_mess.c
new file mode 100644 (file)
index 0000000..61321bc
--- /dev/null
@@ -0,0 +1,17 @@
+    /* convert string to number */
+    err = strtol(argv[optind], NULL, 10);
+    /* testing error condition on conversion */
+    if (err==LONG_MIN) {
+        perror("Underflow on error code");
+        return 1;
+    } else if (err==LONG_MIN) {
+        perror("Overflow on error code");
+        return 1;
+    }
+    /* conversion is fine */
+    if (message) {
+        printf("Error message for %d is %s\n", err, strerror(err));
+    }
+    if (label) {
+        printf("Error label for %d is %s\n", err, err_code[err]);
+    }
diff --git a/listati/errlist.c b/listati/errlist.c
new file mode 100644 (file)
index 0000000..848d8f2
--- /dev/null
@@ -0,0 +1,2 @@
+   const char *sys_errlist[];
+   int sys_nerr;
diff --git a/listati/get_child_max.c b/listati/get_child_max.c
new file mode 100644 (file)
index 0000000..9890abf
--- /dev/null
@@ -0,0 +1,12 @@
+get_child_max(void)
+{
+#ifdef CHILD_MAX
+    return CHILD_MAX;
+#else
+    int val = sysconf(_SC_CHILD_MAX);
+    if (val < 0) {
+        perror("fatal error");
+        exit(-1);
+    }
+    return val;
+}
diff --git a/listati/getline.c b/listati/getline.c
new file mode 100644 (file)
index 0000000..8606d62
--- /dev/null
@@ -0,0 +1,6 @@
+    size_t n = 0; 
+    char *ptr = NULL;
+    int nread;
+    FILE * file;
+    ...    
+    nread = getline(&ptr, &n, file);
diff --git a/listati/group.h b/listati/group.h
new file mode 100644 (file)
index 0000000..3f1a367
--- /dev/null
@@ -0,0 +1,6 @@
+struct group {
+    char    *gr_name;        /* group name */
+    char    *gr_passwd;      /* group password */
+    gid_t   gr_gid;          /* group id */
+    char    **gr_mem;        /* group members */
+};
diff --git a/listati/itimerval.h b/listati/itimerval.h
new file mode 100644 (file)
index 0000000..cdd0b5a
--- /dev/null
@@ -0,0 +1,5 @@
+struct itimerval 
+{
+    struct timeval it_interval; /* next value */
+    struct timeval it_value;    /* current value */
+};
diff --git a/listati/passwd.h b/listati/passwd.h
new file mode 100644 (file)
index 0000000..8be4a4b
--- /dev/null
@@ -0,0 +1,9 @@
+struct passwd {
+    char    *pw_name;       /* user name */
+    char    *pw_passwd;     /* user password */
+    uid_t   pw_uid;         /* user id */
+    gid_t   pw_gid;         /* group id */
+    char    *pw_gecos;      /* real name */
+    char    *pw_dir;        /* home directory */
+    char    *pw_shell;      /* shell program */
+};
diff --git a/listati/redir_stdout.c b/listati/redir_stdout.c
new file mode 100644 (file)
index 0000000..c16da3c
--- /dev/null
@@ -0,0 +1,2 @@
+    fclose(stdout);
+    stdout = fopen("standard-output-file", "w");
diff --git a/listati/rlimit.h b/listati/rlimit.h
new file mode 100644 (file)
index 0000000..f8628b8
--- /dev/null
@@ -0,0 +1,4 @@
+struct rlimit {
+     rlim_t    rlim_cur;
+     rlim_t    rlim_max;
+};
diff --git a/listati/rusage.h b/listati/rusage.h
new file mode 100644 (file)
index 0000000..1307aef
--- /dev/null
@@ -0,0 +1,18 @@
+struct rusage {
+    struct timeval ru_utime; /* user time used */
+    struct timeval ru_stime; /* system time used */
+    long ru_maxrss;          /* maximum resident set size */
+    long ru_ixrss;           /* integral shared memory size */
+    long ru_idrss;           /* integral unshared data size */
+    long ru_isrss;           /* integral unshared stack size */
+    long ru_minflt;          /* page reclaims */
+    long ru_majflt;          /* page faults */
+    long ru_nswap;           /* swaps */
+    long ru_inblock;         /* block input operations */
+    long ru_oublock;         /* block output operations */
+    long ru_msgsnd;          /* messages sent */
+    long ru_msgrcv;          /* messages received */
+    long ru_nsignals;   ;    /* signals received */
+    long ru_nvcsw;           /* voluntary context switches */
+    long ru_nivcsw;          /* involuntary context switches */
+};
diff --git a/listati/sighandler_t.c b/listati/sighandler_t.c
new file mode 100644 (file)
index 0000000..9fe01bc
--- /dev/null
@@ -0,0 +1 @@
+    typedef void (* sighandler_t)(int) 
diff --git a/listati/siglist.c b/listati/siglist.c
new file mode 100644 (file)
index 0000000..eb653ea
--- /dev/null
@@ -0,0 +1 @@
+    extern const char *const sys_siglist[];
diff --git a/listati/signal.c b/listati/signal.c
new file mode 100644 (file)
index 0000000..4e5ce1d
--- /dev/null
@@ -0,0 +1 @@
+    void (*signal(int signum, void (*handler)(int)))int)
diff --git a/listati/statfs.h b/listati/statfs.h
new file mode 100644 (file)
index 0000000..a48e1ee
--- /dev/null
@@ -0,0 +1,12 @@
+struct statfs {
+   long    f_type;     /* tipo di filesystem */
+   long    f_bsize;    /* dimensione ottimale dei blocchi di I/O */
+   long    f_blocks;   /* blocchi totali nel filesystem */
+   long    f_bfree;    /* blocchi liberi nel filesystem */
+   long    f_bavail;   /* blocchi liberi agli utenti normali */
+   long    f_files;    /* inode totali nel filesystem */
+   long    f_ffree;    /* inode liberi nel filesystem */
+   fsid_t  f_fsid;     /* filesystem id */
+   long    f_namelen;  /* lunghezza massima dei nomi dei file */
+   long    f_spare[6]; /* riservati per uso futuro */
+};
diff --git a/listati/time_zone_var.c b/listati/time_zone_var.c
new file mode 100644 (file)
index 0000000..61fb5b7
--- /dev/null
@@ -0,0 +1,3 @@
+extern char *tzname[2];
+extern long timezone;
+extern int daylight;
diff --git a/listati/timeval.h b/listati/timeval.h
new file mode 100644 (file)
index 0000000..4283a69
--- /dev/null
@@ -0,0 +1,9 @@
+struct timeval 
+{
+    long tv_sec;            /* seconds */
+    long tv_usec;           /* microseconds */
+};
+struct timespec {
+    time_t  tv_sec;         /* seconds */
+    long    tv_nsec;        /* nanoseconds */
+};
diff --git a/listati/timex.h b/listati/timex.h
new file mode 100644 (file)
index 0000000..05ff67e
--- /dev/null
@@ -0,0 +1,21 @@
+struct timex {
+    unsigned int modes;   /* mode selector */
+    long int offset;      /* time offset (usec) */
+    long int freq;        /* frequency offset (scaled ppm) */
+    long int maxerror;    /* maximum error (usec) */
+    long int esterror;    /* estimated error (usec) */
+    int status;           /* clock command/status */
+    long int constant;    /* pll time constant */
+    long int precision;   /* clock precision (usec) (read only) */
+    long int tolerance;   /* clock frequency tolerance (ppm) (read only) */
+    struct timeval time;  /* (read only) */
+    long int tick;        /* (modified) usecs between clock ticks */
+    long int ppsfreq;     /* pps frequency (scaled ppm) (ro) */
+    long int jitter;      /* pps jitter (us) (ro) */
+    int shift;            /* interval duration (s) (shift) (ro) */
+    long int stabil;      /* pps stability (scaled ppm) (ro) */
+    long int jitcnt;      /* jitter limit exceeded (ro) */
+    long int calcnt;      /* calibration intervals (ro) */
+    long int errcnt;      /* calibration errors (ro) */
+    long int stbcnt;      /* stability limit exceeded (ro) */
+};
diff --git a/listati/tm.h b/listati/tm.h
new file mode 100644 (file)
index 0000000..d4c9ee2
--- /dev/null
@@ -0,0 +1,13 @@
+struct tm {
+        int     tm_sec;         /* seconds */
+        int     tm_min;         /* minutes */
+        int     tm_hour;        /* hours */
+        int     tm_mday;        /* day of the month */
+        int     tm_mon;         /* month */
+        int     tm_year;        /* year */
+        int     tm_wday;        /* day of the week */
+        int     tm_yday;        /* day in the year */
+        int     tm_isdst;       /* daylight saving time */
+        long int tm_gmtoff;     /* Seconds east of UTC.  */
+        const char *tm_zone;    /* Timezone abbreviation.  */
+};
diff --git a/listati/tms.h b/listati/tms.h
new file mode 100644 (file)
index 0000000..3c9422f
--- /dev/null
@@ -0,0 +1,6 @@
+struct tms {
+       clock_t tms_utime;  /* user time */
+       clock_t tms_stime;  /* system time */
+       clock_t tms_cutime; /* user time of children */
+       clock_t tms_cstime; /* system time of children */
+};
diff --git a/listati/unreliable_sig.c b/listati/unreliable_sig.c
new file mode 100644 (file)
index 0000000..36490c7
--- /dev/null
@@ -0,0 +1,13 @@
+int sig_handler();            /* handler function */
+int main()
+{
+    ...
+    signal(SIGINT, sig_handler);  /* establish handler */
+    ...
+}
+
+int sig_handler() 
+{
+    signal(SIGINT, sig_handler);  /* restablish handler */
+    ...                           /* process signal */
+}
diff --git a/listati/ustname.h b/listati/ustname.h
new file mode 100644 (file)
index 0000000..aef0d4f
--- /dev/null
@@ -0,0 +1,10 @@
+struct utsname {
+    char sysname[];
+    char nodename[];
+    char release[];
+    char version[];
+    char machine[];
+#ifdef _GNU_SOURCE
+    char domainname[];
+#endif
+};
diff --git a/listati/utmp.h b/listati/utmp.h
new file mode 100644 (file)
index 0000000..4d918b6
--- /dev/null
@@ -0,0 +1,15 @@
+struct utmp
+{
+    short int ut_type;            /* Type of login.  */
+    pid_t ut_pid;                 /* Process ID of login process.  */
+    char ut_line[UT_LINESIZE];    /* Devicename.  */
+    char ut_id[4];                /* Inittab ID.  */
+    char ut_user[UT_NAMESIZE];    /* Username.  */
+    char ut_host[UT_HOSTSIZE];    /* Hostname for remote login.  */
+    struct exit_status ut_exit;   /* Exit status of a process marked
+                                     as DEAD_PROCESS.  */
+    long int ut_session;          /* Session ID, used for windowing.  */
+    struct timeval ut_tv;         /* Time entry was made.  */
+    int32_t ut_addr_v6[4];        /* Internet address of remote host.  */
+    char __unused[20];            /* Reserved for future use.  */
+};
index d38c843..6cca82e 100644 (file)
@@ -2065,8 +2065,9 @@ librerie, ma 
 La funzione permette, a seconda del valore di \param{which}, di leggere la
 priorità di un processo, di un gruppo di processi (vedi
 \secref{sec:sess_proc_group}) o di un utente, specificando un corrispondente
-valore per \param{who}; un valore nullo di quest'ultimo indica il processo, il
-gruppo di processi o l'utente correnti.
+valore per \param{who} secondo la legenda di \tabref{tab:proc_getpriority}; un
+valore nullo di quest'ultimo indica il processo, il gruppo di processi o
+l'utente correnti.
 
 \begin{table}[htb]
   \centering
index 525e859..c28a70c 100644 (file)
@@ -105,21 +105,7 @@ verr
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int sig_handler();            /* handler function */
-int main()
-{
-    ...
-    signal(SIGINT, sig_handler);  /* establish handler */
-    ...
-}
-
-int sig_handler() 
-{
-    signal(SIGINT, sig_handler);  /* restablish handler */
-    ...                           /* process signal */
-}
-    \end{lstlisting}
+    \includecodesample{listati/unreliable_sig.c}
   \end{minipage} 
   \normalsize 
   \caption{Esempio di codice di un gestore di segnale per la semantica
@@ -691,12 +677,14 @@ segnali sono:
 Raccogliamo qui infine usa serie di segnali che hanno scopi differenti non
 classificabili in maniera omogenea. Questi segnali sono:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\const{SIGUSR1}] Vedi \const{SIGUSR2}.
-\item[\const{SIGUSR2}] Insieme a \const{SIGUSR1} è un segnale a disposizione
-  dell'utente che li può usare per quello che vuole. Possono essere utili per
-  implementare una comunicazione elementare fra processi diversi, o per
-  eseguire a richiesta una operazione utilizzando un gestore. L'azione
-  predefinita è di terminare il processo.
+\item[\const{SIGUSR1}] Insieme a \const{SIGUSR2} è un segnale a disposizione
+  dell'utente che lo può usare per quello che vuole. Viene generato solo
+  attraverso l'invocazione della funzione \func{kill}. Entrambi i segnali
+  possono essere utili per implementare una comunicazione elementare fra
+  processi diversi, o per eseguire a richiesta una operazione utilizzando un
+  gestore. L'azione predefinita è di terminare il processo.
+\item[\const{SIGUSR2}] È il secondo segnale a dispozione degli utenti. Vedi
+  quanto appena detto per \const{SIGUSR1}.
 \item[\const{SIGWINCH}] Il nome sta per \textit{window (size) change} e viene
   generato in molti sistemi (GNU/Linux compreso) quando le dimensioni (in
   righe e colonne) di un terminale vengono cambiate. Viene usato da alcuni
@@ -740,9 +728,7 @@ Una modalit
 \func{strsignal} e \func{psignal} è quello di fare usare la variabile
 \var{sys\_siglist}, che è definita in \file{signal.h} e può essere acceduta
 con la dichiarazione:
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    extern const char *const sys_siglist[]
-\end{lstlisting}
+\includecodesnip{listati/siglist.c}
 l'array \var{sys\_siglist} contiene i puntatori alle stringhe di descrizione,
 indicizzate per numero di segnale, per cui una chiamata del tipo di \code{char
   *decr = strsignal(SIGINT)} può essere sostituita dall'equivalente \code{char
@@ -879,16 +865,12 @@ In questa definizione si 
 una estensione GNU, definita dalle \acr{glibc}, che permette di riscrivere il
 prototipo di \func{signal} nella forma appena vista, molto più leggibile di
 quanto non sia la versione originaria, che di norma è definita come:
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    void (*signal(int signum, void (*handler)(int)))int)
-\end{lstlisting}
+\includecodesnip{listati/signal.c}
 questa infatti, per la poca chiarezza della sintassi del C quando si vanno a
 trattare puntatori a funzioni, è molto meno comprensibile.  Da un confronto
 con il precedente prototipo si può dedurre la definizione di
 \type{sighandler\_t} che è:
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    typedef void (* sighandler_t)(int) 
-\end{lstlisting}
+\includecodesnip{listati/sighandler_t.c}
 e cioè un puntatore ad una funzione \ctyp{void} (cioè senza valore di ritorno)
 e che prende un argomento di tipo \ctyp{int}.\footnote{si devono usare le
   parentesi intorno al nome della funzione per via delle precedenze degli
@@ -918,22 +900,28 @@ mai notificati.
 L'uso di \func{signal} è soggetto a problemi di compatibilità, dato che essa
 si comporta in maniera diversa per sistemi derivati da BSD o da System V. In
 questi ultimi infatti la funzione è conforme al comportamento originale dei
-primi Unix in cui il gestore viene disinstallato alla sua chiamata,
-secondo la semantica inaffidabile; Linux seguiva questa convenzione fino alle
-\acr{libc5}. Al contrario BSD segue la semantica affidabile, non
-disinstallando il gestore e bloccando il segnale durante l'esecuzione
-dello stesso. Con l'utilizzo delle \acr{glibc} dalla versione 2 anche Linux è
-passato a questo comportamento; quello della versione originale della
-funzione, il cui uso è deprecato per i motivi visti in
-\secref{sec:sig_semantics}, può essere ottenuto chiamando \func{sysv\_signal}.
-In generale, per evitare questi problemi, tutti i nuovi programmi dovrebbero
-usare \func{sigaction}.
+primi Unix in cui il gestore viene disinstallato alla sua chiamata, secondo la
+semantica inaffidabile; anche Linux seguiva questa convenzione con le vecchie
+librerie del C come le \acr{libc4} e le \acr{libc5}.\footnote{nelle
+  \acr{libc5} esiste però la possibilità di includere \file{bsd/signal.h} al
+  posto di \file{signal.h}, nel qual caso la funzione \func{signal} viene
+  ridefinita per seguire la semantica affidabile usata da BSD.}
+
+Al contrario BSD segue la semantica affidabile, non disinstallando il gestore
+e bloccando il segnale durante l'esecuzione dello stesso. Con l'utilizzo delle
+\acr{glibc} dalla versione 2 anche Linux è passato a questo comportamento.  Il
+comportamento della versione originale della funzione, il cui uso è deprecato
+per i motivi visti in \secref{sec:sig_semantics}, può essere ottenuto
+chiamando \func{sysv\_signal}, uno volta che si sia definita la macro
+\macro{\_XOPEN\_SOURCE}.  In generale, per evitare questi problemi, l'uso di
+\func{signal} (ed ogni eventuale ridefinizine della stessa) è da evitare;
+tutti i nuovi programmi dovrebbero usare \func{sigaction}.
 
 È da tenere presente che, seguendo lo standard POSIX, il comportamento di un
 processo che ignora i segnali \const{SIGFPE}, \const{SIGILL}, o
-\const{SIGSEGV} (qualora non originino da una \func{kill} o una \func{raise})
-è indefinito. Un gestore che ritorna da questi segnali può dare luogo ad
-un ciclo infinito.
+\const{SIGSEGV} (qualora questi non originino da una chiamata ad una
+\func{kill} o ad una \func{raise}) è indefinito. Un gestore che ritorna da
+questi segnali può dare luogo ad un ciclo infinito.
 
 
 \subsection{Le funzioni \func{kill} e \func{raise}}
@@ -998,6 +986,25 @@ esso sia realmente quello a cui si intendeva mandare il segnale.
 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}.
+
+Si noti pertanto che la funzione \code{raise(sig)} può essere definita in
+termini di \func{kill}, ed è sostanzialmente equivalente ad una
+\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.
+
+Una seconda funzione che può essere definita in termini di \func{kill} è
+\funcd{killpg}, che è sostanzialmente equivalente a
+\code{kill(-pidgrp, signal)}; il suo prototipo è:
+\begin{prototype}{signal.h}{int killpg(pid\_t pidgrp, int signal)} 
+  
+  Invia il segnale \param{signal} al process group \param{pidgrp}.
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, gli errori sono gli stessi di \func{kill}.}
+\end{prototype}
+\noindent e che permette di inviare un segnale a tutto un \textit{process
+  group} (vedi \secref{sec:sess_proc_group}).
+
 \begin{table}[htb]
   \footnotesize
   \centering
@@ -1019,24 +1026,6 @@ riportati in \tabref{tab:sig_kill_values}.
   \label{tab:sig_kill_values}
 \end{table}
 
-Si noti pertanto che la funzione \code{raise(sig)} può essere definita in
-termini di \func{kill}, ed è sostanzialmente equivalente ad una
-\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.
-
-Una seconda funzione che può essere definita in termini di \func{kill} è
-\funcd{killpg}, che è sostanzialmente equivalente a
-\code{kill(-pidgrp, signal)}; il suo prototipo è:
-\begin{prototype}{signal.h}{int killpg(pid\_t pidgrp, int signal)} 
-  
-  Invia il segnale \param{signal} al process group \param{pidgrp}.
-  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore, gli errori sono gli stessi di \func{kill}.}
-\end{prototype}
-e che permette di inviare un segnale a tutto un \textit{process group} (vedi
-\secref{sec:sess_proc_group}).
-
 Solo l'amministratore può inviare un segnale ad un processo qualunque, in
 tutti gli altri casi l'user-ID reale o l'user-ID effettivo del processo
 chiamante devono corrispondere all'user-ID reale o all'user-ID salvato della
@@ -1164,13 +1153,7 @@ questo modo il ciclo verr
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct itimerval 
-{
-    struct timeval it_interval; /* next value */
-    struct timeval it_value;    /* current value */
-};
-    \end{lstlisting}
+    \includestruct{listati/itimerval.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{itimerval}, che definisce i valori dei timer
@@ -2626,4 +2609,5 @@ dedicato alla gestione, che potrebbe riceverlo fra due chiamate successive.
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
+%%% TeX-master: "gapil"
 %%% End: 
index e5fe228..4d980b2 100644 (file)
@@ -365,22 +365,7 @@ sostituendolo a \code{\_POSIX\_} per le macro definite dagli gli altri due.
 
 In generale si dovrebbe fare uso di \func{sysconf} solo quando la relativa
 macro non è definita, quindi con un codice analogo al seguente:
-%\footnotesize
-\begin{lstlisting}[stepnumber=0,frame=]{}
-get_child_max(void)
-{
-#ifdef CHILD_MAX
-    return CHILD_MAX;
-#else
-    int val = sysconf(_SC_CHILD_MAX);
-    if (val < 0) {
-        perror("fatal error");
-        exit(-1);
-    }
-    return val;
-}
-\end{lstlisting}
-%\normalsize 
+\includecodesnip{listati/get_child_max.c}
 ma in realtà in Linux queste macro sono comunque definite, indicando però un
 limite generico. Per questo motivo è sempre meglio usare i valori restituiti
 da \func{sysconf}.
@@ -521,18 +506,7 @@ solo definendo \macro{\_GNU\_SOURCE}.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-  \begin{lstlisting}[stepnumber=0]{}
-struct utsname {
-    char sysname[];
-    char nodename[];
-    char release[];
-    char version[];
-    char machine[];
-#ifdef _GNU_SOURCE
-    char domainname[];
-#endif
-};
-  \end{lstlisting}
+    \includestruct{listati/ustname.h}
   \end{minipage}
   \normalsize 
   \caption{La struttura \structd{utsname}.} 
@@ -896,20 +870,7 @@ genere 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-  \begin{lstlisting}[stepnumber=0]{}
-struct statfs {
-   long    f_type;     /* tipo di filesystem */
-   long    f_bsize;    /* dimensione ottimale dei blocchi di I/O */
-   long    f_blocks;   /* blocchi totali nel filesystem */
-   long    f_bfree;    /* blocchi liberi nel filesystem */
-   long    f_bavail;   /* blocchi liberi agli utenti normali */
-   long    f_files;    /* inode totali nel filesystem */
-   long    f_ffree;    /* inode liberi nel filesystem */
-   fsid_t  f_fsid;     /* filesystem id */
-   long    f_namelen;  /* lunghezza massima dei nomi dei file */
-   long    f_spare[6]; /* riservati per uso futuro */
-};
-\end{lstlisting}
+    \includestruct{listati/statfs.h}
   \end{minipage}
   \normalsize 
   \caption{La struttura \structd{statfs}.} 
@@ -983,17 +944,7 @@ il significato dei vari campi.
   \footnotesize
   \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct passwd {
-    char    *pw_name;       /* user name */
-    char    *pw_passwd;     /* user password */
-    uid_t   pw_uid;         /* user id */
-    gid_t   pw_gid;         /* group id */
-    char    *pw_gecos;      /* real name */
-    char    *pw_dir;        /* home directory */
-    char    *pw_shell;      /* shell program */
-};
-    \end{lstlisting}
+    \includestruct{listati/passwd.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{passwd} contenente le informazioni relative ad
@@ -1070,14 +1021,7 @@ in questo caso le informazioni vengono restituite in una struttura di tipo
   \footnotesize
   \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct group {
-    char    *gr_name;        /* group name */
-    char    *gr_passwd;      /* group password */
-    gid_t   gr_gid;          /* group id */
-    char    **gr_mem;        /* group members */
-};
-    \end{lstlisting}
+    \includestruct{listati/group.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{group} contenente le informazioni relative ad
@@ -1206,6 +1150,18 @@ standard \const{\_PATH\_UTMP} (che 
 corrispondenti ai file \file{/var/run/utmp} e \file{/var/log/wtmp} visti in
 precedenza.
 
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/utmp.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \structd{utmp} contenente le informazioni di una voce
+    del database di \textit{accounting}.}
+  \label{fig:sys_utmp_struct}
+\end{figure}
+
 Una volta aperto il file si può eseguire una scansione leggendo o scrivendo
 una voce con le funzioni \funcd{getutent}, \funcd{getutid}, \funcd{getutline}
 e \funcd{pututline}, i cui prototipi sono:
@@ -1230,39 +1186,11 @@ e \funcd{pututline}, i cui prototipi sono:
 \end{functions}
 
 Tutte queste funzioni fanno riferimento ad una struttura di tipo \struct{utmp},
-la cui definizione in Linux è riportata in \secref{fig:sys_utmp_struct}. Le
+la cui definizione in Linux è riportata in \figref{fig:sys_utmp_struct}. Le
 prime tre funzioni servono per leggere una voce dal database; \func{getutent}
 legge semplicemente la prima voce disponibile; le altre due permettono di
 eseguire una ricerca.
 
-\begin{figure}[!htb]
-  \footnotesize
-  \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct utmp
-{
-    short int ut_type;            /* Type of login.  */
-    pid_t ut_pid;                 /* Process ID of login process.  */
-    char ut_line[UT_LINESIZE];    /* Devicename.  */
-    char ut_id[4];                /* Inittab ID.  */
-    char ut_user[UT_NAMESIZE];    /* Username.  */
-    char ut_host[UT_HOSTSIZE];    /* Hostname for remote login.  */
-    struct exit_status ut_exit;   /* Exit status of a process marked
-                                     as DEAD_PROCESS.  */
-    long int ut_session;          /* Session ID, used for windowing.  */
-    struct timeval ut_tv;         /* Time entry was made.  */
-    int32_t ut_addr_v6[4];        /* Internet address of remote host.  */
-    char __unused[20];            /* Reserved for future use.  */
-};
-    \end{lstlisting}
-  \end{minipage} 
-  \normalsize 
-  \caption{La struttura \structd{utmp} contenente le informazioni di una voce
-    del database di \textit{accounting}.}
-  \label{fig:sys_utmp_struct}
-\end{figure}
-
 Con \func{getutid} si può cercare una voce specifica, a seconda del valore del
 campo \var{ut\_type} dell'argomento \param{ut}.  Questo può assumere i valori
 riportati in \tabref{tab:sys_ut_type}, quando assume i valori
@@ -1377,26 +1305,7 @@ di tipo \struct{rusage}, la cui definizione (che si trova in
   \footnotesize
   \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct rusage {
-    struct timeval ru_utime; /* user time used */
-    struct timeval ru_stime; /* system time used */
-    long ru_maxrss;          /* maximum resident set size */
-    long ru_ixrss;           /* integral shared memory size */
-    long ru_idrss;           /* integral unshared data size */
-    long ru_isrss;           /* integral unshared stack size */
-    long ru_minflt;          /* page reclaims */
-    long ru_majflt;          /* page faults */
-    long ru_nswap;           /* swaps */
-    long ru_inblock;         /* block input operations */
-    long ru_oublock;         /* block output operations */
-    long ru_msgsnd;          /* messages sent */
-    long ru_msgrcv;          /* messages received */
-    long ru_nsignals;   ;    /* signals received */
-    long ru_nvcsw;           /* voluntary context switches */
-    long ru_nivcsw;          /* involuntary context switches */
-};
-    \end{lstlisting}
+    \includestruct{listati/rusage.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{rusage} per la lettura delle informazioni dei 
@@ -1469,23 +1378,6 @@ struttura \struct{rlimit}, la cui definizione 
 \figref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a limite
 corrente e limite massimo.
 
-\begin{figure}[!htb]
-  \footnotesize
-  \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct rlimit {
-     rlim_t    rlim_cur;
-     rlim_t    rlim_max;
-};
-    \end{lstlisting}
-  \end{minipage} 
-  \normalsize 
-  \caption{La struttura \structd{rlimit} per impostare i limiti di utilizzo 
-    delle risorse usate da un processo.}
-  \label{fig:sys_rlimit_struct}
-\end{figure}
-
 In genere il superamento di un limite comporta o l'emissione di un segnale o
 il fallimento della system call che lo ha provocato; per permettere di leggere
 e di impostare i limiti di utilizzo delle risorse da parte di un processo
@@ -1514,6 +1406,20 @@ prototipi sono:
   ed \errval{EFAULT}.}
 \end{functions}
 
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/rlimit.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \structd{rlimit} per impostare i limiti di utilizzo 
+    delle risorse usate da un processo.}
+  \label{fig:sys_rlimit_struct}
+\end{figure}
+
+
+
 Entrambe le funzioni permettono di specificare, attraverso l'argomento
 \param{resource}, su quale risorsa si vuole operare: i possibili valori di
 questo argomento sono elencati in \secref{tab:sys_rlimit_values}. L'acceso
@@ -1808,14 +1714,7 @@ struttura di tipo \struct{tms}, la cui definizione 
   \footnotesize
   \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct tms {
-       clock_t tms_utime;  /* user time */
-       clock_t tms_stime;  /* system time */
-       clock_t tms_cutime; /* user time of children */
-       clock_t tms_cstime; /* system time of children */
-};
-    \end{lstlisting}
+    \includestruct{listati/tms.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{tms} dei tempi di processore associati a un
@@ -1908,17 +1807,7 @@ nanosecondo.\footnote{la precisione 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct timeval 
-{
-    long tv_sec;            /* seconds */
-    long tv_usec;           /* microseconds */
-};
-struct timespec {
-    time_t  tv_sec;         /* seconds */
-    long    tv_nsec;        /* nanoseconds */
-};
-    \end{lstlisting}
+    \includestruct{listati/timeval.h}
   \end{minipage} 
   \normalsize 
   \caption{Le strutture \structd{timeval} e \structd{timespec} usate per una
@@ -1971,29 +1860,7 @@ effettuato.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct timex {
-    unsigned int modes;   /* mode selector */
-    long int offset;      /* time offset (usec) */
-    long int freq;        /* frequency offset (scaled ppm) */
-    long int maxerror;    /* maximum error (usec) */
-    long int esterror;    /* estimated error (usec) */
-    int status;           /* clock command/status */
-    long int constant;    /* pll time constant */
-    long int precision;   /* clock precision (usec) (read only) */
-    long int tolerance;   /* clock frequency tolerance (ppm) (read only) */
-    struct timeval time;  /* (read only) */
-    long int tick;        /* (modified) usecs between clock ticks */
-    long int ppsfreq;     /* pps frequency (scaled ppm) (ro) */
-    long int jitter;      /* pps jitter (us) (ro) */
-    int shift;            /* interval duration (s) (shift) (ro) */
-    long int stabil;      /* pps stability (scaled ppm) (ro) */
-    long int jitcnt;      /* jitter limit exceeded (ro) */
-    long int calcnt;      /* calibration intervals (ro) */
-    long int errcnt;      /* calibration errors (ro) */
-    long int stbcnt;      /* stability limit exceeded (ro) */
-};
-    \end{lstlisting}
+    \includestruct{listati/timex.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{timex} per il controllo dell'orologio di
@@ -2128,31 +1995,6 @@ stata introdotta una ulteriore rappresentazione, detta \textit{broken-down
   time}, che permette appunto di \textsl{suddividere} il \textit{calendar
   time} usuale in ore, minuti, secondi, ecc.
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct tm {
-        int     tm_sec;         /* seconds */
-        int     tm_min;         /* minutes */
-        int     tm_hour;        /* hours */
-        int     tm_mday;        /* day of the month */
-        int     tm_mon;         /* month */
-        int     tm_year;        /* year */
-        int     tm_wday;        /* day of the week */
-        int     tm_yday;        /* day in the year */
-        int     tm_isdst;       /* daylight saving time */
-        long int tm_gmtoff;     /* Seconds east of UTC.  */
-        const char *tm_zone;    /* Timezone abbreviation.  */
-};
-    \end{lstlisting}
-  \end{minipage} 
-  \normalsize 
-  \caption{La struttura \structd{tm} per una rappresentazione del tempo in
-    termini di ora, minuti, secondi, ecc.}
-  \label{fig:sys_tm_struct}
-\end{figure}
-
 Questo viene effettuato attraverso una opportuna struttura \struct{tm}, la cui
 definizione è riportata in \figref{fig:sys_tm_struct}, ed è in genere questa
 struttura che si utilizza quando si deve specificare un tempo a partire dai
@@ -2192,6 +2034,19 @@ tempo in una stringa contenente data ed ora, i loro prototipi sono:
   restituisce direttamente il valore o -1 in caso di errore.}
 \end{functions}
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/tm.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \structd{tm} per una rappresentazione del tempo in
+    termini di ora, minuti, secondi, ecc.}
+  \label{fig:sys_tm_struct}
+\end{figure}
+
+
+
 Le prime due funzioni, \func{asctime} e \func{ctime} servono per poter
 stampare in forma leggibile un tempo; esse restituiscono il puntatore ad una
 stringa, allocata staticamente, nella forma:
@@ -2242,11 +2097,7 @@ verr
   \footnotesize
   \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-extern char *tzname[2];
-extern long timezone;
-extern int daylight;
-    \end{lstlisting}
+    \includestruct{listati/time_zone_var.c}
   \end{minipage} 
   \normalsize 
   \caption{Le variabili globali usate per la gestione delle \textit{time
@@ -2460,36 +2311,18 @@ punti e da uno spazio, il messaggio 
 
 Il messaggio può essere riportato anche usando altre variabili globali
 dichiarate in \file{errno.h}:
-\begin{verbatim}
-   const char *sys_errlist[];
-   int sys_nerr;
-\end{verbatim}
+\includecodesnip{listati/errlist.c}
 la prima contiene i puntatori alle stringhe di errore indicizzati da
 \var{errno}; la seconda esprime il valore più alto per un codice di errore,
 l'utilizzo di questa stringa è sostanzialmente equivalente a quello di
 \func{strerror}.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-    /* convert string to number */
-    err = strtol(argv[optind], NULL, 10);
-    /* testing error condition on conversion */
-    if (err==LONG_MIN) {
-        perror("Underflow on error code");
-        return 1;
-    } else if (err==LONG_MIN) {
-        perror("Overflow on error code");
-        return 1;
-    }
-    /* conversion is fine */
-    if (message) {
-        printf("Error message for %d is %s\n", err, strerror(err));
-    }
-    if (label) {
-        printf("Error label for %d is %s\n", err, err_code[err]);
-    }
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/errcode_mess.c}
+  \end{minipage}
+  \normalsize
   \caption{Codice per la stampa del messaggio di errore standard.}
   \label{fig:sys_err_mess}
 \end{figure}