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:
-
-\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
@@ -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:
-\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}.
@@ -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]
-  \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}
index 9980d895a06ce42c75840ee22a1aff8f3f75dd21..d184c31ba02b16833ce9c7ae34913324dee4fb1b 100644 (file)
@@ -211,17 +211,11 @@ negativo indica un'attesa indefinita).
 \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 
-  \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}
 
@@ -421,21 +415,10 @@ disponibilit
 \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 
-  \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}
@@ -471,20 +454,11 @@ esse.
 \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 
-  \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}
 
@@ -818,15 +792,10 @@ il secondo, \var{iov\_len}, la dimensione dello stesso.
 \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 
-  \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}
@@ -1512,18 +1481,10 @@ regione bloccata.
 \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 
-  \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}
@@ -1717,60 +1678,7 @@ necessario a soddisfare l'operazione richiesta.
 \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}.}
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{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} 
@@ -423,37 +375,7 @@ invocato dopo.
 \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}.}
@@ -594,60 +516,7 @@ diverso da quelli preimpostati. Il codice completo 
 \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}
@@ -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{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}
@@ -1002,18 +834,7 @@ mantiene varie propriet
 \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
@@ -1210,41 +1031,7 @@ s
 \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
@@ -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{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
@@ -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:
-\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
@@ -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).
-\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}
@@ -1595,12 +1368,7 @@ dovr
 \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
@@ -1755,57 +1523,8 @@ in maniera indipendente con client diversi.
 
 \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}
@@ -1878,26 +1597,8 @@ gestore \code{HandSIGTERM}, che semplicemente si limita a cancellare la coda
 
 \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}
@@ -2087,15 +1788,7 @@ semaforo all'uscita del processo.
 \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
@@ -2137,14 +1830,7 @@ controllo.
 \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
@@ -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{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}
@@ -2388,14 +2066,7 @@ effettivamente eseguite se e soltanto se 
 \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
@@ -2571,57 +2242,7 @@ nullo per segnalarne l'indisponibilit
 \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
@@ -2749,18 +2370,7 @@ norma, significa insieme a dei semafori.
 \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
@@ -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:
-\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
@@ -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.
-\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
@@ -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.
 
-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{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
@@ -3112,6 +2665,11 @@ int ShmRemove(key_t ipc_key, void * shm_ptr)
   \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
@@ -3185,58 +2743,8 @@ video; al solito il codice completo si trova con i sorgenti allegati nel file
 
 \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}.}
@@ -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.
 
+\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.
@@ -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}.
 
-
-\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
@@ -3374,36 +2857,8 @@ rimuove il mutex con \func{MutexRemove} ed esce (\texttt{\small 22}).
 
 \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
@@ -3592,26 +3047,8 @@ cancella con \func{unlink}.
 
 \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
@@ -3672,64 +3109,8 @@ leggermente pi
 
 \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 
@@ -4037,14 +3418,7 @@ struttura \struct{mq\_attr}, la cui definizione 
 \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
@@ -4514,54 +3888,8 @@ descriptor che fa riferimento ad un segmento distinto da eventuali precedenti.
 
 \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
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{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
@@ -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:
 
-\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.
@@ -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:
-\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
@@ -1651,30 +1635,11 @@ effettuano pi
 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}
@@ -1703,33 +1668,18 @@ infine si scrive il nuovo valore modificato con \func{tcsetattr}
 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
-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.
 
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
@@ -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. 
 
-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
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]
-  \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}
@@ -142,19 +92,11 @@ dati di cui 
 \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}
@@ -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.
+
 \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}
@@ -227,21 +140,11 @@ preoccupa di gestire la comunicazione, leggendo una riga alla volta dallo
 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}
@@ -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:
-\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
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{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}.} 
@@ -442,17 +437,7 @@ si usa IPv4) 
 \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}.}
@@ -503,18 +488,7 @@ in \figref{fig:sock_sa_ipv6_struct}.
 \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}.}
@@ -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{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}.}
@@ -603,17 +571,7 @@ file \file{netatalk/at.h}.
 \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}.}
@@ -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{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}.}
@@ -1043,33 +991,11 @@ sono disponibili: 
 \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}
@@ -1086,30 +1012,11 @@ disponibile fra i sorgenti allegati alla guida nei file \file{FullRead.c} e
 
 \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}
@@ -1143,57 +1050,11 @@ standard che restituisce l'ora locale della macchina a cui si effettua la
 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}
@@ -1265,65 +1126,11 @@ nuovamente mostrato in \figref{fig:net_serv_code}, il sorgente completo
 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}