+\func{open} in questo caso non fa differenza) può essere usato per rimuovere
+un lock, dato che quello che conta è solo il \acr{pid} del processo. Da questo
+deriva una ulteriore sottile differenza di comportamento: dato che alla
+chiusura di un file i lock ad esso associati vengono rimossi, nella semantica
+POSIX basterà chiudere un file descriptor qualunque per cancellare tutti i
+lock relativi al file cui esso faceva riferimento, anche se questi fossero
+stati creati usando altri file descriptor che restano aperti.
+
+Dato che il controllo sull'accesso ai lock viene eseguito sulla base del
+\acr{pid} del processo, possiamo anche prendere in cosiderazione un'altro
+degli aspetti meno chiari di questa interfaccia e cioè cosa succede quando si
+richiedono dei lock su regioni che si sovrappongono fra loro all'interno
+stesso processo. Siccome il controllo, come nel caso della rimozione, si basa
+solo sul \acr{pid} del processo che chiama la funzione, queste richieste
+avranno sempre successo.
+
+Nel caso della semantica BSD, essendo i lock relativi a tutto un file e non
+accumulandosi,\footnote{questa ultima caratteristica è vera in generale, se
+ cioè si richiede più volte lo stesso file lock, o più lock sula stessa
+ sezione di file, le richieste non si cumulano e basta una sola richiesta di
+ rilascio per cancellare il lock.} la cosa non ha alcun effetto; la funzione
+ritorna con successo, senza che il kernel debba modificare la lista dei lock.
+In questo caso invece si possono avere una serie di situazioni diverse: ad
+esempio è possibile rimuovere con una sola chiamata più lock distinti
+(indicando in una regione che si sovrapponga completamente a quelle di questi
+ultimi), o rimuovere solo una parte di un lock preesistente (indicando una
+regione contenuta in quella di un altro lock), creando un buco, o coprire con
+un nuovo lock altri lock già ottenuti, e così via, a secondo di come si
+sovrappongono le regioni richieste e del tipo di operazione richiesta. Il
+comportamento seguito in questo caso che la funzione ha successo ed esegue
+l'operazione richiesta sulla regione indicata; è compito del kernel
+preoccuparsi di accorpare o dividere le voci nella lista dei lock per far si
+che le regioni bloccate da essa risultanti siano coerenti con quanto
+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}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione principale del codice del programma \file{Flock.c}.}
+ \label{fig:file_flock_code}
+\end{figure}
+
+Per fare qualche esempio sul file locking si è scritto un programma che
+permette di bloccare una sezione di un file usando la semantica POSIX, o un
+intero file usando la semantica BSD; in \figref{fig:file_flock_code} è
+riportata il corpo principale del codice del programma, (il testo completo è
+allegato nella directory dei sorgenti).
+
+La sezione relativa alla gestione delle opzioni al solito si è omessa, come la
+funzione che stampa le istruzioni per l'uso del programma, essa si cura di
+impostare le variabili \var{type}, \var{start} e \var{len}; queste ultime due
+vengono inizializzate al valore numerico fornito rispettivamente tramite gli
+switch \code{-s} e \cmd{-l}, mentre il valore della prima viene impostato con
+le opzioni \cmd{-w} e \cmd{-r} si richiede rispettivamente o un write lock o
+read lock (i due valori sono esclusivi, la variabile assumerà quello che si è
+specificato per ultimo). Oltre a queste tre vengono pure impostate la
+variabile \var{bsd}, che abilita la semantica omonima quando si invoca
+l'opzione \cmd{-f} (il valore preimpostato è nullo, ad indicare la semantica
+POSIX), e la variabile \var{cmd} che specifica la modalità di richiesta del
+lock (bloccante o meno), a seconda dell'opzione \cmd{-b}.
+
+Il programma inizia col controllare (\texttt{\small 11--14}) che venga passato
+un parametro (il file da bloccare), che sia stato scelto (\texttt{\small
+ 15--18}) il tipo di lock, dopo di che apre (\texttt{\small 19}) il file,
+uscendo (\texttt{\small 20--23}) in caso di errore. A questo punto il
+comportamento dipende dalla semantica scelta; nel caso sia BSD occorre
+reimpostare il valore di \var{cmd} per l'uso con \func{flock}; infatti il
+valore preimpostato fa riferimento alla semantica POSIX e vale rispettivamente
+\macro{F\_SETLKW} o \macro{F\_SETLK} a seconda che si sia impostato o meno la
+modalità bloccante.
+
+Nel caso si sia scelta la semantica BSD (\texttt{\small 25--34}) prima si
+controlla (\texttt{\small 27--31}) il valore di \var{cmd} per determinare se
+si vuole effettuare una chiamata bloccante o meno, reimpostandone il valore
+opportunamente, dopo di che a seconda del tipo di lock al valore viene
+aggiunta la relativa opzione (con un OR aritmetico, dato che \func{flock}
+vuole un argomento \param{operation} in forma di maschera binaria. Nel caso
+invece che si sia scelta la semantica POSIX le operazioni sono molto più
+immediate, si prepara (\texttt{\small 36--40}) la struttura per il lock, e lo
+esegue (\texttt{\small 41}).
+
+In entrambi i casi dopo aver richiesto il lock viene controllato il risultato
+uscendo (\texttt{\small 44--46}) in caso di errore, o stampando un messaggio
+(\texttt{\small 47--49}) in caso di successo. Infine il programma si pone in
+attesa (\texttt{\small 50}) finché un segnale (ad esempio un \cmd{C-c} dato da
+tastiera) non lo interrompa; in questo caso il programma termina, e tutti i
+lock vengono rilasciati.
+
+Con il programma possiamo fare varie verifiche sul funzionamento del file
+locking; cominciamo con l'eseguire un read lock su un file, ad esempio usando
+all'interno di un terminale il seguente comando:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+il programma segnalerà di aver acquisito un lock e si bloccherà; in questo
+caso si è usato il file locking POSIX e non avendo specificato niente riguardo
+alla sezione che si vuole bloccare sono stati usati i valori preimpostati che
+bloccano tutto il file. A questo punto se proviamo ad eseguire lo stesso
+comando in un altro terminale, e avremo lo stesso risultato. Se invece
+proviamo ad eseguire un write lock avremo:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+come ci aspettiamo il programma terminerà segnalando l'indisponibilità del
+lock, dato che il file è bloccato dal precedente read lock. Si noti che il
+risultato è lo stesso anche se si richiede il blocco su una sola parte del
+file con il comando:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s0 -l10 Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+se invece blocchiamo una regione con:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r -s0 -l10 Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+una volta che riproviamo ad acquisire il write lock i risultati dipenderanno
+dalla regione richiesta; ad esempio nel caso in cui le due regioni si
+sovrappongono avremo che:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s5 -l15 Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+ed il lock viene rifiutato, ma se invece si richiede una regione distinta
+avremo che:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s11 -l15 Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+ed il lock viene acquisito. Se a questo punto si prova ad eseguire un read
+lock che comprende la nuova regione bloccata in scrittura:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r -s10 -l20 Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+come ci aspettimo questo non sarà consentito.
+
+Il programma di norma esegue il tentativo di acquisire il lock in modalità non
+bloccante, se però usiamo l'opzione \cmd{-b} possiamo impostare la modalità
+bloccante, riproviamo allora a ripetere le prove precedenti con questa
+opzione:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r -b -s0 -l10 Flock.c Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+il primo comando acquisisce subito un read lock, e quindi non cambia nulla, ma
+se proviamo adesso a richidere un write lock che non potrà essere acquisito
+otterremo:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s0 -l10 Flock.c
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+il programma cioè si bloccherà nella chiamata a \func{fcntl}; se a questo
+punto rilasciamo il precedente lock (terminando il primo comando un
+\texttt{C-c} sul terminale) potremo verificare che sull'altro terminale il
+lock viene acquisito, con la comparsa di una nuova riga:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s0 -l10 Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{3mm}
+\par\noindent
+
+Un'altra cosa che si può controllare con il nostro programma è l'interazione
+fra i due tipi di lock; se ripartiamo dal primo comando con cui si è ottenuto
+un lock in lettura sull'intero file, possiamo verificare cosa succede quando
+si cerca di ottenere un lock in scrittura con la semantica BSD:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[root@gont sources]# ./flock -f -w Flock.c
+Lock acquired
+\end{verbatim}
+\end{minipage}\vspace{1mm}
+\par\noindent
+che ci mostra come i due tipi di lock siano assolutamente indipendenti; per
+questo motivo occorre sempre tenere presente quale fra le due semantiche
+disponibili stanno usando i programmi con cui si interagisce, dato che i lock
+applicati con l'altra non avrebbero nessun effetto.
+
+
+
+\subsection{La funzione \func{lockf}}
+\label{sec:file_lockf}