From: Simone Piccardi Date: Thu, 16 Aug 2007 15:23:21 +0000 (+0000) Subject: Risistemata versione del programma di esempio di {{{splice}}}, X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=45633dbe15fd23b17a975eb4d9c231d22a67ac00 Risistemata versione del programma di esempio di {{{splice}}}, funziona solo su kernel che la supportano (Ubuntu 32bit pare di no...) --- diff --git a/fileadv.tex b/fileadv.tex index 1581fbb..a7851b6 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -2963,16 +2963,39 @@ l'argomento in sez.~\ref{sec:ipc_unix}). Dal punto di vista concettuale allora l'oggetto \textsl{buffer in kernel space}. Così se per una \textit{pipe} o una \textit{fifo} il buffer viene utilizzato -(come illustrato in fig.~\ref{fig:ipc_pipe_singular}) come area di memoria -dove appoggiare i dati che vengono trasferiti da un capo all'altro della -stessa, creando un meccanismo di comunicazione fra processi, nel caso di -\func{splice} il buffer viene usato o come fonte dei dati che con saranno -scritti su un file, o come destinazione dei dati che vengono letti da un file. - - - +come area di memoria dove appoggiare i dati che vengono trasferiti da un capo +all'altro della stessa (vedi fig.~\ref{fig:ipc_pipe_singular}) per creare un +meccanismo di comunicazione fra processi, nel caso di \funcd{splice} il buffer +viene usato o come fonte dei dati che saranno scritti su un file, o come +destinazione dei dati che vengono letti da un file. La funzione infatti è una +interfaccia generica che consente di trasferire dati da un buffer ad un file o +viceversa; il suo prototipo, accessibile solo avendo definito +\macro{\_GNU\_SOURCE},\footnote{ovviamente, essendo come detto la funzione + totalmente specifica di Linux, essa non è prevista da nessuno standard e + deve essere evitata se si vogliono scrivere programmi portabili.} è: +\begin{functions} + \headdecl{fcntl.h} + \funcdecl{} + + Trasferisce dati da un file verso una pipe o viceversa. + \bodydesc{La funzione restituisce il numero di byte trasferiti in caso di + successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno + dei valori: + \begin{errlist} + \item[\errcode{EAGAIN}] si è impostata la modalità non bloccante su + \param{out\_fd} e la scrittura si bloccherebbe. + \item[\errcode{EINVAL}] i file descriptor non sono validi, o sono bloccati + (vedi sez.~\ref{sec:file_locking}), o \func{mmap} non è disponibile per + \param{in\_fd}. + \item[\errcode{EIO}] si è avuto un errore di lettura da \param{in\_fd}. + \item[\errcode{ENOMEM}] non c'è memoria sufficiente per la lettura da + \param{in\_fd}. + \end{errlist} + ed inoltre \errcode{EBADF} e \errcode{EFAULT}. + } +\end{functions} diff --git a/img/splice_copy.dia b/img/splice_copy.dia new file mode 100644 index 0000000..5c57b6f Binary files /dev/null and b/img/splice_copy.dia differ diff --git a/sockctrl.tex b/sockctrl.tex index a2323e3..bfdfcd9 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -4122,13 +4122,13 @@ accessibile con \texttt{man 7 ip}, sono i seguenti: \item[\procrelfile{/proc/sys/net/ipv4}{ip\_local\_port\_range}] imposta l'intervallo dei valori usati per l'assegnazione delle porte effimere, permette cioè di modificare i valori illustrati in - fig.~\ref{fig:TCP_port_alloc}; prende due valori numerici, che indicano gli - estremi dell'intervallo. Si abbia cura di non definire un intervallo che si - sovrappone a quello delle porte usate per il \itindex{masquerading} - \textit{masquerading}, il kernel può gestire la sovrapposizione, ma si avrà - una perdita di prestazioni. Si imposti sempre un valore iniziale maggiore di - 1024 (o meglio ancora di 4096) per evitare conflitti con le porte usate dai - servizi noti. + fig.~\ref{fig:TCP_port_alloc}; prende due valori interi separati da spazi, + che indicano gli estremi dell'intervallo. Si abbia cura di non definire un + intervallo che si sovrappone a quello delle porte usate per il + \itindex{masquerading} \textit{masquerading}, il kernel può gestire la + sovrapposizione, ma si avrà una perdita di prestazioni. Si imposti sempre un + valore iniziale maggiore di 1024 (o meglio ancora di 4096) per evitare + conflitti con le porte usate dai servizi noti. \item[\procrelfile{/proc/sys/net/ipv4}{ip\_no\_pmtu\_disc}] permette di disabilitare per i socket \const{SOCK\_STREAM} la ricerca automatica della @@ -4425,11 +4425,17 @@ pagina di manuale (accessibile con \texttt{man 7 tcp}), sono i seguenti: nell'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323}. Di default è abilitato. -\item[\procrelfile{/proc/sys/net/ipv4}{tcp\_tw\_recycle}] +\item[\procrelfile{/proc/sys/net/ipv4}{tcp\_tw\_recycle}] un valore logico, + disattivo di default, che abilita un rapido riutilizzo dei socket in stato + \texttt{TIME\_WAIT}. Non è opportuno abilitare questa opzione che può + causare problemi con il NAT. \item[\procrelfile{/proc/sys/net/ipv4}{tcp\_tw\_reuse}] -\item[\procrelfile{/proc/sys/net/ipv4}{tcp\_window\_scaling}] +\item[\procrelfile{/proc/sys/net/ipv4}{tcp\_window\_scaling}] un valore + logico, attivo di default, che abilita la funzionalità del \textit{TCP + window scaling} definita + dall'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323} \item[\procrelfile{/proc/sys/net/ipv4}{tcp\_vegas\_cong\_avoid}] diff --git a/sources/splicecp.c b/sources/splicecp.c index feda8e6..c19066f 100644 --- a/sources/splicecp.c +++ b/sources/splicecp.c @@ -35,14 +35,14 @@ #include /* error definitions and routines */ #include /* standard I/O library */ #include /* C strings library */ -#include -#include +#include /* file characteristics constants and functions */ +#include /* primitive system data types */ +#include "macros.h" /* * Function and globals definitions */ void usage(void); /* Help printing routine */ - /* * Main program */ @@ -89,7 +89,7 @@ int main(int argc, char *argv[]) usage(); } /* open pipe, input and output file */ - if (pipe(pipefd) == -1) { + if (pipe(pipefd) == -1) { perror("Cannot create buffer pipe"); exit(EXIT_FAILURE); } @@ -98,45 +98,43 @@ int main(int argc, char *argv[]) printf("Input error %s on %s\n", strerror(errno), argv[optind]); exit(EXIT_FAILURE); } - out_fd = open(argv[optind+1], O_CREAT|O_RDWR, 0644); + out_fd = open(argv[optind+1], O_CREAT|O_RDWR|O_TRUNC, 0644); if (out_fd < 0) { printf("Cannot open %s, error %s\n", argv[optind+1], strerror(errno)); exit(EXIT_FAILURE); } /* copy loop */ - printf("Size %d\n", size); + debug("Size %d\n", size); while (1) { nread = splice(in_fd, NULL, pipefd[1], NULL, size, 0); - printf("read %d bytes\n", nread); + debug("read %d bytes\n", nread); if (nread == 0) break; if (nread < 0) { if (errno == EINTR) { continue; } else { perror("read error"); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } do { - nwrite = splice(pipefd[0], NULL, out_fd, NULL, nread, 0); - printf("write %d bytes\n", nwrite); + nwrite = splice(pipefd[0], NULL, out_fd, NULL, nread, 0); + debug("write %d bytes\n", nwrite); if (nwrite == 0) continue; if (nwrite < 0) { if (errno == EINTR) continue; - } else { - perror("write error"); - exit(EXIT_FAILURE); + else { + perror("write error"); + exit(EXIT_FAILURE); + } } nread -= nwrite; - printf("left %d bytes", nread); + debug("left %d bytes\n", nread); } while (nread); } return EXIT_SUCCESS; } - - - /* * routine to print usage info and exit */