Finita la conversione dei listati in file separati. Passato anche alla nuova
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 6 Apr 2003 00:47:57 +0000 (00:47 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 6 Apr 2003 00:47:57 +0000 (00:47 +0000)
versione di listings.

60 files changed:
elemtcp.tex
fileadv.tex
ipc.tex
listati/BarCode.c [new file with mode: 0644]
listati/BarCodePage.c [new file with mode: 0644]
listati/ClientEcho.c [new file with mode: 0644]
listati/ComputeValues.c [new file with mode: 0644]
listati/DirMonitor.c [new file with mode: 0644]
listati/EchoServerWrong.c [new file with mode: 0644]
listati/ElemDaytimeTCPClient.c [new file with mode: 0644]
listati/ElemDaytimeTCPCuncServ.c [new file with mode: 0644]
listati/ElemDaytimeTCPServer.c [new file with mode: 0644]
listati/ElemEchoTCPServer.c [new file with mode: 0644]
listati/Flock.c [new file with mode: 0644]
listati/FortuneClient.c [new file with mode: 0644]
listati/FortuneServer.c [new file with mode: 0644]
listati/FullRead.c [new file with mode: 0644]
listati/FullWrite.c [new file with mode: 0644]
listati/IPCTestId.c [new file with mode: 0644]
listati/LockFile.c [new file with mode: 0644]
listati/MQFortuneClient.c [new file with mode: 0644]
listati/MQFortuneServer.c [new file with mode: 0644]
listati/MemShared.c [new file with mode: 0644]
listati/Mutex.c [new file with mode: 0644]
listati/MutexLocking.c [new file with mode: 0644]
listati/ReadMonitor.c [new file with mode: 0644]
listati/ServEcho.c [new file with mode: 0644]
listati/SetTermAttr.c [new file with mode: 0644]
listati/SharedMem.c [new file with mode: 0644]
listati/UnSetTermAttr.c [new file with mode: 0644]
listati/aiocb.h [new file with mode: 0644]
listati/flock.h [new file with mode: 0644]
listati/iovec.h [new file with mode: 0644]
listati/ipc_perm.h [new file with mode: 0644]
listati/mq_attr.h [new file with mode: 0644]
listati/msgbuf.h [new file with mode: 0644]
listati/msqid_ds.h [new file with mode: 0644]
listati/oflag.c [new file with mode: 0644]
listati/pollfd.h [new file with mode: 0644]
listati/sem.h [new file with mode: 0644]
listati/sembuf.h [new file with mode: 0644]
listati/semid_ds.h [new file with mode: 0644]
listati/semun.h [new file with mode: 0644]
listati/serv_addr_sin6_addr.c [new file with mode: 0644]
listati/serv_addr_sin_addr.c [new file with mode: 0644]
listati/shmid_ds.h [new file with mode: 0644]
listati/sigchildhand.c [new file with mode: 0644]
listati/sigevent.h [new file with mode: 0644]
listati/sockaddr.h [new file with mode: 0644]
listati/sockaddr_atalk.h [new file with mode: 0644]
listati/sockaddr_in.h [new file with mode: 0644]
listati/sockaddr_in6.h [new file with mode: 0644]
listati/sockaddr_ll.h [new file with mode: 0644]
listati/sockaddr_un.h [new file with mode: 0644]
listati/termios.h [new file with mode: 0644]
listati/value_c_cc.c [new file with mode: 0644]
session.tex
signal.tex
simpltcp.tex
socket.tex

index efd8a05810496e08f9d12053cdf117608bab15b9..fc1d1d754ac362ea8e0caeee8f93579599fce698 100644 (file)
@@ -700,10 +700,7 @@ Per specificare un indirizzo generico con IPv4 si usa il valore
 \const{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
 è pari a zero, nell'esempio \figref{fig:net_serv_code} si è usata
 un'assegnazione immediata del tipo:
 \const{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
 è pari a zero, nell'esempio \figref{fig:net_serv_code} si è usata
 un'assegnazione immediata del tipo:
-
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
-\end{lstlisting}
+\includecodesnip{listati/serv_addr_sin_addr.c}
 
 Si noti che si è usato \func{htonl} per assegnare il valore
 \const{INADDR\_ANY}, benché essendo questo pari a zero il riordinamento sia
 
 Si noti che si è usato \func{htonl} per assegnare il valore
 \const{INADDR\_ANY}, benché essendo questo pari a zero il riordinamento sia
@@ -741,9 +738,7 @@ Per questo motivo nell'header \file{netinet/in.h} 
 \const{in6addr\_any} (dichiarata come \direct{extern}, ed inizializzata dal
 sistema al valore \const{IN6ADRR\_ANY\_INIT}) che permette di effettuare una
 assegnazione del tipo:
 \const{in6addr\_any} (dichiarata come \direct{extern}, ed inizializzata dal
 sistema al valore \const{IN6ADRR\_ANY\_INIT}) che permette di effettuare una
 assegnazione del tipo:
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    serv_add.sin6_addr = in6addr_any;   /* connect from anywhere */
-\end{lstlisting}
+\includecodesnip{listati/serv_addr_sin6_addr.c}
 in maniera analoga si può utilizzare la variabile \const{in6addr\_loopback}
 per indicare l'indirizzo di \textit{loopback}, che a sua volta viene
 inizializzata staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}.
 in maniera analoga si può utilizzare la variabile \const{in6addr\_loopback}
 per indicare l'indirizzo di \textit{loopback}, che a sua volta viene
 inizializzata staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}.
@@ -1121,61 +1116,11 @@ rispetto al precedente esempio. Al solito il sorgente completo del server
 \file{ElemDaytimeTCPCuncServ.c} è allegato nella directory dei sorgenti.
 
 \begin{figure}[!htb]
 \file{ElemDaytimeTCPCuncServ.c} è allegato nella directory dei sorgenti.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <sys/types.h>   /* predefined types */
-#include <unistd.h>      /* include unix standard library */
-#include <arpa/inet.h>   /* IP addresses conversion utililites */
-#include <sys/socket.h>  /* socket library */
-#include <stdio.h>       /* include standard I/O library */
-#include <time.h>
-
-int main(int argc, char *argv[])
-{
-    int list_fd, conn_fd;
-    int i;
-    struct sockaddr_in serv_add, client;
-    char buffer[MAXLINE];
-    socklen_t len;
-    time_t timeval;
-    pid_t pid;
-    int logging=0;
-     ...
-    /* write daytime to client */
-    while (1) {
-        if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) 
-             <0 ) {
-            perror("accept error");
-            exit(-1);
-        }
-        /* fork to handle connection */
-        if ( (pid = fork()) < 0 ){
-            perror("fork error");
-            exit(-1);
-        }
-        if (pid == 0) {                 /* child */
-            close(list_fd);
-            timeval = time(NULL);
-            snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
-            if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
-                perror("write error");
-                exit(-1);
-            }
-            if (logging) {
-                inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer));
-                printf("Request from host %s, port %d\n", buffer,
-                       ntohs(client.sin_port));
-            }
-            close(conn_fd);
-            exit(0);
-        } else {                        /* parent */
-            close(conn_fd);
-        }
-    }
-    /* normal exit, never reached */
-    exit(0);
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/ElemDaytimeTCPCuncServ.c}
+  \end{minipage} 
+  \normalsize
   \caption{Esempio di codice di un server concorrente elementare per il 
     servizio daytime.}
   \label{fig:TCPel_serv_code}
   \caption{Esempio di codice di un server concorrente elementare per il 
     servizio daytime.}
   \label{fig:TCPel_serv_code}
index 9980d895a06ce42c75840ee22a1aff8f3f75dd21..d184c31ba02b16833ce9c7ae34913324dee4fb1b 100644 (file)
@@ -211,17 +211,11 @@ negativo indica un'attesa indefinita).
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct pollfd {
-        int fd;           /* file descriptor */
-        short events;     /* requested events */
-        short revents;    /* returned events */
-};
-    \end{lstlisting}
+    \includestruct{listati/pollfd.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{pollfd}, utilizzata per specificare le modalità
-    di controllo di un file descriptor alla funzione \func{poll}.}
+  \caption{La struttura \structd{pollfd}, utilizzata per specificare le
+    modalità di controllo di un file descriptor alla funzione \func{poll}.}
   \label{fig:file_pollfd}
 \end{figure}
 
   \label{fig:file_pollfd}
 \end{figure}
 
@@ -421,21 +415,10 @@ disponibilit
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct aiocb
-{
-    int aio_fildes;               /* File descriptor.  */
-    off_t aio_offset;             /* File offset */
-    int aio_lio_opcode;           /* Operation to be performed.  */
-    int aio_reqprio;              /* Request priority offset.  */
-    volatile void *aio_buf;       /* Location of buffer.  */
-    size_t aio_nbytes;            /* Length of transfer.  */
-    struct sigevent aio_sigevent; /* Signal number and value.  */
-};
-    \end{lstlisting}
+    \includestruct{listati/aiocb.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{aiocb}, usata per il controllo dell'I/O
+  \caption{La struttura \structd{aiocb}, usata per il controllo dell'I/O
     asincrono.}
   \label{fig:file_aiocb}
 \end{figure}
     asincrono.}
   \label{fig:file_aiocb}
 \end{figure}
@@ -471,20 +454,11 @@ esse.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sigevent
-{
-    sigval_t sigev_value;
-    int sigev_signo;
-    int sigev_notify;
-    void (*sigev_notify_function)(sigval_t);
-    pthread_attr_t *sigev_notify_attributes;
-};
-    \end{lstlisting}
+    \includestruct{listati/sigevent.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{sigevent}, usata per specificare le modalità di
-    notifica degli eventi relativi alle operazioni di I/O asincrono.}
+  \caption{La struttura \structd{sigevent}, usata per specificare le modalità
+    di notifica degli eventi relativi alle operazioni di I/O asincrono.}
   \label{fig:file_sigevent}
 \end{figure}
 
   \label{fig:file_sigevent}
 \end{figure}
 
@@ -818,15 +792,10 @@ il secondo, \var{iov\_len}, la dimensione dello stesso.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct iovec {
-    __ptr_t iov_base;    /* Starting address */
-    size_t iov_len;      /* Length in bytes  */
-};
-    \end{lstlisting}
+    \includestruct{listati/iovec.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{iovec}, usata dalle operazioni di I/O
+  \caption{La struttura \structd{iovec}, usata dalle operazioni di I/O
     vettorizzato.} 
   \label{fig:file_iovec}
 \end{figure}
     vettorizzato.} 
   \label{fig:file_iovec}
 \end{figure}
@@ -1512,18 +1481,10 @@ regione bloccata.
 \begin{figure}[!bht]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!bht]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct flock {
-    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
-    short int l_whence; /* Where `l_start' is relative to (like `lseek').*/
-    off_t l_start;      /* Offset where the lock begins.  */
-    off_t l_len;        /* Size of the locked area; zero means until EOF.*/
-    pid_t l_pid;        /* Process holding the lock.  */
-};
-    \end{lstlisting}
+    \includestruct{listati/flock.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{flock}, usata da \func{fcntl} per il file
+  \caption{La struttura \structd{flock}, usata da \func{fcntl} per il file
     locking.} 
   \label{fig:struct_flock}
 \end{figure}
     locking.} 
   \label{fig:struct_flock}
 \end{figure}
@@ -1717,60 +1678,7 @@ necessario a soddisfare l'operazione richiesta.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int main(int argc, char *argv[])
-{
-    int type = F_UNLCK;            /* lock type: default to unlock (invalid) */
-    off_t start = 0;             /* start of the locked region: default to 0 */
-    off_t len = 0;              /* length of the locked region: default to 0 */
-    int fd, res, i;                                    /* internal variables */
-    int bsd = 0;                          /* semantic type: default to POSIX */
-    int cmd = F_SETLK;              /* lock command: default to non-blocking */
-    struct flock lock;                                /* file lock structure */
-    ...
-    if ((argc - optind) != 1) {          /* There must be remaing parameters */
-        printf("Wrong number of arguments %d\n", argc - optind);
-        usage();
-    }
-    if (type == F_UNLCK) {            /* There must be a -w or -r option set */
-        printf("You should set a read or a write lock\n");
-        usage();
-    }
-    fd = open(argv[optind], O_RDWR);           /* open the file to be locked */
-    if (fd < 0) {                                           /* on error exit */
-        perror("Wrong filename");
-        exit(1);
-    }
-    /* do lock */
-    if (bsd) {                                             /* if BSD locking */
-        /* rewrite cmd for suitables flock operation values */ 
-        if (cmd == F_SETLKW) {                             /* if no-blocking */
-            cmd = LOCK_NB;              /* set the value for flock operation */
-        } else {                                                     /* else */
-            cmd = 0;                                      /* default is null */
-        }
-        if (type == F_RDLCK) cmd |= LOCK_SH;          /* set for shared lock */
-        if (type == F_WRLCK) cmd |= LOCK_EX;       /* set for exclusive lock */
-        res = flock(fd, cmd);                                /* esecute lock */
-    } else {                                             /* if POSIX locking */
-        /* setting flock structure */
-        lock.l_type = type;                       /* set type: read or write */
-        lock.l_whence = SEEK_SET;    /* start from the beginning of the file */
-        lock.l_start = start;          /* set the start of the locked region */
-        lock.l_len = len;             /* set the length of the locked region */
-        res = fcntl(fd, cmd, &lock);                              /* do lock */
-    }
-    /* check lock results */
-    if (res) {                                              /* on error exit */
-        perror("Failed lock");
-        exit(1);
-    } else {                                           /* else write message */
-        printf("Lock acquired\n");
-    }
-    pause();                       /* stop the process, use a signal to exit */
-    return 0;
-}
-    \end{lstlisting}
+    \includecodesample{listati/Flock.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del programma \file{Flock.c}.}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del programma \file{Flock.c}.}
diff --git a/ipc.tex b/ipc.tex
index e4c32b7bca1b8eaa53e26ab804fde1b6b1aeda6b..bd3aa42858b4f77c4595107f2950157a89e31e0f 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -190,55 +190,7 @@ nel file \file{BarCodePage.c} che si trova nella directory dei sorgenti.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int main(int argc, char *argv[], char *envp[])
-{
-    ...
-    /* create two pipes, pipein and pipeout, to handle communication */
-    if ( (retval = pipe(pipein)) ) {
-        WriteMess("input pipe creation error");
-        exit(0);        
-    }
-    if ( (retval = pipe(pipeout)) ) {
-        WriteMess("output pipe creation error");
-        exit(0);        
-    }    
-    /* First fork: use child to run barcode program */
-    if ( (pid = fork()) == -1) {          /* on error exit */
-        WriteMess("child creation error");
-        exit(0);        
-    }
-    /* if child */
-    if (pid == 0) {
-        close(pipein[1]);                /* close pipe write end  */
-        dup2(pipein[0], STDIN_FILENO);   /* remap stdin to pipe read end */
-        close(pipeout[0]);
-        dup2(pipeout[1], STDOUT_FILENO); /* remap stdout in pipe output */
-        execlp("barcode", "barcode", size, NULL);
-    } 
-    close(pipein[0]);                    /* close input side of input pipe */
-    write(pipein[1], argv[1], strlen(argv[1]));  /* write parameter to pipe */
-    close(pipein[1]);                    /* closing write end */
-    waitpid(pid, NULL, 0);               /* wait child completion */
-    /* Second fork: use child to run ghostscript */
-    if ( (pid = fork()) == -1) {
-        WriteMess("child creation error");
-        exit(0);
-    }
-    /* second child, convert PS to JPEG  */
-    if (pid == 0) {                     
-        close(pipeout[1]);              /* close write end */
-        dup2(pipeout[0], STDIN_FILENO); /* remap read end to stdin */
-        /* send mime type */
-        write(STDOUT_FILENO, content, strlen(content));
-        execlp("gs", "gs", "-q", "-sDEVICE=jpeg", "-sOutputFile=-", "-", NULL);
-    }
-    /* still parent */
-    close(pipeout[1]); 
-    waitpid(pid, NULL, 0);
-    exit(0);
-}
-    \end{lstlisting}
+    \includecodesample{listati/BarCodePage.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del \textit{CGI} 
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del \textit{CGI} 
@@ -423,37 +375,7 @@ invocato dopo.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int main(int argc, char *argv[], char *envp[])
-{
-    FILE *pipe[4];
-    FILE *pipein;
-    char *cmd_string[4]={
-        "pnmtopng",
-        "pnmmargin -white 10",
-        "pnmcrop",
-        "gs -sDEVICE=ppmraw -sOutputFile=- -sNOPAUSE -q - -c showpage -c quit"
-    };  
-    char content[]="Content-type: image/png\n\n";
-    int i;
-    /* write mime-type to stdout */ 
-    write(STDOUT_FILENO, content, strlen(content));
-    /* execute chain of command */
-    for (i=0; i<4; i++) {
-        pipe[i] = popen(cmd_string[i], "w");
-        dup2(fileno(pipe[i]), STDOUT_FILENO); 
-    }
-    /* create barcode (in PS) */
-    pipein = popen("barcode", "w");
-    /* send barcode string to barcode program */
-    write(fileno(pipein), argv[1], strlen(argv[1]));
-    /* close all pipes (in reverse order) */
-    for (i=4; i==0; i--) {
-        pclose((pipe[i]));
-    }
-    exit(0);
-}
-    \end{lstlisting}
+    \includecodesample{listati/BarCode.c}
   \end{minipage} 
   \normalsize 
   \caption{Codice completo del \textit{CGI} \file{BarCode.c}.}
   \end{minipage} 
   \normalsize 
   \caption{Codice completo del \textit{CGI} \file{BarCode.c}.}
@@ -594,60 +516,7 @@ diverso da quelli preimpostati. Il codice completo 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-char *fifoname = "/tmp/fortune.fifo";
-int main(int argc, char *argv[])
-{
-/* Variables definition */
-    int i, n = 0;
-    char *fortunefilename = "/usr/share/games/fortunes/linux";
-    char **fortune;
-    char line[80];
-    int fifo_server, fifo_client;
-    int nread;
-    ...
-    if (n==0) usage();          /* if no pool depth exit printing usage info */
-    Signal(SIGTERM, HandSIGTERM);            /* set handlers for termination */
-    Signal(SIGINT, HandSIGTERM);
-    Signal(SIGQUIT, HandSIGTERM);
-    i = FortuneParse(fortunefilename, fortune, n);          /* parse phrases */
-    if (mkfifo(fifoname, 0622)) {  /* create well known fifo if does't exist */
-        if (errno!=EEXIST) {
-            perror("Cannot create well known fifo");
-            exit(1);
-        }
-    }
-    daemon(0, 0);
-    /* open fifo two times to avoid EOF */
-    fifo_server = open(fifoname, O_RDONLY);
-    if (fifo_server < 0) {
-        perror("Cannot open read only well known fifo");
-        exit(1);
-    }
-    if (open(fifoname, O_WRONLY) < 0) {                        
-        perror("Cannot open write only well known fifo");
-        exit(1);
-    }
-    /* Main body: loop over requests */
-    while (1) {
-        nread = read(fifo_server, line, 79);                 /* read request */
-        if (nread < 0) {
-            perror("Read Error");
-            exit(1);
-        }
-        line[nread] = 0;                       /* terminate fifo name string */
-        n = random() % i;                             /* select random value */
-        fifo_client = open(line, O_WRONLY);              /* open client fifo */
-        if (fifo_client < 0) {
-            perror("Cannot open");
-            exit(1);
-        }
-        nread = write(fifo_client,                           /* write phrase */
-                      fortune[n], strlen(fortune[n])+1);
-        close(fifo_client);                             /* close client fifo */
-    }
-}
-    \end{lstlisting}
+    \includecodesample{listati/FortuneServer.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del server di \textit{fortunes}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del server di \textit{fortunes}
@@ -737,44 +606,7 @@ principale del programma e le definizioni delle variabili. Il codice completo
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int main(int argc, char *argv[])
-{
-/* Variables definition */
-    int n = 0;
-    char *fortunefilename = "/tmp/fortune.fifo";
-    char line[80];
-    int fifo_server, fifo_client;
-    char fifoname[80];
-    int nread;
-    char buffer[PIPE_BUF];
-    ...
-    snprintf(fifoname, 80, "/tmp/fortune.%d", getpid());     /* compose name */
-    if (mkfifo(fifoname, 0622)) {                        /* open client fifo */
-        if (errno!=EEXIST) {
-            perror("Cannot create well known fifo");
-            exit(-1);
-        }
-    }
-    fifo_server = open(fortunefilename, O_WRONLY);       /* open server fifo */
-    if (fifo_server < 0) {
-        perror("Cannot open well known fifo");
-        exit(-1);
-    }
-    nread = write(fifo_server, fifoname, strlen(fifoname)+1);  /* write name */
-    close(fifo_server);                                 /* close server fifo */
-    fifo_client = open(fifoname, O_RDONLY);              /* open client fifo */
-    if (fifo_client < 0) {
-        perror("Cannot open well known fifo");
-        exit(-1);
-    }
-    nread = read(fifo_client, buffer, sizeof(buffer));        /* read answer */
-    printf("%s", buffer);                                   /* print fortune */
-    close(fifo_client);                                      /* close client */
-    close(fifo_server);                                      /* close server */
-    unlink(fifoname);                                  /* remove client fifo */
-}
-    \end{lstlisting}
+    \includecodesample{listati/FortuneClient.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del client di \textit{fortunes}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del client di \textit{fortunes}
@@ -1002,18 +834,7 @@ mantiene varie propriet
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}%,frame=,indent=1cm ]{}
-struct ipc_perm
-{
-    key_t key;                        /* Key.  */
-    uid_t uid;                        /* Owner's user ID.  */
-    gid_t gid;                        /* Owner's group ID.  */
-    uid_t cuid;                       /* Creator's user ID.  */
-    gid_t cgid;                       /* Creator's group ID.  */
-    unsigned short int mode;          /* Read/write permission.  */
-    unsigned short int seq;           /* Sequence number.  */
-};
-    \end{lstlisting}
+    \includestruct{listati/ipc_perm.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{ipc\_perm}, come definita in
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{ipc\_perm}, come definita in
@@ -1210,41 +1031,7 @@ s
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int main(int argc, char *argv[])
-{
-    ...
-    switch (type) {
-    case 'q':   /* Message Queue */
-        debug("Message Queue Try\n");
-        for (i=0; i<n; i++) {
-            id = msgget(IPC_PRIVATE, IPC_CREAT|0666);
-            printf("Identifier Value %d \n", id);
-            msgctl(id, IPC_RMID, NULL);
-        }
-        break;
-    case 's':   /* Semaphore */
-        debug("Semaphore\n");
-        for (i=0; i<n; i++) {
-            id = semget(IPC_PRIVATE, 1, IPC_CREAT|0666);
-            printf("Identifier Value %d \n", id);
-            semctl(id, 0, IPC_RMID);
-        }
-        break;
-    case 'm':   /* Shared Memory */
-        debug("Shared Memory\n");
-        for (i=0; i<n; i++) {
-            id = shmget(IPC_PRIVATE, 1000, IPC_CREAT|0666);
-            printf("Identifier Value %d \n", id);
-            shmctl(id, IPC_RMID, NULL);
-        }
-        break;
-    default:    /* should not reached */
-        return -1;
-    }
-    return 0;
-}
-    \end{lstlisting}
+    \includecodesample{listati/IPCTestId.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del programma di test per l'assegnazione degli
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del programma di test per l'assegnazione degli
@@ -1415,21 +1202,7 @@ kernel.\footnote{lo schema illustrato in \figref{fig:ipc_mq_schema} 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct msqid_ds {
-    struct ipc_perm msg_perm;     /* structure for operation permission */
-    time_t msg_stime;             /* time of last msgsnd command */
-    time_t msg_rtime;             /* time of last msgrcv command */
-    time_t msg_ctime;             /* time of last change */
-    msgqnum_t msg_qnum;           /* number of messages currently on queue */
-    msglen_t msg_qbytes;          /* max number of bytes allowed on queue */
-    pid_t msg_lspid;              /* pid of last msgsnd() */
-    pid_t msg_lrpid;              /* pid of last msgrcv() */
-    struct msg *msg_first;        /* first message on queue, unused  */
-    struct msg *msg_last;         /* last message in queue, unused */
-    unsigned long int msg_cbytes; /* current number of bytes on queue */
-};
-    \end{lstlisting}
+    \includestruct{listati/msqid_ds.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{msqid\_ds}, associata a ciascuna coda di
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{msqid\_ds}, associata a ciascuna coda di
@@ -1455,7 +1228,7 @@ Quando si crea una nuova coda con \func{msgget} questa struttura viene
 inizializzata, in particolare il campo \var{msg\_perm} viene inizializzato
 come illustrato in \secref{sec:ipc_sysv_access_control}, per quanto riguarda
 gli altri campi invece:
 inizializzata, in particolare il campo \var{msg\_perm} viene inizializzato
 come illustrato in \secref{sec:ipc_sysv_access_control}, per quanto riguarda
 gli altri campi invece:
-\begin{itemize}
+\begin{itemize*}
 \item il campo \var{msg\_qnum}, che esprime il numero di messaggi presenti
   sulla coda, viene inizializzato a 0.
 \item i campi \var{msg\_lspid} e \var{msg\_lrpid}, che esprimono
 \item il campo \var{msg\_qnum}, che esprime il numero di messaggi presenti
   sulla coda, viene inizializzato a 0.
 \item i campi \var{msg\_lspid} e \var{msg\_lrpid}, che esprimono
@@ -1474,7 +1247,7 @@ gli altri campi invece:
   \var{msg\_cbytes}, che esprime la dimensione in byte dei messaggi presenti è
   inizializzato a zero. Questi campi sono ad uso interno dell'implementazione
   e non devono essere utilizzati da programmi in user space).
   \var{msg\_cbytes}, che esprime la dimensione in byte dei messaggi presenti è
   inizializzato a zero. Questi campi sono ad uso interno dell'implementazione
   e non devono essere utilizzati da programmi in user space).
-\end{itemize}
+\end{itemize*}
 
 Una volta creata una coda di messaggi le operazioni di controllo vengono
 effettuate con la funzione \funcd{msgctl}, che (come le analoghe \func{semctl}
 
 Una volta creata una coda di messaggi le operazioni di controllo vengono
 effettuate con la funzione \funcd{msgctl}, che (come le analoghe \func{semctl}
@@ -1595,12 +1368,7 @@ dovr
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-    struct msgbuf {
-         long mtype;          /* message type, must be > 0 */
-         char mtext[LENGTH];  /* message data */
-    };
-    \end{lstlisting}
+    \includestruct{listati/msgbuf.h}
   \end{minipage} 
   \normalsize 
   \caption{Schema della struttura \structd{msgbuf}, da utilizzare come
   \end{minipage} 
   \normalsize 
   \caption{Schema della struttura \structd{msgbuf}, da utilizzare come
@@ -1755,57 +1523,8 @@ in maniera indipendente con client diversi.
 
 \begin{figure}[!bht]
   \footnotesize \centering
 
 \begin{figure}[!bht]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int msgid;                                       /* Message queue identifier */
-int main(int argc, char *argv[])
-{
-/* Variables definition */
-    int i, n = 0;
-    char **fortune;                       /* array of fortune message string */
-    char *fortunefilename = "/usr/share/games/fortunes/linux";  /* file name */
-    struct msgbuf_read {      /* message struct to read request from clients */
-        long mtype;                               /* message type, must be 1 */
-        long pid;             /* message data, must be the pid of the client */
-    } msg_read;
-    struct msgbuf_write {       /* message struct to write result to clients */
-        long mtype;            /* message type, will be the pid of the client*/
-        char mtext[MSGMAX];             /* message data, will be the fortune */
-    } msg_write;
-    key_t key;                                          /* Message queue key */
-    int size;                                                /* message size */
-    ...
-    Signal(SIGTERM, HandSIGTERM);            /* set handlers for termination */
-    Signal(SIGINT, HandSIGTERM);
-    Signal(SIGQUIT, HandSIGTERM);
-    if (n==0) usage();          /* if no pool depth exit printing usage info */
-    i = FortuneParse(fortunefilename, fortune, n);          /* parse phrases */
-    /* Create the queue */
-    key = ftok("./MQFortuneServer.c", 1); 
-    msgid = msgget(key, IPC_CREAT|0666);
-    if (msgid < 0) {
-        perror("Cannot create message queue");
-        exit(1);
-    }
-    /* Main body: loop over requests */
-    daemon(0, 0);
-    while (1) {
-        msgrcv(msgid, &msg_read, sizeof(int), 1, MSG_NOERROR);
-        n = random() % i;                             /* select random value */
-        strncpy(msg_write.mtext, fortune[n], MSGMAX);
-        size = min(strlen(fortune[n])+1, MSGMAX);  
-        msg_write.mtype=msg_read.pid;             /* use request pid as type */
-        msgsnd(msgid, &msg_write, size, 0);
-    }
-}
-/*
- * Signal Handler to manage termination
- */
-void HandSIGTERM(int signo) {
-    msgctl(msgid, IPC_RMID, NULL);                   /* remove message queue */
-    exit(0);
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/MQFortuneServer.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del server di \textit{fortunes}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del server di \textit{fortunes}
@@ -1878,26 +1597,8 @@ gestore \code{HandSIGTERM}, che semplicemente si limita a cancellare la coda
 
 \begin{figure}[!bht]
   \footnotesize \centering
 
 \begin{figure}[!bht]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int main(int argc, char *argv[])
-{
-    ...
-    key = ftok("./MQFortuneServer.c", 1); 
-    msgid = msgget(key, 0); 
-    if (msgid < 0) {
-        perror("Cannot find message queue");
-        exit(1);
-    }
-    /* Main body: do request and write result */
-    msg_read.mtype = 1;                      /* type for request is always 1 */
-    msg_read.pid = getpid();                   /* use pid for communications */
-    size = sizeof(msg_read.pid);  
-    msgsnd(msgid, &msg_read, size, 0);               /* send request message */
-    msgrcv(msgid, &msg_write, MSGMAX, msg_read.pid, MSG_NOERROR);
-    printf("%s", msg_write.mtext);
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/MQFortuneClient.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del client di \textit{fortunes}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del client di \textit{fortunes}
@@ -2087,15 +1788,7 @@ semaforo all'uscita del processo.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct semid_ds
-{
-    struct ipc_perm sem_perm;           /* operation permission struct */
-    time_t sem_otime;                   /* last semop() time */
-    time_t sem_ctime;                   /* last time changed by semctl() */
-    unsigned long int sem_nsems;        /* number of semaphores in set */
-};
-    \end{lstlisting}
+    \includestruct{listati/semid_ds.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{semid\_ds}, associata a ciascun insieme di
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{semid\_ds}, associata a ciascun insieme di
@@ -2137,14 +1830,7 @@ controllo.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sem {
-  short   sempid;         /* pid of last operation */
-  ushort  semval;         /* current value */
-  ushort  semncnt;        /* num procs awaiting increase in semval */
-  ushort  semzcnt;        /* num procs awaiting semval = 0 */
-};
-    \end{lstlisting}
+    \includestruct{listati/sem.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{sem}, che contiene i dati di un singolo
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{sem}, che contiene i dati di un singolo
@@ -2234,15 +1920,7 @@ specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-union semun {
-      int val;                  /* value for SETVAL */
-      struct semid_ds *buf;     /* buffer for IPC_STAT, IPC_SET */
-      unsigned short *array;    /* array for GETALL, SETALL */
-                                /* Linux specific part: */
-      struct seminfo *__buf;    /* buffer for IPC_INFO */
-};
-    \end{lstlisting}
+    \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
   \caption{La definizione dei possibili valori di una \direct{union}
   \end{minipage} 
   \normalsize 
   \caption{La definizione dei possibili valori di una \direct{union}
@@ -2388,14 +2066,7 @@ effettivamente eseguite se e soltanto se 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sembuf
-{
-  unsigned short int sem_num;   /* semaphore number */
-  short int sem_op;             /* semaphore operation */
-  short int sem_flg;            /* operation flag */
-};
-    \end{lstlisting}
+    \includestruct{listati/sembuf.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{sembuf}, usata per le operazioni sui
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{sembuf}, usata per le operazioni sui
@@ -2571,57 +2242,7 @@ nullo per segnalarne l'indisponibilit
 \begin{figure}[!bht]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!bht]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-/* Function MutexCreate: create a mutex/semaphore */
-int MutexCreate(key_t ipc_key) 
-{
-    const union semun semunion={1};             /* semaphore union structure */
-    int sem_id, ret;
-    sem_id = semget(ipc_key, 1, IPC_CREAT|0666);         /* get semaphore ID */
-    if (sem_id == -1) {                              /* if error return code */
-        return sem_id;
-    }
-    ret = semctl(sem_id, 0, SETVAL, semunion);             /* init semaphore */
-    if (ret == -1) {
-        return ret;
-    }
-    return sem_id;
-}
-/* Function MutexFind: get the semaphore/mutex Id given the IPC key value */
-int MutexFind(key_t ipc_key) 
-{
-    return semget(ipc_key,1,0);
-}
-/* Function MutexRead: read the current value of the mutex/semaphore */
-int MutexRead(int sem_id) 
-{
-    return semctl(sem_id, 0, GETVAL);
-}
-/* Define sembuf structures to lock and unlock the semaphore  */
-struct sembuf sem_lock={                                /* to lock semaphore */
-    0,                                   /* semaphore number (only one so 0) */
-    -1,                                    /* operation (-1 to use resource) */
-    SEM_UNDO};                                /* flag (set for undo at exit) */
-struct sembuf sem_ulock={                             /* to unlock semaphore */
-    0,                                   /* semaphore number (only one so 0) */
-    1,                                  /* operation (1 to release resource) */
-    SEM_UNDO};                                      /* flag (in this case 0) */
-/* Function MutexLock: to lock a mutex/semaphore */
-int MutexLock(int sem_id) 
-{
-    return semop(sem_id, &sem_lock, 1);
-}
-/* Function MutexUnlock: to unlock a mutex/semaphore */
-int MutexUnlock(int sem_id) 
-{
-    return semop(sem_id, &sem_ulock, 1);
-}
-/* Function MutexRemove: remove a mutex/semaphore */
-int MutexRemove(int sem_id) 
-{
-    return semctl(sem_id, 0, IPC_RMID);
-}
-    \end{lstlisting}
+    \includecodesample{listati/Mutex.c}
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono di creare o recuperare
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono di creare o recuperare
@@ -2749,18 +2370,7 @@ norma, significa insieme a dei semafori.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct shmid_ds {
-     struct    ipc_perm shm_perm;  /* operation perms */
-     int  shm_segsz;               /* size of segment (bytes) */
-     time_t    shm_atime;          /* last attach time */
-     time_t    shm_dtime;          /* last detach time */
-     time_t    shm_ctime;          /* last change time */
-     unsigned short shm_cpid;      /* pid of creator */
-     unsigned short shm_lpid;      /* pid of last operator */
-     short     shm_nattch;         /* no. of current attaches */
-};
-    \end{lstlisting}
+    \includestruct{listati/shmid_ds.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{shmid\_ds}, associata a ciascun segmento di
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{shmid\_ds}, associata a ciascun segmento di
@@ -2776,7 +2386,7 @@ campo \var{shm\_perm} viene inizializzato come illustrato in
 \secref{sec:ipc_sysv_access_control}, e valgono le considerazioni ivi fatte
 relativamente ai permessi di accesso; per quanto riguarda gli altri campi
 invece:
 \secref{sec:ipc_sysv_access_control}, e valgono le considerazioni ivi fatte
 relativamente ai permessi di accesso; per quanto riguarda gli altri campi
 invece:
-\begin{itemize*}
+\begin{itemize}
 \item il campo \var{shm\_segsz}, che esprime la dimensione del segmento, viene
   inizializzato al valore di \param{size}.
 \item il campo \var{shm\_ctime}, che esprime il tempo di creazione del
 \item il campo \var{shm\_segsz}, che esprime la dimensione del segmento, viene
   inizializzato al valore di \param{size}.
 \item il campo \var{shm\_ctime}, che esprime il tempo di creazione del
@@ -2790,7 +2400,7 @@ invece:
   creato il segmento, viene inizializzato al \acr{pid} del processo chiamante.
 \item il campo \var{shm\_nattac}, che esprime il numero di processi agganciati
   al segmento viene inizializzato a zero.
   creato il segmento, viene inizializzato al \acr{pid} del processo chiamante.
 \item il campo \var{shm\_nattac}, che esprime il numero di processi agganciati
   al segmento viene inizializzato a zero.
-\end{itemize*}
+\end{itemize}
 
 Come per le code di messaggi e gli insiemi di semafori, anche per i segmenti
 di memoria condivisa esistono una serie di limiti imposti dal sistema.  Alcuni
 
 Come per le code di messaggi e gli insiemi di semafori, anche per i segmenti
 di memoria condivisa esistono una serie di limiti imposti dal sistema.  Alcuni
@@ -3044,67 +2654,10 @@ In caso di successo la funzione aggiorna anche i seguenti campi di
 inoltre la regione di indirizzi usata per il segmento di memoria condivisa
 viene tolta dallo spazio di indirizzi del processo.
 
 inoltre la regione di indirizzi usata per il segmento di memoria condivisa
 viene tolta dallo spazio di indirizzi del processo.
 
-Come esempio di uso di queste funzioni vediamo come implementare una serie di
-funzioni di libreria che ne semplifichino l'uso, automatizzando le operazioni
-più comuni; il codice, contenuto nel file \file{SharedMem.c}, è riportato in
-\figref{fig:ipc_sysv_shm_func}.
-
 \begin{figure}[!bht]
   \footnotesize \centering
 \begin{figure}[!bht]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-/* Function ShmCreate  Create a SysV shared memory segment */
-void * ShmCreate(key_t ipc_key, int shm_size, int perm, int fill) 
-{
-    void * shm_ptr;
-    int shm_id;                       /* ID of the IPC shared memory segment */
-    shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm);        /* get shm ID */
-    if (shm_id < 0) { 
-        return NULL;
-    }
-    shm_ptr = shmat(shm_id, NULL, 0);                  /* map it into memory */
-    if (shm_ptr < 0) {
-        return NULL;
-    }
-    memset((void *)shm_ptr, fill, shm_size);                 /* fill segment */
-    return shm_ptr;
-}
-/* Function ShmFind: Find a SysV shared memory segment  */
-void * ShmFind(key_t ipc_key, int shm_size) 
-{
-    void * shm_ptr;
-    int shm_id;                      /* ID of the SysV shared memory segment */
-    shm_id = shmget(ipc_key, shm_size, 0);          /* find shared memory ID */
-    if (shm_id < 0) {
-        return NULL;
-    }
-    shm_ptr = shmat(shm_id, NULL, 0);                  /* map it into memory */
-    if (shm_ptr < 0) {
-        return NULL;
-    }
-    return shm_ptr;
-}
-/* Function ShmRemove: Schedule removal for a SysV shared memory segment  */
-int ShmRemove(key_t ipc_key, void * shm_ptr) 
-{
-    int shm_id;                      /* ID of the SysV shared memory segment */
-    /* first detach segment */
-    if (shmdt(shm_ptr) < 0) {
-        return -1;
-    }
-    /* schedule segment removal */
-    shm_id = shmget(ipc_key, 0, 0);                 /* find shared memory ID */
-    if (shm_id < 0) {
-        if (errno == EIDRM) return 0;
-        return -1;
-    }
-    if (shmctl(shm_id, IPC_RMID, NULL) < 0) {             /* ask for removal */
-        if (errno == EIDRM) return 0;
-        return -1;
-    }
-    return 0;
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/SharedMem.c}
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono di creare, trovare e
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono di creare, trovare e
@@ -3112,6 +2665,11 @@ int ShmRemove(key_t ipc_key, void * shm_ptr)
   \label{fig:ipc_sysv_shm_func}
 \end{figure}
 
   \label{fig:ipc_sysv_shm_func}
 \end{figure}
 
+Come esempio di uso di queste funzioni vediamo come implementare una serie di
+funzioni di libreria che ne semplifichino l'uso, automatizzando le operazioni
+più comuni; il codice, contenuto nel file \file{SharedMem.c}, è riportato in
+\figref{fig:ipc_sysv_shm_func}.
+
 La prima funzione (\texttt{\small 3--16}) è \func{ShmCreate} che, data una
 chiave, crea il segmento di memoria condivisa restituendo il puntatore allo
 stesso. La funzione comincia (\texttt{\small 6}) con il chiamare
 La prima funzione (\texttt{\small 3--16}) è \func{ShmCreate} che, data una
 chiave, crea il segmento di memoria condivisa restituendo il puntatore allo
 stesso. La funzione comincia (\texttt{\small 6}) con il chiamare
@@ -3185,58 +2743,8 @@ video; al solito il codice completo si trova con i sorgenti allegati nel file
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-/* global variables for shared memory segment */
-struct DirProp {
-    int tot_size;    
-    int tot_files;   
-    int tot_regular; 
-    int tot_fifo;    
-    int tot_link;    
-    int tot_dir;     
-    int tot_block;   
-    int tot_char;    
-    int tot_sock;
-} *shmptr;
-key_t key;
-int mutex;
-/* main body */
-int main(int argc, char *argv[]) 
-{
-    int i, pause = 10;
-    ...
-    if ((argc - optind) != 1) {          /* There must be remaing parameters */
-        printf("Wrong number of arguments %d\n", argc - optind);
-        usage();
-    }
-    if (chdir(argv[1])) {                      /* chdir to be sure dir exist */
-        perror("Cannot find directory to monitor");
-    }
-    Signal(SIGTERM, HandSIGTERM);            /* set handlers for termination */
-    Signal(SIGINT, HandSIGTERM);
-    Signal(SIGQUIT, HandSIGTERM);
-    key = ftok("~/gapil/sources/DirMonitor.c", 1);           /* define a key */
-    shmptr = ShmCreate(key, 4096, 0666, 0);   /* get a shared memory segment */
-    if (!shmptr) {
-        perror("Cannot create shared memory");
-        exit(1);
-    }
-    if ((mutex = MutexCreate(key)) == -1) {                   /* get a Mutex */
-        perror("Cannot create mutex");
-        exit(1);
-    }
-    /* main loop, monitor directory properties each 10 sec */
-    daemon(1, 0);              /* demonize process, staying in monitored dir */
-    while (1) {
-        MutexLock(mutex);                              /* lock shared memory */
-        memset(shmptr, 0, sizeof(struct DirProp));    /* erase previous data */
-        DirScan(argv[1], ComputeValues);                     /* execute scan */
-        MutexUnlock(mutex);                          /* unlock shared memory */
-        sleep(pause);                              /* sleep until next watch */
-    }
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/DirMonitor.c}
   \end{minipage} 
   \normalsize 
   \caption{Codice della funzione principale del programma \file{DirMonitor.c}.}
   \end{minipage} 
   \normalsize 
   \caption{Codice della funzione principale del programma \file{DirMonitor.c}.}
@@ -3287,6 +2795,16 @@ sar
 di interfaccia già descritte in \secref{sec:ipc_sysv_sem}, anche un mutex, che
 utilizzeremo per regolare l'accesso alla memoria condivisa.
 
 di interfaccia già descritte in \secref{sec:ipc_sysv_sem}, anche un mutex, che
 utilizzeremo per regolare l'accesso alla memoria condivisa.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/ComputeValues.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Codice delle funzioni ausiliarie usate da \file{DirMonitor.c}.}
+  \label{fig:ipc_dirmonitor_sub}
+\end{figure}
+
 Completata l'inizializzazione e la creazione degli oggetti di
 intercomunicazione il programma entra nel ciclo principale (\texttt{\small
   40--49}) dove vengono eseguite indefinitamente le attività di monitoraggio.
 Completata l'inizializzazione e la creazione degli oggetti di
 intercomunicazione il programma entra nel ciclo principale (\texttt{\small
   40--49}) dove vengono eseguite indefinitamente le attività di monitoraggio.
@@ -3305,41 +2823,6 @@ degli stessi utilizzando la funzione \func{DirScan}; infine (\texttt{\small
 (\texttt{\small 47}) per il periodo di tempo specificato a riga di comando con
 l'opzione \code{-p} con una \func{sleep}.
 
 (\texttt{\small 47}) per il periodo di tempo specificato a riga di comando con
 l'opzione \code{-p} con una \func{sleep}.
 
-
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-/* Routine  to compute directory properties inside DirScan */
-int ComputeValues(struct dirent * direntry) 
-{
-    struct stat data;
-    stat(direntry->d_name, &data);                          /* get stat data */
-    shmptr->tot_size += data.st_size;
-    shmptr->tot_files++;
-    if (S_ISREG(data.st_mode)) shmptr->tot_regular++;
-    if (S_ISFIFO(data.st_mode)) shmptr->tot_fifo++;
-    if (S_ISLNK(data.st_mode)) shmptr->tot_link++;
-    if (S_ISDIR(data.st_mode)) shmptr->tot_dir++;
-    if (S_ISBLK(data.st_mode)) shmptr->tot_block++;
-    if (S_ISCHR(data.st_mode)) shmptr->tot_char++;
-    if (S_ISSOCK(data.st_mode)) shmptr->tot_sock++;
-    return 0;
-}
-/* Signal Handler to manage termination */
-void HandSIGTERM(int signo) {
-    MutexLock(mutex);
-    ShmRemove(key, shmptr);
-    MutexRemove(mutex);
-    exit(0);
-}
-    \end{lstlisting}
-  \end{minipage} 
-  \normalsize 
-  \caption{Codice delle funzione ausiliarie usate da \file{DirMonitor.c}.}
-  \label{fig:ipc_dirmonitor_sub}
-\end{figure}
-
 Si noti come per il calcolo dei valori da mantenere nella memoria condivisa si
 sia usata ancora una volta la funzione \func{DirScan}, già utilizzata (e
 descritta in dettaglio) in \secref{sec:file_dir_read}, che ci permette di
 Si noti come per il calcolo dei valori da mantenere nella memoria condivisa si
 sia usata ancora una volta la funzione \func{DirScan}, già utilizzata (e
 descritta in dettaglio) in \secref{sec:file_dir_read}, che ci permette di
@@ -3374,36 +2857,8 @@ rimuove il mutex con \func{MutexRemove} ed esce (\texttt{\small 22}).
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-int main(int argc, char *argv[]) 
-{
-    key_t key;
-    ...
-    /* create needed IPC objects */
-    key = ftok("~/gapil/sources/DirMonitor.c", 1);           /* define a key */
-    if (!(shmptr = ShmFind(key, 4096))) {     /* get a shared memory segment */
-        perror("Cannot find shared memory");
-        exit(1);
-    }
-    if ((mutex = MutexFind(key)) == -1) {                   /* get the Mutex */
-        perror("Cannot find mutex");
-        exit(1);
-    }
-    /* main loop */
-    MutexLock(mutex);                                  /* lock shared memory */
-    printf("Ci sono %d file dati\n", shmptr->tot_regular);
-    printf("Ci sono %d directory\n", shmptr->tot_dir);
-    printf("Ci sono %d link\n", shmptr->tot_link);
-    printf("Ci sono %d fifo\n", shmptr->tot_fifo);
-    printf("Ci sono %d socket\n", shmptr->tot_sock);
-    printf("Ci sono %d device a caratteri\n", shmptr->tot_char);
-    printf("Ci sono %d device a blocchi\n", shmptr->tot_block);
-    printf("Totale  %d file, per %d byte\n",
-           shmptr->tot_files, shmptr->tot_size);
-    MutexUnlock(mutex);                              /* unlock shared memory */
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6 cm}
+    \includecodesample{listati/ReadMonitor.c}
   \end{minipage} 
   \normalsize 
   \caption{Codice del programma client del monitor delle proprietà di una
   \end{minipage} 
   \normalsize 
   \caption{Codice del programma client del monitor delle proprietà di una
@@ -3592,26 +3047,8 @@ cancella con \func{unlink}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>                               /* unix standard functions */
-/*
- * Function LockFile:
- */
-int LockFile(const char* path_name)
-{
-    return open(path_name, O_EXCL|O_CREAT);
-}
-/*
- * Function UnlockFile:
- */
-int UnlockFile(const char* path_name) 
-{
-    return unlink(path_name);
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/LockFile.c}
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni \func{LockFile} e \func{UnlockFile} che
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni \func{LockFile} e \func{UnlockFile} che
@@ -3672,64 +3109,8 @@ leggermente pi
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-/* Function CreateMutex: Create a mutex using file locking. */
-int CreateMutex(const char *path_name)
-{
-    return open(path_name, O_EXCL|O_CREAT);
-}
-/* Function UnlockMutex: unlock a file. */
-int FindMutex(const char *path_name)
-{
-    return open(path_name, O_RDWR);
-}
-/* Function LockMutex: lock mutex using file locking. */
-int LockMutex(int fd)
-{
-    struct flock lock;                                /* file lock structure */
-    /* set flock structure */
-    lock.l_type = F_WRLCK;                        /* set type: read or write */
-    lock.l_whence = SEEK_SET;        /* start from the beginning of the file */
-    lock.l_start = 0;                  /* set the start of the locked region */
-    lock.l_len = 0;                   /* set the length of the locked region */
-    /* do locking */
-    return fcntl(fd, F_SETLKW, &lock);
-}
-/* Function UnlockMutex: unlock a file. */
-int UnlockMutex(int fd)
-{
-    struct flock lock;                                /* file lock structure */
-    /* set flock structure */
-    lock.l_type = F_UNLCK;                               /* set type: unlock */
-    lock.l_whence = SEEK_SET;        /* start from the beginning of the file */
-    lock.l_start = 0;                  /* set the start of the locked region */
-    lock.l_len = 0;                   /* set the length of the locked region */
-    /* do locking */
-    return fcntl(fd, F_SETLK, &lock);
-}
-/* Function RemoveMutex: remove a mutex (unlinking the lock file). */
-int RemoveMutex(const char *path_name)
-{
-    return unlink(path_name);
-}
-/* Function ReadMutex: read a mutex status. */
-int ReadMutex(int fd)
-{
-    int res;
-    struct flock lock;                                /* file lock structure */
-    /* set flock structure */
-    lock.l_type = F_WRLCK;                               /* set type: unlock */
-    lock.l_whence = SEEK_SET;        /* start from the beginning of the file */
-    lock.l_start = 0;                  /* set the start of the locked region */
-    lock.l_len = 0;                   /* set the length of the locked region */
-    /* do locking */
-    if ( (res = fcntl(fd, F_GETLK, &lock)) ) {
-        return res;
-    }
-    return lock.l_type;
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/MutexLocking.c}
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono per la gestione dei 
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono per la gestione dei 
@@ -4037,14 +3418,7 @@ struttura \struct{mq\_attr}, la cui definizione 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct mq_attr {
-        long    mq_flags;       /* message queue flags                  */
-        long    mq_maxmsg;      /* maximum number of messages           */
-        long    mq_msgsize;     /* maximum message size                 */
-        long    mq_curmsgs;     /* number of messages currently queued  */
-};
-    \end{lstlisting}
+    \includestruct{listati/mq_attr.h}
   \end{minipage} 
   \normalsize
   \caption{La struttura \structd{mq\_attr}, contenente gli attributi di una
   \end{minipage} 
   \normalsize
   \caption{La struttura \structd{mq\_attr}, contenente gli attributi di una
@@ -4514,54 +3888,8 @@ descriptor che fa riferimento ad un segmento distinto da eventuali precedenti.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{} 
-/* Function CreateShm: Create a shared memory segment mapping it */
-void * CreateShm(char * shm_name, off_t shm_size, mode_t perm, int fill) 
-{
-    void * shm_ptr;
-    int fd;
-    int flag;
-    /* first open the object, creating it if not existent */
-    flag = O_CREAT|O_EXCL|O_RDWR;
-    fd = shm_open(shm_name, flag, perm);    /* get object file descriptor */
-    if (fd < 0) { 
-        return NULL;
-    }
-    /* set the object size */
-    if (ftruncate(fd, shm_size)) {
-        return NULL;
-    }
-    /* map it in the process address space */
-    shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
-    if (shm_ptr == MAP_FAILED) {
-        return NULL;
-    }
-    memset((void *) shm_ptr, fill, shm_size);                /* fill segment */
-    return shm_ptr;
-}
-/* Function FindShm: Find a POSIX shared memory segment  */
-void * FindShm(char * shm_name, off_t shm_size) 
-{
-    void * shm_ptr;
-    int fd;                           /* ID of the IPC shared memory segment */
-    /* find shared memory ID */
-    if ((fd = shm_open(shm_name, O_RDWR|O_EXCL, 0)) < 0) {
-        return NULL;
-    }
-    /* take the pointer to it */
-    shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
-    if (shm_ptr == MAP_FAILED) {
-        return NULL;
-    }
-    return shm_ptr;
-}
-/* Function RemoveShm: Remove a POSIX shared memory segment */
-int RemoveShm(char * shm_name)
-{
-    return shm_unlink(shm_name);
-}
-    \end{lstlisting}
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/MemShared.c}
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni di gestione dei segmenti di memoria
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni di gestione dei segmenti di memoria
diff --git a/listati/BarCode.c b/listati/BarCode.c
new file mode 100644 (file)
index 0000000..f2b1fe6
--- /dev/null
@@ -0,0 +1,29 @@
+int main(int argc, char *argv[], char *envp[])
+{
+    FILE *pipe[4];
+    FILE *pipein;
+    char *cmd_string[4]={
+        "pnmtopng",
+        "pnmmargin -white 10",
+        "pnmcrop",
+        "gs -sDEVICE=ppmraw -sOutputFile=- -sNOPAUSE -q - -c showpage -c quit"
+    };  
+    char content[]="Content-type: image/png\n\n";
+    int i;
+    /* write mime-type to stdout */ 
+    write(STDOUT_FILENO, content, strlen(content));
+    /* execute chain of command */
+    for (i=0; i<4; i++) {
+        pipe[i] = popen(cmd_string[i], "w");
+        dup2(fileno(pipe[i]), STDOUT_FILENO); 
+    }
+    /* create barcode (in PS) */
+    pipein = popen("barcode", "w");
+    /* send barcode string to barcode program */
+    write(fileno(pipein), argv[1], strlen(argv[1]));
+    /* close all pipes (in reverse order) */
+    for (i=4; i==0; i--) {
+        pclose((pipe[i]));
+    }
+    exit(0);
+}
diff --git a/listati/BarCodePage.c b/listati/BarCodePage.c
new file mode 100644 (file)
index 0000000..26a8290
--- /dev/null
@@ -0,0 +1,47 @@
+int main(int argc, char *argv[], char *envp[])
+{
+    ...
+    /* create two pipes, pipein and pipeout, to handle communication */
+    if ( (retval = pipe(pipein)) ) {
+        WriteMess("input pipe creation error");
+        exit(0);        
+    }
+    if ( (retval = pipe(pipeout)) ) {
+        WriteMess("output pipe creation error");
+        exit(0);        
+    }    
+    /* First fork: use child to run barcode program */
+    if ( (pid = fork()) == -1) {          /* on error exit */
+        WriteMess("child creation error");
+        exit(0);        
+    }
+    /* if child */
+    if (pid == 0) {
+        close(pipein[1]);                /* close pipe write end  */
+        dup2(pipein[0], STDIN_FILENO);   /* remap stdin to pipe read end */
+        close(pipeout[0]);
+        dup2(pipeout[1], STDOUT_FILENO); /* remap stdout in pipe output */
+        execlp("barcode", "barcode", size, NULL);
+    } 
+    close(pipein[0]);                    /* close input side of input pipe */
+    write(pipein[1], argv[1], strlen(argv[1]));  /* write parameter to pipe */
+    close(pipein[1]);                    /* closing write end */
+    waitpid(pid, NULL, 0);               /* wait child completion */
+    /* Second fork: use child to run ghostscript */
+    if ( (pid = fork()) == -1) {
+        WriteMess("child creation error");
+        exit(0);
+    }
+    /* second child, convert PS to JPEG  */
+    if (pid == 0) {                     
+        close(pipeout[1]);              /* close write end */
+        dup2(pipeout[0], STDIN_FILENO); /* remap read end to stdin */
+        /* send mime type */
+        write(STDOUT_FILENO, content, strlen(content));
+        execlp("gs", "gs", "-q", "-sDEVICE=jpeg", "-sOutputFile=-", "-", NULL);
+    }
+    /* still parent */
+    close(pipeout[1]); 
+    waitpid(pid, NULL, 0);
+    exit(0);
+}
diff --git a/listati/ClientEcho.c b/listati/ClientEcho.c
new file mode 100644 (file)
index 0000000..0a64e94
--- /dev/null
@@ -0,0 +1,12 @@
+void ClientEcho(FILE * filein, int socket) 
+{
+    char sendbuff[MAXLINE], recvbuff[MAXLINE];
+    int nread; 
+    while (fgets(sendbuff, MAXLINE, filein) != NULL) {
+        FullWrite(socket, sendbuff, strlen(sendbuff)); 
+        nread = FullRead(socket, recvbuff, strlen(sendbuff));        
+        recvbuff[nread] = 0;
+        fputs(recvbuff, stdout);
+    }
+    return;
+}
diff --git a/listati/ComputeValues.c b/listati/ComputeValues.c
new file mode 100644 (file)
index 0000000..bc11c28
--- /dev/null
@@ -0,0 +1,23 @@
+/* Routine  to compute directory properties inside DirScan */
+int ComputeValues(struct dirent * direntry) 
+{
+    struct stat data;
+    stat(direntry->d_name, &data);                          /* get stat data */
+    shmptr->tot_size += data.st_size;
+    shmptr->tot_files++;
+    if (S_ISREG(data.st_mode)) shmptr->tot_regular++;
+    if (S_ISFIFO(data.st_mode)) shmptr->tot_fifo++;
+    if (S_ISLNK(data.st_mode)) shmptr->tot_link++;
+    if (S_ISDIR(data.st_mode)) shmptr->tot_dir++;
+    if (S_ISBLK(data.st_mode)) shmptr->tot_block++;
+    if (S_ISCHR(data.st_mode)) shmptr->tot_char++;
+    if (S_ISSOCK(data.st_mode)) shmptr->tot_sock++;
+    return 0;
+}
+/* Signal Handler to manage termination */
+void HandSIGTERM(int signo) {
+    MutexLock(mutex);
+    ShmRemove(key, shmptr);
+    MutexRemove(mutex);
+    exit(0);
+}
diff --git a/listati/DirMonitor.c b/listati/DirMonitor.c
new file mode 100644 (file)
index 0000000..edd5bb9
--- /dev/null
@@ -0,0 +1,49 @@
+/* global variables for shared memory segment */
+struct DirProp {
+    int tot_size;    
+    int tot_files;   
+    int tot_regular; 
+    int tot_fifo;    
+    int tot_link;    
+    int tot_dir;     
+    int tot_block;   
+    int tot_char;    
+    int tot_sock;
+} *shmptr;
+key_t key;
+int mutex;
+/* main body */
+int main(int argc, char *argv[]) 
+{
+    int i, pause = 10;
+    ...
+    if ((argc - optind) != 1) {          /* There must be remaing parameters */
+        printf("Wrong number of arguments %d\n", argc - optind);
+        usage();
+    }
+    if (chdir(argv[1])) {                      /* chdir to be sure dir exist */
+        perror("Cannot find directory to monitor");
+    }
+    Signal(SIGTERM, HandSIGTERM);            /* set handlers for termination */
+    Signal(SIGINT, HandSIGTERM);
+    Signal(SIGQUIT, HandSIGTERM);
+    key = ftok("~/gapil/sources/DirMonitor.c", 1);           /* define a key */
+    shmptr = ShmCreate(key, 4096, 0666, 0);   /* get a shared memory segment */
+    if (!shmptr) {
+        perror("Cannot create shared memory");
+        exit(1);
+    }
+    if ((mutex = MutexCreate(key)) == -1) {                   /* get a Mutex */
+        perror("Cannot create mutex");
+        exit(1);
+    }
+    /* main loop, monitor directory properties each 10 sec */
+    daemon(1, 0);              /* demonize process, staying in monitored dir */
+    while (1) {
+        MutexLock(mutex);                              /* lock shared memory */
+        memset(shmptr, 0, sizeof(struct DirProp));    /* erase previous data */
+        DirScan(argv[1], ComputeValues);                     /* execute scan */
+        MutexUnlock(mutex);                          /* unlock shared memory */
+        sleep(pause);                              /* sleep until next watch */
+    }
+}
diff --git a/listati/EchoServerWrong.c b/listati/EchoServerWrong.c
new file mode 100644 (file)
index 0000000..f9a67b6
--- /dev/null
@@ -0,0 +1,32 @@
+int main(int argc, char *argv[])
+{
+/* 
+ * Variables definition  
+ */
+    int sock_fd, i;
+    struct sockaddr_in serv_add;
+    ...
+    /* create socket */
+    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        return -1;
+    }
+    /* initialize address */
+    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                   /* address type is INET */
+    serv_add.sin_port = htons(7);                    /* echo port is 7 */
+    /* build address using inet_pton */
+    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
+        perror("Address creation error");
+        return -1;
+    }
+    /* extablish connection */
+    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("Connection error");
+        return -1;
+    }
+    /* read daytime from server */
+    ClientEcho(stdin, sock_fd);
+    /* normal exit */
+    return 0;
+}
diff --git a/listati/ElemDaytimeTCPClient.c b/listati/ElemDaytimeTCPClient.c
new file mode 100644 (file)
index 0000000..e1459d9
--- /dev/null
@@ -0,0 +1,48 @@
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utilities */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+
+int main(int argc, char *argv[])
+{
+    int sock_fd;
+    int i, nread;
+    struct sockaddr_in serv_add;
+    char buffer[MAXLINE];
+     ...
+    /* create socket */
+    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        return -1;
+    }
+    /* initialize address */
+    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                   /* address type is INET */
+    serv_add.sin_port = htons(13);                   /* daytime post is 13 */
+    /* build address using inet_pton */
+    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
+        perror("Address creation error");
+        return -1;
+    }
+    /* extablish connection */
+    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("Connection error");
+        return -1;
+    }
+    /* read daytime from server */
+    while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) {
+        buffer[nread]=0;
+        if (fputs(buffer, stdout) == EOF) {          /* write daytime */
+            perror("fputs error");
+            return -1;
+        }
+    }
+    /* error on read */
+    if (nread < 0) {
+        perror("Read error");
+        return -1;
+    }
+    /* normal exit */
+    return 0;
+}
diff --git a/listati/ElemDaytimeTCPCuncServ.c b/listati/ElemDaytimeTCPCuncServ.c
new file mode 100644 (file)
index 0000000..9af8cc7
--- /dev/null
@@ -0,0 +1,52 @@
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utililites */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+#include <time.h>
+
+int main(int argc, char *argv[])
+{
+    int list_fd, conn_fd;
+    int i;
+    struct sockaddr_in serv_add, client;
+    char buffer[MAXLINE];
+    socklen_t len;
+    time_t timeval;
+    pid_t pid;
+    int logging=0;
+     ...
+    /* write daytime to client */
+    while (1) {
+        if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) 
+             <0 ) {
+            perror("accept error");
+            exit(-1);
+        }
+        /* fork to handle connection */
+        if ( (pid = fork()) < 0 ){
+            perror("fork error");
+            exit(-1);
+        }
+        if (pid == 0) {                 /* child */
+            close(list_fd);
+            timeval = time(NULL);
+            snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
+            if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
+                perror("write error");
+                exit(-1);
+            }
+            if (logging) {
+                inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer));
+                printf("Request from host %s, port %d\n", buffer,
+                       ntohs(client.sin_port));
+            }
+            close(conn_fd);
+            exit(0);
+        } else {                        /* parent */
+            close(conn_fd);
+        }
+    }
+    /* normal exit, never reached */
+    exit(0);
+}
diff --git a/listati/ElemDaytimeTCPServer.c b/listati/ElemDaytimeTCPServer.c
new file mode 100644 (file)
index 0000000..5f9b116
--- /dev/null
@@ -0,0 +1,56 @@
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utilities */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+#include <time.h>
+#define MAXLINE 80
+#define BACKLOG 10
+int main(int argc, char *argv[])
+{
+/* 
+ * Variables definition  
+ */
+    int list_fd, conn_fd;
+    int i;
+    struct sockaddr_in serv_add;
+    char buffer[MAXLINE];
+    time_t timeval;
+    ...
+    /* create socket */
+    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        exit(-1);
+    }
+    /* initialize address */
+    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                  /* address type is INET */
+    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
+    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
+    /* bind socket */
+    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("bind error");
+        exit(-1);
+    }
+    /* listen on socket */
+    if (listen(list_fd, BACKLOG) < 0 ) {
+        perror("listen error");
+        exit(-1);
+    }
+    /* write daytime to client */
+    while (1) {
+        if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
+            perror("accept error");
+            exit(-1);
+        }
+        timeval = time(NULL);
+        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
+        if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
+            perror("write error");
+            exit(-1);
+        }
+        close(conn_fd);
+    }
+    /* normal exit */
+    exit(0);
+}
diff --git a/listati/ElemEchoTCPServer.c b/listati/ElemEchoTCPServer.c
new file mode 100644 (file)
index 0000000..a434957
--- /dev/null
@@ -0,0 +1,52 @@
+/* Subroutines declaration */
+void ServEcho(int sockfd);
+/* Program beginning */
+int main(int argc, char *argv[])
+{
+    int list_fd, conn_fd;
+    pid_t pid;
+    struct sockaddr_in serv_add;
+     ...
+    /* create socket */
+    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        exit(-1);
+    }
+    /* initialize address */
+    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                  /* address type is INET */
+    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
+    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
+    /* bind socket */
+    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("bind error");
+        exit(-1);
+    }
+    /* listen on socket */
+    if (listen(list_fd, BACKLOG) < 0 ) {
+        perror("listen error");
+        exit(-1);
+    }
+    /* handle echo to client */
+    while (1) {
+        /* accept connection */
+        if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) {
+            perror("accept error");
+            exit(-1);
+        }
+        /* fork to handle connection */
+        if ( (pid = fork()) < 0 ){
+            perror("fork error");
+            exit(-1);
+        }
+        if (pid == 0) {      /* child */
+            close(list_fd);          /* close listening socket */   
+            SockEcho(conn_fd);       /* handle echo */
+            exit(0);
+        } else {             /* parent */
+            close(conn_fd);          /* close connected socket */
+        }
+    }
+    /* normal exit, never reached */
+    exit(0);
+}
diff --git a/listati/Flock.c b/listati/Flock.c
new file mode 100644 (file)
index 0000000..cf85d3b
--- /dev/null
@@ -0,0 +1,52 @@
+int main(int argc, char *argv[])
+{
+    int type = F_UNLCK;            /* lock type: default to unlock (invalid) */
+    off_t start = 0;             /* start of the locked region: default to 0 */
+    off_t len = 0;              /* length of the locked region: default to 0 */
+    int fd, res, i;                                    /* internal variables */
+    int bsd = 0;                          /* semantic type: default to POSIX */
+    int cmd = F_SETLK;              /* lock command: default to non-blocking */
+    struct flock lock;                                /* file lock structure */
+    ...
+    if ((argc - optind) != 1) {          /* There must be remaing parameters */
+        printf("Wrong number of arguments %d\n", argc - optind);
+        usage();
+    }
+    if (type == F_UNLCK) {            /* There must be a -w or -r option set */
+        printf("You should set a read or a write lock\n");
+        usage();
+    }
+    fd = open(argv[optind], O_RDWR);           /* open the file to be locked */
+    if (fd < 0) {                                           /* on error exit */
+        perror("Wrong filename");
+        exit(1);
+    }
+    /* do lock */
+    if (bsd) {                                             /* if BSD locking */
+        /* rewrite cmd for suitables flock operation values */ 
+        if (cmd == F_SETLKW) {                             /* if no-blocking */
+            cmd = LOCK_NB;              /* set the value for flock operation */
+        } else {                                                     /* else */
+            cmd = 0;                                      /* default is null */
+        }
+        if (type == F_RDLCK) cmd |= LOCK_SH;          /* set for shared lock */
+        if (type == F_WRLCK) cmd |= LOCK_EX;       /* set for exclusive lock */
+        res = flock(fd, cmd);                                /* esecute lock */
+    } else {                                             /* if POSIX locking */
+        /* setting flock structure */
+        lock.l_type = type;                       /* set type: read or write */
+        lock.l_whence = SEEK_SET;    /* start from the beginning of the file */
+        lock.l_start = start;          /* set the start of the locked region */
+        lock.l_len = len;             /* set the length of the locked region */
+        res = fcntl(fd, cmd, &lock);                              /* do lock */
+    }
+    /* check lock results */
+    if (res) {                                              /* on error exit */
+        perror("Failed lock");
+        exit(1);
+    } else {                                           /* else write message */
+        printf("Lock acquired\n");
+    }
+    pause();                       /* stop the process, use a signal to exit */
+    return 0;
+}
diff --git a/listati/FortuneClient.c b/listati/FortuneClient.c
new file mode 100644 (file)
index 0000000..f0c1030
--- /dev/null
@@ -0,0 +1,36 @@
+int main(int argc, char *argv[])
+{
+/* Variables definition */
+    int n = 0;
+    char *fortunefilename = "/tmp/fortune.fifo";
+    char line[80];
+    int fifo_server, fifo_client;
+    char fifoname[80];
+    int nread;
+    char buffer[PIPE_BUF];
+    ...
+    snprintf(fifoname, 80, "/tmp/fortune.%d", getpid());     /* compose name */
+    if (mkfifo(fifoname, 0622)) {                        /* open client fifo */
+        if (errno!=EEXIST) {
+            perror("Cannot create well known fifo");
+            exit(-1);
+        }
+    }
+    fifo_server = open(fortunefilename, O_WRONLY);       /* open server fifo */
+    if (fifo_server < 0) {
+        perror("Cannot open well known fifo");
+        exit(-1);
+    }
+    nread = write(fifo_server, fifoname, strlen(fifoname)+1);  /* write name */
+    close(fifo_server);                                 /* close server fifo */
+    fifo_client = open(fifoname, O_RDONLY);              /* open client fifo */
+    if (fifo_client < 0) {
+        perror("Cannot open well known fifo");
+        exit(-1);
+    }
+    nread = read(fifo_client, buffer, sizeof(buffer));        /* read answer */
+    printf("%s", buffer);                                   /* print fortune */
+    close(fifo_client);                                      /* close client */
+    close(fifo_server);                                      /* close server */
+    unlink(fifoname);                                  /* remove client fifo */
+}
diff --git a/listati/FortuneServer.c b/listati/FortuneServer.c
new file mode 100644 (file)
index 0000000..7c45d23
--- /dev/null
@@ -0,0 +1,52 @@
+char *fifoname = "/tmp/fortune.fifo";
+int main(int argc, char *argv[])
+{
+/* Variables definition */
+    int i, n = 0;
+    char *fortunefilename = "/usr/share/games/fortunes/linux";
+    char **fortune;
+    char line[80];
+    int fifo_server, fifo_client;
+    int nread;
+    ...
+    if (n==0) usage();          /* if no pool depth exit printing usage info */
+    Signal(SIGTERM, HandSIGTERM);            /* set handlers for termination */
+    Signal(SIGINT, HandSIGTERM);
+    Signal(SIGQUIT, HandSIGTERM);
+    i = FortuneParse(fortunefilename, fortune, n);          /* parse phrases */
+    if (mkfifo(fifoname, 0622)) {  /* create well known fifo if does't exist */
+        if (errno!=EEXIST) {
+            perror("Cannot create well known fifo");
+            exit(1);
+        }
+    }
+    daemon(0, 0);
+    /* open fifo two times to avoid EOF */
+    fifo_server = open(fifoname, O_RDONLY);
+    if (fifo_server < 0) {
+        perror("Cannot open read only well known fifo");
+        exit(1);
+    }
+    if (open(fifoname, O_WRONLY) < 0) {                        
+        perror("Cannot open write only well known fifo");
+        exit(1);
+    }
+    /* Main body: loop over requests */
+    while (1) {
+        nread = read(fifo_server, line, 79);                 /* read request */
+        if (nread < 0) {
+            perror("Read Error");
+            exit(1);
+        }
+        line[nread] = 0;                       /* terminate fifo name string */
+        n = random() % i;                             /* select random value */
+        fifo_client = open(line, O_WRONLY);              /* open client fifo */
+        if (fifo_client < 0) {
+            perror("Cannot open");
+            exit(1);
+        }
+        nread = write(fifo_client,                           /* write phrase */
+                      fortune[n], strlen(fortune[n])+1);
+        close(fifo_client);                             /* close client fifo */
+    }
+}
diff --git a/listati/FullRead.c b/listati/FullRead.c
new file mode 100644 (file)
index 0000000..fcc265b
--- /dev/null
@@ -0,0 +1,23 @@
+#include <unistd.h>
+
+ssize_t FullRead(int fd, void *buf, size_t count) 
+{
+    size_t nleft;
+    ssize_t nread;
+    nleft = count;
+    while (nleft > 0) {             /* repeat until no left */
+        if ( (nread = read(fd, buf, nleft)) < 0) {
+            if (errno == EINTR) {   /* if interrupted by system call */
+                continue;           /* repeat the loop */
+            } else {
+                return(nread);      /* otherwise exit */
+            }
+        } else if (nread == 0) {    /* EOF */
+            break;                  /* break loop here */ 
+        }
+        nleft -= nread;             /* set left to read */
+        buf +=nread;                /* set pointer */
+    }
+    return (count - nleft);
+}
diff --git a/listati/FullWrite.c b/listati/FullWrite.c
new file mode 100644 (file)
index 0000000..505a1b8
--- /dev/null
@@ -0,0 +1,21 @@
+#include <unistd.h>
+
+ssize_t FullWrite(int fd, const void *buf, size_t count) 
+{
+    size_t nleft;
+    ssize_t nwritten;
+
+    nleft = count;
+    while (nleft > 0) {             /* repeat until no left */
+        if ( (nwritten = write(fd, buf, nleft)) < 0) {
+            if (errno == EINTR) {   /* if interrupted by system call */
+                continue;           /* repeat the loop */
+            } else {
+                return(nwritten);   /* otherwise exit with error */
+            }
+        }
+        nleft -= nwritten;          /* set left to write */
+        buf +=nwritten;             /* set pointer */
+    }
+    return (count);
+}
diff --git a/listati/IPCTestId.c b/listati/IPCTestId.c
new file mode 100644 (file)
index 0000000..4508c6f
--- /dev/null
@@ -0,0 +1,33 @@
+int main(int argc, char *argv[])
+{
+    ...
+    switch (type) {
+    case 'q':   /* Message Queue */
+        debug("Message Queue Try\n");
+        for (i=0; i<n; i++) {
+            id = msgget(IPC_PRIVATE, IPC_CREAT|0666);
+            printf("Identifier Value %d \n", id);
+            msgctl(id, IPC_RMID, NULL);
+        }
+        break;
+    case 's':   /* Semaphore */
+        debug("Semaphore\n");
+        for (i=0; i<n; i++) {
+            id = semget(IPC_PRIVATE, 1, IPC_CREAT|0666);
+            printf("Identifier Value %d \n", id);
+            semctl(id, 0, IPC_RMID);
+        }
+        break;
+    case 'm':   /* Shared Memory */
+        debug("Shared Memory\n");
+        for (i=0; i<n; i++) {
+            id = shmget(IPC_PRIVATE, 1000, IPC_CREAT|0666);
+            printf("Identifier Value %d \n", id);
+            shmctl(id, IPC_RMID, NULL);
+        }
+        break;
+    default:    /* should not reached */
+        return -1;
+    }
+    return 0;
+}
diff --git a/listati/LockFile.c b/listati/LockFile.c
new file mode 100644 (file)
index 0000000..7cd07d3
--- /dev/null
@@ -0,0 +1,17 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>                               /* unix standard functions */
+/*
+ * Function LockFile:
+ */
+int LockFile(const char* path_name)
+{
+    return open(path_name, O_EXCL|O_CREAT);
+}
+/*
+ * Function UnlockFile:
+ */
+int UnlockFile(const char* path_name) 
+{
+    return unlink(path_name);
+}
diff --git a/listati/MQFortuneClient.c b/listati/MQFortuneClient.c
new file mode 100644 (file)
index 0000000..84f86c6
--- /dev/null
@@ -0,0 +1,17 @@
+int main(int argc, char *argv[])
+{
+    ...
+    key = ftok("./MQFortuneServer.c", 1); 
+    msgid = msgget(key, 0); 
+    if (msgid < 0) {
+        perror("Cannot find message queue");
+        exit(1);
+    }
+    /* Main body: do request and write result */
+    msg_read.mtype = 1;                      /* type for request is always 1 */
+    msg_read.pid = getpid();                   /* use pid for communications */
+    size = sizeof(msg_read.pid);  
+    msgsnd(msgid, &msg_read, size, 0);               /* send request message */
+    msgrcv(msgid, &msg_write, MSGMAX, msg_read.pid, MSG_NOERROR);
+    printf("%s", msg_write.mtext);
+}
diff --git a/listati/MQFortuneServer.c b/listati/MQFortuneServer.c
new file mode 100644 (file)
index 0000000..cd0dd1e
--- /dev/null
@@ -0,0 +1,48 @@
+int msgid;                                       /* Message queue identifier */
+int main(int argc, char *argv[])
+{
+/* Variables definition */
+    int i, n = 0;
+    char **fortune;                       /* array of fortune message string */
+    char *fortunefilename = "/usr/share/games/fortunes/linux";  /* file name */
+    struct msgbuf_read {      /* message struct to read request from clients */
+        long mtype;                               /* message type, must be 1 */
+        long pid;             /* message data, must be the pid of the client */
+    } msg_read;
+    struct msgbuf_write {       /* message struct to write result to clients */
+        long mtype;            /* message type, will be the pid of the client*/
+        char mtext[MSGMAX];             /* message data, will be the fortune */
+    } msg_write;
+    key_t key;                                          /* Message queue key */
+    int size;                                                /* message size */
+    ...
+    Signal(SIGTERM, HandSIGTERM);            /* set handlers for termination */
+    Signal(SIGINT, HandSIGTERM);
+    Signal(SIGQUIT, HandSIGTERM);
+    if (n==0) usage();          /* if no pool depth exit printing usage info */
+    i = FortuneParse(fortunefilename, fortune, n);          /* parse phrases */
+    /* Create the queue */
+    key = ftok("./MQFortuneServer.c", 1); 
+    msgid = msgget(key, IPC_CREAT|0666);
+    if (msgid < 0) {
+        perror("Cannot create message queue");
+        exit(1);
+    }
+    /* Main body: loop over requests */
+    daemon(0, 0);
+    while (1) {
+        msgrcv(msgid, &msg_read, sizeof(int), 1, MSG_NOERROR);
+        n = random() % i;                             /* select random value */
+        strncpy(msg_write.mtext, fortune[n], MSGMAX);
+        size = min(strlen(fortune[n])+1, MSGMAX);  
+        msg_write.mtype=msg_read.pid;             /* use request pid as type */
+        msgsnd(msgid, &msg_write, size, 0);
+    }
+}
+/*
+ * Signal Handler to manage termination
+ */
+void HandSIGTERM(int signo) {
+    msgctl(msgid, IPC_RMID, NULL);                   /* remove message queue */
+    exit(0);
+}
diff --git a/listati/MemShared.c b/listati/MemShared.c
new file mode 100644 (file)
index 0000000..dfeea8d
--- /dev/null
@@ -0,0 +1,45 @@
+/* Function CreateShm: Create a shared memory segment mapping it */
+void * CreateShm(char * shm_name, off_t shm_size, mode_t perm, int fill) 
+{
+    void * shm_ptr;
+    int fd;
+    int flag;
+    /* first open the object, creating it if not existent */
+    flag = O_CREAT|O_EXCL|O_RDWR;
+    fd = shm_open(shm_name, flag, perm);    /* get object file descriptor */
+    if (fd < 0) { 
+        return NULL;
+    }
+    /* set the object size */
+    if (ftruncate(fd, shm_size)) {
+        return NULL;
+    }
+    /* map it in the process address space */
+    shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
+    if (shm_ptr == MAP_FAILED) {
+        return NULL;
+    }
+    memset((void *) shm_ptr, fill, shm_size);                /* fill segment */
+    return shm_ptr;
+}
+/* Function FindShm: Find a POSIX shared memory segment  */
+void * FindShm(char * shm_name, off_t shm_size) 
+{
+    void * shm_ptr;
+    int fd;                           /* ID of the IPC shared memory segment */
+    /* find shared memory ID */
+    if ((fd = shm_open(shm_name, O_RDWR|O_EXCL, 0)) < 0) {
+        return NULL;
+    }
+    /* take the pointer to it */
+    shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
+    if (shm_ptr == MAP_FAILED) {
+        return NULL;
+    }
+    return shm_ptr;
+}
+/* Function RemoveShm: Remove a POSIX shared memory segment */
+int RemoveShm(char * shm_name)
+{
+    return shm_unlink(shm_name);
+}
diff --git a/listati/Mutex.c b/listati/Mutex.c
new file mode 100644 (file)
index 0000000..3d0c4c0
--- /dev/null
@@ -0,0 +1,49 @@
+/* Function MutexCreate: create a mutex/semaphore */
+int MutexCreate(key_t ipc_key) 
+{
+    const union semun semunion={1};             /* semaphore union structure */
+    int sem_id, ret;
+    sem_id = semget(ipc_key, 1, IPC_CREAT|0666);         /* get semaphore ID */
+    if (sem_id == -1) {                              /* if error return code */
+        return sem_id;
+    }
+    ret = semctl(sem_id, 0, SETVAL, semunion);             /* init semaphore */
+    if (ret == -1) {
+        return ret;
+    }
+    return sem_id;
+}
+/* Function MutexFind: get the semaphore/mutex Id given the IPC key value */
+int MutexFind(key_t ipc_key) 
+{
+    return semget(ipc_key,1,0);
+}
+/* Function MutexRead: read the current value of the mutex/semaphore */
+int MutexRead(int sem_id) 
+{
+    return semctl(sem_id, 0, GETVAL);
+}
+/* Define sembuf structures to lock and unlock the semaphore  */
+struct sembuf sem_lock={                                /* to lock semaphore */
+    0,                                   /* semaphore number (only one so 0) */
+    -1,                                    /* operation (-1 to use resource) */
+    SEM_UNDO};                                /* flag (set for undo at exit) */
+struct sembuf sem_ulock={                             /* to unlock semaphore */
+    0,                                   /* semaphore number (only one so 0) */
+    1,                                  /* operation (1 to release resource) */
+    SEM_UNDO};                                      /* flag (in this case 0) */
+/* Function MutexLock: to lock a mutex/semaphore */
+int MutexLock(int sem_id) 
+{
+    return semop(sem_id, &sem_lock, 1);
+}
+/* Function MutexUnlock: to unlock a mutex/semaphore */
+int MutexUnlock(int sem_id) 
+{
+    return semop(sem_id, &sem_ulock, 1);
+}
+/* Function MutexRemove: remove a mutex/semaphore */
+int MutexRemove(int sem_id) 
+{
+    return semctl(sem_id, 0, IPC_RMID);
+}
diff --git a/listati/MutexLocking.c b/listati/MutexLocking.c
new file mode 100644 (file)
index 0000000..1b45315
--- /dev/null
@@ -0,0 +1,55 @@
+/* Function CreateMutex: Create a mutex using file locking. */
+int CreateMutex(const char *path_name)
+{
+    return open(path_name, O_EXCL|O_CREAT);
+}
+/* Function UnlockMutex: unlock a file. */
+int FindMutex(const char *path_name)
+{
+    return open(path_name, O_RDWR);
+}
+/* Function LockMutex: lock mutex using file locking. */
+int LockMutex(int fd)
+{
+    struct flock lock;                                /* file lock structure */
+    /* set flock structure */
+    lock.l_type = F_WRLCK;                        /* set type: read or write */
+    lock.l_whence = SEEK_SET;        /* start from the beginning of the file */
+    lock.l_start = 0;                  /* set the start of the locked region */
+    lock.l_len = 0;                   /* set the length of the locked region */
+    /* do locking */
+    return fcntl(fd, F_SETLKW, &lock);
+}
+/* Function UnlockMutex: unlock a file. */
+int UnlockMutex(int fd)
+{
+    struct flock lock;                                /* file lock structure */
+    /* set flock structure */
+    lock.l_type = F_UNLCK;                               /* set type: unlock */
+    lock.l_whence = SEEK_SET;        /* start from the beginning of the file */
+    lock.l_start = 0;                  /* set the start of the locked region */
+    lock.l_len = 0;                   /* set the length of the locked region */
+    /* do locking */
+    return fcntl(fd, F_SETLK, &lock);
+}
+/* Function RemoveMutex: remove a mutex (unlinking the lock file). */
+int RemoveMutex(const char *path_name)
+{
+    return unlink(path_name);
+}
+/* Function ReadMutex: read a mutex status. */
+int ReadMutex(int fd)
+{
+    int res;
+    struct flock lock;                                /* file lock structure */
+    /* set flock structure */
+    lock.l_type = F_WRLCK;                               /* set type: unlock */
+    lock.l_whence = SEEK_SET;        /* start from the beginning of the file */
+    lock.l_start = 0;                  /* set the start of the locked region */
+    lock.l_len = 0;                   /* set the length of the locked region */
+    /* do locking */
+    if ( (res = fcntl(fd, F_GETLK, &lock)) ) {
+        return res;
+    }
+    return lock.l_type;
+}
diff --git a/listati/ReadMonitor.c b/listati/ReadMonitor.c
new file mode 100644 (file)
index 0000000..8881795
--- /dev/null
@@ -0,0 +1,27 @@
+int main(int argc, char *argv[]) 
+{
+    key_t key;
+    ...
+    /* create needed IPC objects */
+    key = ftok("~/gapil/sources/DirMonitor.c", 1);           /* define a key */
+    if (!(shmptr = ShmFind(key, 4096))) {     /* get a shared memory segment */
+        perror("Cannot find shared memory");
+        exit(1);
+    }
+    if ((mutex = MutexFind(key)) == -1) {                   /* get the Mutex */
+        perror("Cannot find mutex");
+        exit(1);
+    }
+    /* main loop */
+    MutexLock(mutex);                                  /* lock shared memory */
+    printf("Ci sono %d file dati\n", shmptr->tot_regular);
+    printf("Ci sono %d directory\n", shmptr->tot_dir);
+    printf("Ci sono %d link\n", shmptr->tot_link);
+    printf("Ci sono %d fifo\n", shmptr->tot_fifo);
+    printf("Ci sono %d socket\n", shmptr->tot_sock);
+    printf("Ci sono %d device a caratteri\n", shmptr->tot_char);
+    printf("Ci sono %d device a blocchi\n", shmptr->tot_block);
+    printf("Totale  %d file, per %d byte\n",
+           shmptr->tot_files, shmptr->tot_size);
+    MutexUnlock(mutex);                              /* unlock shared memory */
+}
diff --git a/listati/ServEcho.c b/listati/ServEcho.c
new file mode 100644 (file)
index 0000000..917c7c4
--- /dev/null
@@ -0,0 +1,10 @@
+void ServEcho(int sockfd) {
+    char buffer[MAXLINE];
+    int nread, nwrite;
+    
+    /* main loop, reading 0 char means client close connection */
+    while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
+        nwrite = FullWrite(sockfd, buffer, nread);
+    }
+    return;
+}
diff --git a/listati/SetTermAttr.c b/listati/SetTermAttr.c
new file mode 100644 (file)
index 0000000..41656f2
--- /dev/null
@@ -0,0 +1,21 @@
+#include <unistd.h>
+#include <termios.h>
+#include <errno.h>
+
+int SetTermAttr(int fd, tcflag_t flag) 
+{
+    struct termios values;
+    int res;
+    res = tcgetattr (desc, &values);
+    if (res) {
+        perror("Cannot get attributes");
+        return res;
+    }
+    values.c_lflag |= flag;
+    res = tcsetattr (desc, TCSANOW, &values);
+    if (res) {
+        perror("Cannot set attributes");
+        return res;
+    }
+    return 0;
+}
diff --git a/listati/SharedMem.c b/listati/SharedMem.c
new file mode 100644 (file)
index 0000000..9f5b438
--- /dev/null
@@ -0,0 +1,51 @@
+/* Function ShmCreate  Create a SysV shared memory segment */
+void * ShmCreate(key_t ipc_key, int shm_size, int perm, int fill) 
+{
+    void * shm_ptr;
+    int shm_id;                       /* ID of the IPC shared memory segment */
+    shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm);        /* get shm ID */
+    if (shm_id < 0) { 
+        return NULL;
+    }
+    shm_ptr = shmat(shm_id, NULL, 0);                  /* map it into memory */
+    if (shm_ptr < 0) {
+        return NULL;
+    }
+    memset((void *)shm_ptr, fill, shm_size);                 /* fill segment */
+    return shm_ptr;
+}
+/* Function ShmFind: Find a SysV shared memory segment  */
+void * ShmFind(key_t ipc_key, int shm_size) 
+{
+    void * shm_ptr;
+    int shm_id;                      /* ID of the SysV shared memory segment */
+    shm_id = shmget(ipc_key, shm_size, 0);          /* find shared memory ID */
+    if (shm_id < 0) {
+        return NULL;
+    }
+    shm_ptr = shmat(shm_id, NULL, 0);                  /* map it into memory */
+    if (shm_ptr < 0) {
+        return NULL;
+    }
+    return shm_ptr;
+}
+/* Function ShmRemove: Schedule removal for a SysV shared memory segment  */
+int ShmRemove(key_t ipc_key, void * shm_ptr) 
+{
+    int shm_id;                      /* ID of the SysV shared memory segment */
+    /* first detach segment */
+    if (shmdt(shm_ptr) < 0) {
+        return -1;
+    }
+    /* schedule segment removal */
+    shm_id = shmget(ipc_key, 0, 0);                 /* find shared memory ID */
+    if (shm_id < 0) {
+        if (errno == EIDRM) return 0;
+        return -1;
+    }
+    if (shmctl(shm_id, IPC_RMID, NULL) < 0) {             /* ask for removal */
+        if (errno == EIDRM) return 0;
+        return -1;
+    }
+    return 0;
+}
diff --git a/listati/UnSetTermAttr.c b/listati/UnSetTermAttr.c
new file mode 100644 (file)
index 0000000..fbeec75
--- /dev/null
@@ -0,0 +1,17 @@
+int UnSetTermAttr(int fd, tcflag_t flag) 
+{
+    struct termios values;
+    int res;
+    res = tcgetattr (desc, &values);
+    if (res) {
+        perror("Cannot get attributes");
+        return res;
+    }
+    values.c_lflag &= (~flag);
+    res = tcsetattr (desc, TCSANOW, &values);
+    if (res) {
+        perror("Cannot set attributes");
+        return res;
+    }
+    return 0;
+}
diff --git a/listati/aiocb.h b/listati/aiocb.h
new file mode 100644 (file)
index 0000000..fd3c643
--- /dev/null
@@ -0,0 +1,10 @@
+struct aiocb
+{
+    int aio_fildes;               /* File descriptor.  */
+    off_t aio_offset;             /* File offset */
+    int aio_lio_opcode;           /* Operation to be performed.  */
+    int aio_reqprio;              /* Request priority offset.  */
+    volatile void *aio_buf;       /* Location of buffer.  */
+    size_t aio_nbytes;            /* Length of transfer.  */
+    struct sigevent aio_sigevent; /* Signal number and value.  */
+};
diff --git a/listati/flock.h b/listati/flock.h
new file mode 100644 (file)
index 0000000..4768dcd
--- /dev/null
@@ -0,0 +1,7 @@
+struct flock {
+    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence; /* Where `l_start' is relative to (like `lseek').*/
+    off_t l_start;      /* Offset where the lock begins.  */
+    off_t l_len;        /* Size of the locked area; zero means until EOF.*/
+    pid_t l_pid;        /* Process holding the lock.  */
+};
diff --git a/listati/iovec.h b/listati/iovec.h
new file mode 100644 (file)
index 0000000..963751b
--- /dev/null
@@ -0,0 +1,4 @@
+struct iovec {
+    __ptr_t iov_base;    /* Starting address */
+    size_t iov_len;      /* Length in bytes  */
+};
diff --git a/listati/ipc_perm.h b/listati/ipc_perm.h
new file mode 100644 (file)
index 0000000..9c7949e
--- /dev/null
@@ -0,0 +1,10 @@
+struct ipc_perm
+{
+    key_t key;                        /* Key.  */
+    uid_t uid;                        /* Owner's user ID.  */
+    gid_t gid;                        /* Owner's group ID.  */
+    uid_t cuid;                       /* Creator's user ID.  */
+    gid_t cgid;                       /* Creator's group ID.  */
+    unsigned short int mode;          /* Read/write permission.  */
+    unsigned short int seq;           /* Sequence number.  */
+};
diff --git a/listati/mq_attr.h b/listati/mq_attr.h
new file mode 100644 (file)
index 0000000..be2ef47
--- /dev/null
@@ -0,0 +1,6 @@
+struct mq_attr {
+        long    mq_flags;       /* message queue flags                  */
+        long    mq_maxmsg;      /* maximum number of messages           */
+        long    mq_msgsize;     /* maximum message size                 */
+        long    mq_curmsgs;     /* number of messages currently queued  */
+};
diff --git a/listati/msgbuf.h b/listati/msgbuf.h
new file mode 100644 (file)
index 0000000..a487e48
--- /dev/null
@@ -0,0 +1,4 @@
+struct msgbuf {
+     long mtype;          /* message type, must be > 0 */
+     char mtext[LENGTH];  /* message data */
+};
diff --git a/listati/msqid_ds.h b/listati/msqid_ds.h
new file mode 100644 (file)
index 0000000..4efeabe
--- /dev/null
@@ -0,0 +1,13 @@
+struct msqid_ds {
+    struct ipc_perm msg_perm;     /* structure for operation permission */
+    time_t msg_stime;             /* time of last msgsnd command */
+    time_t msg_rtime;             /* time of last msgrcv command */
+    time_t msg_ctime;             /* time of last change */
+    msgqnum_t msg_qnum;           /* number of messages currently on queue */
+    msglen_t msg_qbytes;          /* max number of bytes allowed on queue */
+    pid_t msg_lspid;              /* pid of last msgsnd() */
+    pid_t msg_lrpid;              /* pid of last msgrcv() */
+    struct msg *msg_first;        /* first message on queue, unused  */
+    struct msg *msg_last;         /* last message in queue, unused */
+    unsigned long int msg_cbytes; /* current number of bytes on queue */
+};
diff --git a/listati/oflag.c b/listati/oflag.c
new file mode 100644 (file)
index 0000000..9b4a965
--- /dev/null
@@ -0,0 +1,2 @@
+    c_oflag &= (~CRDLY);
+    c_oflag |= CR1;
diff --git a/listati/pollfd.h b/listati/pollfd.h
new file mode 100644 (file)
index 0000000..cb1cbb4
--- /dev/null
@@ -0,0 +1,5 @@
+struct pollfd {
+        int fd;           /* file descriptor */
+        short events;     /* requested events */
+        short revents;    /* returned events */
+};
diff --git a/listati/sem.h b/listati/sem.h
new file mode 100644 (file)
index 0000000..a219929
--- /dev/null
@@ -0,0 +1,6 @@
+struct sem {
+  short   sempid;         /* pid of last operation */
+  ushort  semval;         /* current value */
+  ushort  semncnt;        /* num procs awaiting increase in semval */
+  ushort  semzcnt;        /* num procs awaiting semval = 0 */
+};
diff --git a/listati/sembuf.h b/listati/sembuf.h
new file mode 100644 (file)
index 0000000..277b34f
--- /dev/null
@@ -0,0 +1,6 @@
+struct sembuf
+{
+  unsigned short int sem_num;   /* semaphore number */
+  short int sem_op;             /* semaphore operation */
+  short int sem_flg;            /* operation flag */
+};
diff --git a/listati/semid_ds.h b/listati/semid_ds.h
new file mode 100644 (file)
index 0000000..24d797b
--- /dev/null
@@ -0,0 +1,7 @@
+struct semid_ds
+{
+    struct ipc_perm sem_perm;           /* operation permission struct */
+    time_t sem_otime;                   /* last semop() time */
+    time_t sem_ctime;                   /* last time changed by semctl() */
+    unsigned long int sem_nsems;        /* number of semaphores in set */
+};
diff --git a/listati/semun.h b/listati/semun.h
new file mode 100644 (file)
index 0000000..3b90c50
--- /dev/null
@@ -0,0 +1,7 @@
+union semun {
+      int val;                  /* value for SETVAL */
+      struct semid_ds *buf;     /* buffer for IPC_STAT, IPC_SET */
+      unsigned short *array;    /* array for GETALL, SETALL */
+                                /* Linux specific part: */
+      struct seminfo *__buf;    /* buffer for IPC_INFO */
+};
diff --git a/listati/serv_addr_sin6_addr.c b/listati/serv_addr_sin6_addr.c
new file mode 100644 (file)
index 0000000..a758ebb
--- /dev/null
@@ -0,0 +1 @@
+    serv_add.sin6_addr = in6addr_any;
diff --git a/listati/serv_addr_sin_addr.c b/listati/serv_addr_sin_addr.c
new file mode 100644 (file)
index 0000000..97a9181
--- /dev/null
@@ -0,0 +1 @@
+    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);
diff --git a/listati/shmid_ds.h b/listati/shmid_ds.h
new file mode 100644 (file)
index 0000000..37ea5e3
--- /dev/null
@@ -0,0 +1,10 @@
+struct shmid_ds {
+     struct    ipc_perm shm_perm;  /* operation perms */
+     int  shm_segsz;               /* size of segment (bytes) */
+     time_t    shm_atime;          /* last attach time */
+     time_t    shm_dtime;          /* last detach time */
+     time_t    shm_ctime;          /* last change time */
+     unsigned short shm_cpid;      /* pid of creator */
+     unsigned short shm_lpid;      /* pid of last operator */
+     short     shm_nattch;         /* no. of current attaches */
+};
diff --git a/listati/sigchildhand.c b/listati/sigchildhand.c
new file mode 100644 (file)
index 0000000..8ded584
--- /dev/null
@@ -0,0 +1,5 @@
+    ...
+    /* install SIGCHLD handler */
+    Signal(SIGCHLD, sigchld_hand);  /* establish handler */
+    /* create socket */
+    ...
diff --git a/listati/sigevent.h b/listati/sigevent.h
new file mode 100644 (file)
index 0000000..6b6539a
--- /dev/null
@@ -0,0 +1,8 @@
+struct sigevent
+{
+    sigval_t sigev_value;
+    int sigev_signo;
+    int sigev_notify;
+    void (*sigev_notify_function)(sigval_t);
+    pthread_attr_t *sigev_notify_attributes;
+};
diff --git a/listati/sockaddr.h b/listati/sockaddr.h
new file mode 100644 (file)
index 0000000..8a85177
--- /dev/null
@@ -0,0 +1,4 @@
+struct sockaddr {
+    sa_family_t  sa_family;     /* address family: AF_xxx */
+    char         sa_data[14];   /* address (protocol-specific) */
+};
diff --git a/listati/sockaddr_atalk.h b/listati/sockaddr_atalk.h
new file mode 100644 (file)
index 0000000..e0b13fa
--- /dev/null
@@ -0,0 +1,9 @@
+struct sockaddr_atalk {
+    sa_family_t     sat_family; /* address family */
+    uint8_t         sat_port;   /* port */
+    struct at_addr  sat_addr;   /* net/node */
+};
+struct at_addr {
+    uint16_t        s_net;
+    uint8_t         s_node;
+};
diff --git a/listati/sockaddr_in.h b/listati/sockaddr_in.h
new file mode 100644 (file)
index 0000000..a4b1587
--- /dev/null
@@ -0,0 +1,9 @@
+struct sockaddr_in {
+    sa_family_t     sin_family; /* address family: AF_INET */
+    in_port_t       sin_port;   /* port in network byte order */
+    struct in_addr  sin_addr;   /* internet address */
+};
+/* Internet address. */
+struct in_addr {
+    in_addr_t       s_addr;     /* address in network byte order */
+};
diff --git a/listati/sockaddr_in6.h b/listati/sockaddr_in6.h
new file mode 100644 (file)
index 0000000..34bc216
--- /dev/null
@@ -0,0 +1,10 @@
+struct sockaddr_in6 {
+    uint16_t        sin6_family;   /* AF_INET6 */
+    in_port_t       sin6_port;     /* port number */
+    uint32_t        sin6_flowinfo; /* IPv6 flow information */
+    struct in6_addr sin6_addr;     /* IPv6 address */
+    uint32_t        sin6_scope_id; /* Scope id (new in 2.4) */
+};
+struct in6_addr {
+    uint8_t       s6_addr[16];   /* IPv6 address */
+};
diff --git a/listati/sockaddr_ll.h b/listati/sockaddr_ll.h
new file mode 100644 (file)
index 0000000..ad9030f
--- /dev/null
@@ -0,0 +1,9 @@
+struct sockaddr_ll {
+    unsigned short  sll_family;    /* Always AF_PACKET */
+    unsigned short  sll_protocol;  /* Physical layer protocol */
+    int             sll_ifindex;   /* Interface number */
+    unsigned short  sll_hatype;    /* Header type */
+    unsigned char   sll_pkttype;   /* Packet type */
+    unsigned char   sll_halen;     /* Length of address */
+    unsigned char   sll_addr[8];   /* Physical layer address */
+};
diff --git a/listati/sockaddr_un.h b/listati/sockaddr_un.h
new file mode 100644 (file)
index 0000000..fb1c01e
--- /dev/null
@@ -0,0 +1,5 @@
+#define UNIX_PATH_MAX    108
+struct sockaddr_un {
+    sa_family_t  sun_family;              /* AF_UNIX */
+    char         sun_path[UNIX_PATH_MAX]; /* pathname */
+};
diff --git a/listati/termios.h b/listati/termios.h
new file mode 100644 (file)
index 0000000..b0be108
--- /dev/null
@@ -0,0 +1,10 @@
+struct termios {
+    tcflag_t c_iflag;      /* input modes */
+    tcflag_t c_oflag;      /* output modes */
+    tcflag_t c_cflag;      /* control modes */
+    tcflag_t c_lflag;      /* local modes */
+    cc_t c_cc[NCCS];       /* control characters */
+    cc_t c_line;           /* line discipline */
+    speed_t c_ispeed;      /* input speed */
+    speed_t c_ospeed;      /* output speed */
+};
diff --git a/listati/value_c_cc.c b/listati/value_c_cc.c
new file mode 100644 (file)
index 0000000..922ab3c
--- /dev/null
@@ -0,0 +1 @@
+    value.c_cc[VEOL2] = '\n';
index b53320ce2f6196f8a8a2088bd13b4b870d5ac2e9..dbee21978dc0b1289126948d8f0e2716d19e03ef 100644 (file)
@@ -1092,18 +1092,7 @@ ulteriori informazioni.\footnote{la definizione della struttura si trova in
 \begin{figure}[!htb] 
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb] 
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct termios {
-    tcflag_t c_iflag;      /* input modes */
-    tcflag_t c_oflag;      /* output modes */
-    tcflag_t c_cflag;      /* control modes */
-    tcflag_t c_lflag;      /* local modes */
-    cc_t c_cc[NCCS];       /* control characters */
-    cc_t c_line;           /* line discipline */
-    speed_t c_ispeed;      /* input speed */
-    speed_t c_ospeed;      /* output speed */
-;
-    \end{lstlisting}
+    \includestruct{listati/termios.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{termios}, che identifica le proprietà di un
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{termios}, che identifica le proprietà di un
@@ -1284,10 +1273,7 @@ della maschera, i valori da immettere infatti (quelli riportati nella
 spiegazione corrispondente) sono numerici e non per bit, per cui possono
 sovrapporsi fra di loro. Occorrerà perciò utilizzare un codice del tipo:
 
 spiegazione corrispondente) sono numerici e non per bit, per cui possono
 sovrapporsi fra di loro. Occorrerà perciò utilizzare un codice del tipo:
 
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    c_oflag &= (~CRDLY);
-    c_oflag |= CR1;
-\end{lstlisting}
+\includecodesnip{listati/oflag.c}
 
 \noindent che prima cancella i bit della maschera in questione e poi setta il
 valore.
 
 \noindent che prima cancella i bit della maschera in questione e poi setta il
 valore.
@@ -1556,9 +1542,7 @@ completo dei caratteri di controllo, con le costanti e delle funzionalit
 associate è riportato in \tabref{tab:sess_termios_cc}, usando quelle
 definizioni diventa possibile assegnare un nuovo carattere di controllo con un
 codice del tipo:
 associate è riportato in \tabref{tab:sess_termios_cc}, usando quelle
 definizioni diventa possibile assegnare un nuovo carattere di controllo con un
 codice del tipo:
-\begin{lstlisting}[stepnumber=0,frame=]{}
-    value.c_cc[VEOL2] = '\n';
-\end{lstlisting}
+\includecodesnip{listati/value_c_cc.c}
 
 La maggior parte di questi caratteri (tutti tranne \const{VTIME} e
 \const{VMIN}) hanno effetto solo quando il terminale viene utilizzato in modo
 
 La maggior parte di questi caratteri (tutti tranne \const{VTIME} e
 \const{VMIN}) hanno effetto solo quando il terminale viene utilizzato in modo
@@ -1651,30 +1635,11 @@ effettuano pi
 chiamata a \func{tcgetattr} che essi siano stati eseguiti tutti quanti.
 
 \begin{figure}[!htb]
 chiamata a \func{tcgetattr} che essi siano stati eseguiti tutti quanti.
 
 \begin{figure}[!htb]
-  \footnotesize 
-  \begin{lstlisting}{}
-#include <unistd.h>
-#include <termios.h>
-#include <errno.h>
-
-int SetTermAttr(int fd, tcflag_t flag) 
-{
-    struct termios values;
-    int res;
-    res = tcgetattr (desc, &values);
-    if (res) {
-        perror("Cannot get attributes");
-        return res;
-    }
-    values.c_lflag |= flag;
-    res = tcsetattr (desc, TCSANOW, &values);
-    if (res) {
-        perror("Cannot set attributes");
-        return res;
-    }
-    return 0;
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/SetTermAttr.c}
+  \end{minipage} 
+  \normalsize 
   \caption{Codice della funzione \func{SetTermAttr} che permette di
     impostare uno dei flag di controllo locale del terminale.}
   \label{fig:term_set_attr}
   \caption{Codice della funzione \func{SetTermAttr} che permette di
     impostare uno dei flag di controllo locale del terminale.}
   \label{fig:term_set_attr}
@@ -1703,33 +1668,18 @@ infine si scrive il nuovo valore modificato con \func{tcsetattr}
 o uscendo normalmente.
 
 \begin{figure}[!htb]
 o uscendo normalmente.
 
 \begin{figure}[!htb]
-  \footnotesize 
-  \begin{lstlisting}{}
-int UnSetTermAttr(int fd, tcflag_t flag) 
-{
-    struct termios values;
-    int res;
-    res = tcgetattr (desc, &values);
-    if (res) {
-        perror("Cannot get attributes");
-        return res;
-    }
-    values.c_lflag &= (~flag);
-    res = tcsetattr (desc, TCSANOW, &values);
-    if (res) {
-        perror("Cannot set attributes");
-        return res;
-    }
-    return 0;
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/UnSetTermAttr.c}
+  \end{minipage} 
+  \normalsize 
   \caption{Codice della funzione \func{UnSetTermAttr} che permette di
     rimuovere uno dei flag di controllo locale del terminale.} 
   \label{fig:term_unset_attr}
 \end{figure}
 
 La seconda funzione, \func{UnSetTermAttr}, è assolutamente identica alla
   \caption{Codice della funzione \func{UnSetTermAttr} che permette di
     rimuovere uno dei flag di controllo locale del terminale.} 
   \label{fig:term_unset_attr}
 \end{figure}
 
 La seconda funzione, \func{UnSetTermAttr}, è assolutamente identica alla
-prima, solo che in questo caso (in \texttt{\small 15}) si rimuovono i bit
+prima, solo che in questo caso, in (\texttt{\small 15}), si rimuovono i bit
 specificati dall'argomento \param{flag} usando un AND binario del valore
 negato.
 
 specificati dall'argomento \param{flag} usando un AND binario del valore
 negato.
 
index 2fa13ad1996fd691acc665f9ce07d03802fe12ee..7a680d40d0e77c7fed49f7185c8e054a1ea4dd6f 100644 (file)
@@ -1,4 +1,4 @@
-%% signal.tex
+a%% signal.tex
 %%
 %% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %%
 %% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
@@ -2260,14 +2260,14 @@ l'I/O asincrono (vedi \secref{sec:file_asyncronous_io}) o per le code di
 messaggi POSIX (vedi \secref{sec:ipc_posix_mq}); pertanto devono essere
 inviati esplicitamente. 
 
 messaggi POSIX (vedi \secref{sec:ipc_posix_mq}); pertanto devono essere
 inviati esplicitamente. 
 
-Inoltre per poter usufruire della capacità di restituire dei dati i relativi
-gestori devono essere installati con \func{sigaction} specificando la modalità
-\const{SA\_SIGINFO} che permette di utilizzare la forma estesa
-\var{sa\_sigaction} (vedi \secref{sec:sig_sigaction}).  In questo modo tutti i
-segnali real-time possono restituire al gestore una serie di informazioni
-aggiuntive attraverso l'argomento \struct{siginfo\_t}, la cui definizione
-abbiamo già visto in \figref{fig:sig_siginfo_t}, nella trattazione dei gestori
-in forma estesa.
+Inoltre, per poter usufruire della capacità di restituire dei dati, i relativi
+gestori devono essere installati con \func{sigaction}, specificando per
+\var{sa\_flags} la modalità \const{SA\_SIGINFO} che permette di utilizzare la
+forma estesa \var{sa\_sigaction} (vedi \secref{sec:sig_sigaction}).  In questo
+modo tutti i segnali real-time possono restituire al gestore una serie di
+informazioni aggiuntive attraverso l'argomento \struct{siginfo\_t}, la cui
+definizione abbiamo già visto in \figref{fig:sig_siginfo_t}, nella trattazione
+dei gestori in forma estesa.
 
 In particolare i campi utilizzati dai segnali real-time sono \var{si\_pid} e
 \var{si\_uid} in cui vengono memorizzati rispettivamente il \acr{pid} e
 
 In particolare i campi utilizzati dai segnali real-time sono \var{si\_pid} e
 \var{si\_uid} in cui vengono memorizzati rispettivamente il \acr{pid} e
index b4b9931413d9a08703352b2b39c54ed6c5b90b5b..cd3dce8d21f953e8b9982dbcaabb31b758647561 100644 (file)
@@ -61,61 +61,11 @@ parte, riportata in \figref{fig:TCPsimpl_serv_code}, 
 nel precedente esempio esaminato in \secref{sec:TCPel_cunc_serv}.
 
 \begin{figure}[!htb]
 nel precedente esempio esaminato in \secref{sec:TCPel_cunc_serv}.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-/* Subroutines declaration */
-void ServEcho(int sockfd);
-/* Program beginning */
-int main(int argc, char *argv[])
-{
-    int list_fd, conn_fd;
-    pid_t pid;
-    struct sockaddr_in serv_add;
-     ...
-    /* create socket */
-    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        exit(-1);
-    }
-    /* initialize address */
-    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                  /* address type is INET */
-    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
-    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
-    /* bind socket */
-    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("bind error");
-        exit(-1);
-    }
-    /* listen on socket */
-    if (listen(list_fd, BACKLOG) < 0 ) {
-        perror("listen error");
-        exit(-1);
-    }
-    /* handle echo to client */
-    while (1) {
-        /* accept connection */
-        if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) {
-            perror("accept error");
-            exit(-1);
-        }
-        /* fork to handle connection */
-        if ( (pid = fork()) < 0 ){
-            perror("fork error");
-            exit(-1);
-        }
-        if (pid == 0) {      /* child */
-            close(list_fd);          /* close listening socket */   
-            SockEcho(conn_fd);       /* handle echo */
-            exit(0);
-        } else {             /* parent */
-            close(conn_fd);          /* close connected socket */
-        }
-    }
-    /* normal exit, never reached */
-    exit(0);
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/ElemEchoTCPServer.c}
+  \end{minipage} 
+  \normalsize
   \caption{Codice della funzione \code{main} della prima versione del server
     per il servizio \texttt{echo}.}
   \label{fig:TCPsimpl_serv_code}
   \caption{Codice della funzione \code{main} della prima versione del server
     per il servizio \texttt{echo}.}
   \label{fig:TCPsimpl_serv_code}
@@ -142,19 +92,11 @@ dati di cui 
 \func{write}.
 
 \begin{figure}[!htb]
 \func{write}.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-void ServEcho(int sockfd) {
-    char buffer[MAXLINE];
-    int nread, nwrite;
-    
-    /* main loop, reading 0 char means client close connection */
-    while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
-        nwrite = FullWrite(sockfd, buffer, nread);
-    }
-    return;
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/ServEcho.c}
+  \end{minipage} 
+  \normalsize
   \caption{Codice della prima versione della funzione \code{ServEcho} per la
     gestione del servizio \texttt{echo}.}
   \label{fig:TCPsimpl_server_elem_sub}
   \caption{Codice della prima versione della funzione \code{ServEcho} per la
     gestione del servizio \texttt{echo}.}
   \label{fig:TCPsimpl_server_elem_sub}
@@ -174,42 +116,13 @@ esso ricalca la struttura del precedente client per il servizio
 \texttt{daytime} (vedi \secref{sec:net_cli_sample}) ma, come per il server, lo
 si è diviso in due parti, inserendo la parte relativa alle operazioni
 specifiche previste per il protocollo \texttt{echo} in una funzione a parte.
 \texttt{daytime} (vedi \secref{sec:net_cli_sample}) ma, come per il server, lo
 si è diviso in due parti, inserendo la parte relativa alle operazioni
 specifiche previste per il protocollo \texttt{echo} in una funzione a parte.
+
 \begin{figure}[!htb]
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-int main(int argc, char *argv[])
-{
-/* 
- * Variables definition  
- */
-    int sock_fd, i;
-    struct sockaddr_in serv_add;
-    ...
-    /* create socket */
-    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        return -1;
-    }
-    /* initialize address */
-    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                   /* address type is INET */
-    serv_add.sin_port = htons(7);                    /* echo port is 7 */
-    /* build address using inet_pton */
-    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
-        perror("Address creation error");
-        return -1;
-    }
-    /* extablish connection */
-    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("Connection error");
-        return -1;
-    }
-    /* read daytime from server */
-    ClientEcho(stdin, sock_fd);
-    /* normal exit */
-    return 0;
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6 cm}
+    \includecodesample{listati/EchoServerWrong.c}
+  \end{minipage} 
+  \normalsize
   \caption{Codice della prima versione del client \texttt{echo}.}
   \label{fig:TCPsimpl_client_elem}
 \end{figure}
   \caption{Codice della prima versione del client \texttt{echo}.}
   \label{fig:TCPsimpl_client_elem}
 \end{figure}
@@ -227,21 +140,11 @@ preoccupa di gestire la comunicazione, leggendo una riga alla volta dallo
 ricevuto in risposta dal server.
 
 \begin{figure}[!htb]
 ricevuto in risposta dal server.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-void ClientEcho(FILE * filein, int socket) 
-{
-    char sendbuff[MAXLINE], recvbuff[MAXLINE];
-    int nread; 
-    while (fgets(sendbuff, MAXLINE, filein) != NULL) {
-        FullWrite(socket, sendbuff, strlen(sendbuff)); 
-        nread = FullRead(socket, recvbuff, strlen(sendbuff));        
-        recvbuff[nread] = 0;
-        fputs(recvbuff, stdout);
-    }
-    return;
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/ClientEcho.c}
+  \end{minipage} 
+  \normalsize
   \caption{Codice della prima versione della funzione \texttt{ClientEcho} per 
     la gestione del servizio \texttt{echo}.}
   \label{fig:TCPsimpl_client_echo_sub}
   \caption{Codice della prima versione della funzione \texttt{ClientEcho} per 
     la gestione del servizio \texttt{echo}.}
   \label{fig:TCPsimpl_client_echo_sub}
@@ -429,14 +332,7 @@ Per questo useremo la funzione \code{Signal}, illustrata in
 \figref{fig:sig_Signal_code}, per installare il semplice gestore che
 riceve i segnali dei processi figli terminati già visto in 
 \figref{fig:sig_sigchld_handl}; aggiungendo il seguente codice:
 \figref{fig:sig_Signal_code}, per installare il semplice gestore che
 riceve i segnali dei processi figli terminati già visto in 
 \figref{fig:sig_sigchld_handl}; aggiungendo il seguente codice:
-\begin{lstlisting}{}
-    ...
-    /* install SIGCHLD handler */
-    Signal(SIGCHLD, sigchld_hand);  /* establish handler */
-    /* create socket */
-    ...
-\end{lstlisting}
-
+\includecodesnip{listati/sigchildhand.c}
 \noindent
 all'esempio illustrato in \figref{fig:TCPsimpl_serv_code}, e linkando il tutto
 alla funzione \code{sigchld\_hand}, si risolverà completamente il problema
 \noindent
 all'esempio illustrato in \figref{fig:TCPsimpl_serv_code}, e linkando il tutto
 alla funzione \code{sigchld\_hand}, si risolverà completamente il problema
index 1c9d1a746b528ee4472f1e8534321920528c8b1c..ba5c608d8b4fc67232600790b109ee0d39180132 100644 (file)
@@ -361,12 +361,7 @@ una struttura generica per gli indirizzi dei socket, \struct{sockaddr}, che si
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sockaddr {
-    sa_family_t  sa_family;     /* address family: AF_xxx */
-    char         sa_data[14];   /* address (protocol-specific) */
-};
-    \end{lstlisting}
+    \includestruct{listati/sockaddr.h}
   \end{minipage} 
   \caption{La struttura generica degli indirizzi dei socket
     \structd{sockaddr}.} 
   \end{minipage} 
   \caption{La struttura generica degli indirizzi dei socket
     \structd{sockaddr}.} 
@@ -442,17 +437,7 @@ si usa IPv4) 
 \begin{figure}[!htb]
   \footnotesize\centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize\centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sockaddr_in {
-    sa_family_t     sin_family; /* address family: AF_INET */
-    in_port_t       sin_port;   /* port in network byte order */
-    struct in_addr  sin_addr;   /* internet address */
-};
-/* Internet address. */
-struct in_addr {
-    in_addr_t       s_addr;     /* address in network byte order */
-};
-    \end{lstlisting}
+    \includestruct{listati/sockaddr_in.h}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket internet (IPv4)
     \structd{sockaddr\_in}.}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket internet (IPv4)
     \structd{sockaddr\_in}.}
@@ -503,18 +488,7 @@ in \figref{fig:sock_sa_ipv6_struct}.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sockaddr_in6 {
-    uint16_t        sin6_family;   /* AF_INET6 */
-    in_port_t       sin6_port;     /* port number */
-    uint32_t        sin6_flowinfo; /* IPv6 flow information */
-    struct in6_addr sin6_addr;     /* IPv6 address */
-    uint32_t        sin6_scope_id; /* Scope id (new in 2.4) */
-};
-struct in6_addr {
-    uint8_t       s6_addr[16];   /* IPv6 address */
-};
-    \end{lstlisting}
+    \includestruct{listati/sockaddr_in6.h}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket IPv6 
     \structd{sockaddr\_in6}.}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket IPv6 
     \structd{sockaddr\_in6}.}
@@ -555,13 +529,7 @@ ad uno di questi socket si deve usare una struttura degli indirizzi di tipo
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-#define UNIX_PATH_MAX    108
-struct sockaddr_un {
-    sa_family_t  sun_family;              /* AF_UNIX */
-    char         sun_path[UNIX_PATH_MAX]; /* pathname */
-};
-    \end{lstlisting}
+    \includestruct{listati/sockaddr_un.h}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket locali (detti anche
     \textit{unix domain}) \structd{sockaddr\_un} definita in \file{sys/un.h}.}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket locali (detti anche
     \textit{unix domain}) \structd{sockaddr\_un} definita in \file{sys/un.h}.}
@@ -603,17 +571,7 @@ file \file{netatalk/at.h}.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sockaddr_atalk {
-    sa_family_t     sat_family; /* address family */
-    uint8_t         sat_port;   /* port */
-    struct at_addr  sat_addr;   /* net/node */
-};
-struct at_addr {
-    uint16_t        s_net;
-    uint8_t         s_node;
-};
-    \end{lstlisting}
+    \includestruct{listati/sockaddr_atalk.h}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket AppleTalk 
     \structd{sockaddr\_atalk}.}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket AppleTalk 
     \structd{sockaddr\_atalk}.}
@@ -684,17 +642,7 @@ occorre usare la funzione \func{bind} per agganciare il socket a quest'ultima.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[stepnumber=0]{}
-struct sockaddr_ll {
-    unsigned short  sll_family;    /* Always AF_PACKET */
-    unsigned short  sll_protocol;  /* Physical layer protocol */
-    int             sll_ifindex;   /* Interface number */
-    unsigned short  sll_hatype;    /* Header type */
-    unsigned char   sll_pkttype;   /* Packet type */
-    unsigned char   sll_halen;     /* Length of address */
-    unsigned char   sll_addr[8];   /* Physical layer address */
-};
-    \end{lstlisting}
+    \includestruct{listati/sockaddr_ll.h}
   \end{minipage} 
   \caption{La struttura \structd{sockaddr\_ll} degli indirizzi dei
     \textit{packet socket}.}
   \end{minipage} 
   \caption{La struttura \structd{sockaddr\_ll} degli indirizzi dei
     \textit{packet socket}.}
@@ -1043,33 +991,11 @@ sono disponibili: 
 \secref{sec:ipc_pipes}).
 
 \begin{figure}[htb]
 \secref{sec:ipc_pipes}).
 
 \begin{figure}[htb]
-  \centering
-  \footnotesize
-  \begin{lstlisting}{}
-#include <unistd.h>
-
-ssize_t FullRead(int fd, void *buf, size_t count) 
-{
-    size_t nleft;
-    ssize_t nread;
-    nleft = count;
-    while (nleft > 0) {             /* repeat until no left */
-        if ( (nread = read(fd, buf, nleft)) < 0) {
-            if (errno == EINTR) {   /* if interrupted by system call */
-                continue;           /* repeat the loop */
-            } else {
-                return(nread);      /* otherwise exit */
-            }
-        } else if (nread == 0) {    /* EOF */
-            break;                  /* break loop here */ 
-        }
-        nleft -= nread;             /* set left to read */
-        buf +=nread;                /* set pointer */
-    }
-    return (count - nleft);
-}  
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/FullRead.c}
+  \end{minipage} 
+  \normalsize
   \caption{Funzione \func{FullRead}, legge esattamente \var{count} byte da un
     file descriptor, iterando opportunamente le letture.}
   \label{fig:sock_FullRead_code}
   \caption{Funzione \func{FullRead}, legge esattamente \var{count} byte da un
     file descriptor, iterando opportunamente le letture.}
   \label{fig:sock_FullRead_code}
@@ -1086,30 +1012,11 @@ disponibile fra i sorgenti allegati alla guida nei file \file{FullRead.c} e
 
 \begin{figure}[htb]
   \centering
 
 \begin{figure}[htb]
   \centering
-  \footnotesize
-  \begin{lstlisting}{}
-#include <unistd.h>
-
-ssize_t FullWrite(int fd, const void *buf, size_t count) 
-{
-    size_t nleft;
-    ssize_t nwritten;
-
-    nleft = count;
-    while (nleft > 0) {             /* repeat until no left */
-        if ( (nwritten = write(fd, buf, nleft)) < 0) {
-            if (errno == EINTR) {   /* if interrupted by system call */
-                continue;           /* repeat the loop */
-            } else {
-                return(nwritten);   /* otherwise exit with error */
-            }
-        }
-        nleft -= nwritten;          /* set left to write */
-        buf +=nwritten;             /* set pointer */
-    }
-    return (count);
-}  
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/FullWrite.c}
+  \end{minipage} 
+  \normalsize
   \caption{Funzione \func{FullWrite}, scrive \var{count} byte su un socket.}
   \label{fig:sock_FullWrite_code}
 \end{figure}
   \caption{Funzione \func{FullWrite}, scrive \var{count} byte su un socket.}
   \label{fig:sock_FullWrite_code}
 \end{figure}
@@ -1143,57 +1050,11 @@ standard che restituisce l'ora locale della macchina a cui si effettua la
 richiesta.
 
 \begin{figure}[!htb]
 richiesta.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <sys/types.h>   /* predefined types */
-#include <unistd.h>      /* include unix standard library */
-#include <arpa/inet.h>   /* IP addresses conversion utilities */
-#include <sys/socket.h>  /* socket library */
-#include <stdio.h>       /* include standard I/O library */
-
-int main(int argc, char *argv[])
-{
-    int sock_fd;
-    int i, nread;
-    struct sockaddr_in serv_add;
-    char buffer[MAXLINE];
-     ...
-    /* create socket */
-    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        return -1;
-    }
-    /* initialize address */
-    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                   /* address type is INET */
-    serv_add.sin_port = htons(13);                   /* daytime post is 13 */
-    /* build address using inet_pton */
-    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
-        perror("Address creation error");
-        return -1;
-    }
-    /* extablish connection */
-    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("Connection error");
-        return -1;
-    }
-    /* read daytime from server */
-    while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) {
-        buffer[nread]=0;
-        if (fputs(buffer, stdout) == EOF) {          /* write daytime */
-            perror("fputs error");
-            return -1;
-        }
-    }
-    /* error on read */
-    if (nread < 0) {
-        perror("Read error");
-        return -1;
-    }
-    /* normal exit */
-    return 0;
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/ElemDaytimeTCPClient.c}
+  \end{minipage} 
+  \normalsize
   \caption{Esempio di codice di un client elementare per il servizio daytime.}
   \label{fig:net_cli_code}
 \end{figure}
   \caption{Esempio di codice di un client elementare per il servizio daytime.}
   \label{fig:net_cli_code}
 \end{figure}
@@ -1265,65 +1126,11 @@ nuovamente mostrato in \figref{fig:net_serv_code}, il sorgente completo
 directory \file{sources}.
 
 \begin{figure}[!htbp]
 directory \file{sources}.
 
 \begin{figure}[!htbp]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <sys/types.h>   /* predefined types */
-#include <unistd.h>      /* include unix standard library */
-#include <arpa/inet.h>   /* IP addresses conversion utilities */
-#include <sys/socket.h>  /* socket library */
-#include <stdio.h>       /* include standard I/O library */
-#include <time.h>
-#define MAXLINE 80
-#define BACKLOG 10
-int main(int argc, char *argv[])
-{
-/* 
- * Variables definition  
- */
-    int list_fd, conn_fd;
-    int i;
-    struct sockaddr_in serv_add;
-    char buffer[MAXLINE];
-    time_t timeval;
-    ...
-    /* create socket */
-    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        perror("Socket creation error");
-        exit(-1);
-    }
-    /* initialize address */
-    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
-    serv_add.sin_family = AF_INET;                  /* address type is INET */
-    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
-    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
-    /* bind socket */
-    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
-        perror("bind error");
-        exit(-1);
-    }
-    /* listen on socket */
-    if (listen(list_fd, BACKLOG) < 0 ) {
-        perror("listen error");
-        exit(-1);
-    }
-    /* write daytime to client */
-    while (1) {
-        if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
-            perror("accept error");
-            exit(-1);
-        }
-        timeval = time(NULL);
-        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
-        if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
-            perror("write error");
-            exit(-1);
-        }
-        close(conn_fd);
-    }
-    /* normal exit */
-    exit(0);
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/ElemDaytimeTCPServer.c}
+  \end{minipage} 
+  \normalsize
   \caption{Esempio di codice di un semplice server per il servizio daytime.}
   \label{fig:net_serv_code}
 \end{figure}
   \caption{Esempio di codice di un semplice server per il servizio daytime.}
   \label{fig:net_serv_code}
 \end{figure}