Inizio trattazione statx
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 18 Aug 2019 14:53:21 +0000 (16:53 +0200)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 18 Aug 2019 14:53:21 +0000 (16:53 +0200)
fileio.tex
listati/InitFile.c [new file with mode: 0644]
listati/statx.h [new file with mode: 0644]
sources/Gapil.h
sources/InitFile.c
sources/test_initfile.c

index d2522e1442955588d0147419db29764fdb6eeed0..a99960a1e7bfd120679d36c5a0772863ccf06770 100644 (file)
@@ -1764,7 +1764,6 @@ specificata.\footnote{l'introduzione è avvenuta su proposta dello sviluppatore
 Essendo accomunate dalla stessa interfaccia le tratteremo insieme in questa
 sezione pur non essendo strettamente attinenti l'I/O su file.
 
 Essendo accomunate dalla stessa interfaccia le tratteremo insieme in questa
 sezione pur non essendo strettamente attinenti l'I/O su file.
 
-
 Benché queste funzioni non siano presenti negli standard tradizionali esse
 sono state adottate da altri sistemi unix-like come Solaris, i vari BSD, fino
 ad essere incluse in una recente revisione dello standard POSIX.1 (la
 Benché queste funzioni non siano presenti negli standard tradizionali esse
 sono state adottate da altri sistemi unix-like come Solaris, i vari BSD, fino
 ad essere incluse in una recente revisione dello standard POSIX.1 (la
@@ -2136,7 +2135,7 @@ utilizzare invece la funzione di sistema \funcd{fstatat}, il cui prototipo è:
 \fhead{sys/stat.h}
 \fdecl{int fstatat(int dirfd, const char *pathname, struct stat *statbuf, int
   flags)} 
 \fhead{sys/stat.h}
 \fdecl{int fstatat(int dirfd, const char *pathname, struct stat *statbuf, int
   flags)} 
-\fdesc{Rimuove una voce da una directory.} 
+\fdesc{Legge le informazioni di un file.} 
 }
 
 {La funzione ritorna gli stessi valori e gli stessi codici di errore di
 }
 
 {La funzione ritorna gli stessi valori e gli stessi codici di errore di
@@ -2231,7 +2230,6 @@ consentirebbe rendere accessibile all'interno di un \textit{choot} (vedi
 sez.~\ref{sec:file_chroot}) un qualunque file sia stato aperto fuori dallo
 stesso prima di entrarvi.
 
 sez.~\ref{sec:file_chroot}) un qualunque file sia stato aperto fuori dallo
 stesso prima di entrarvi.
 
-
 % NOTE per la discussione sui problemi di sicurezza relativi a questa
 % funzionalità vedi http://lwn.net/Articles/562488/
 
 % NOTE per la discussione sui problemi di sicurezza relativi a questa
 % funzionalità vedi http://lwn.net/Articles/562488/
 
@@ -2239,52 +2237,73 @@ Per questo motivo l'uso di \const{AT\_EMPTY\_PATH} richiede comunque privilegi
 amministrativi, anche se, quando è disponibile il filesystem \texttt{/proc}, è
 possibile usare \func{linkat} per creare un file da un qualunque file
 descriptor un processo abbia aperto, usandola con un codice analogo al
 amministrativi, anche se, quando è disponibile il filesystem \texttt{/proc}, è
 possibile usare \func{linkat} per creare un file da un qualunque file
 descriptor un processo abbia aperto, usandola con un codice analogo al
-seguente:\footnote{non esiste, al momento, una modalità per evitare i rischi
-  illustrati in precedenza se si sta usando il filesystem \textit{proc}.}
+seguente:\footnote{non esiste al momento, se si sta usando il filesystem
+  \textit{proc}, una modalità per evitare i rischi illustrati in precedenza.}
 \includecodesnip{listati/procfd_linkat.c}
 \includecodesnip{listati/procfd_linkat.c}
-
-Questa modalità è anche quella con cui è possibile assegnare in un secondo
+e questa modalità è anche quella con cui è possibile assegnare in un secondo
 tempo il nome ad un file anonimo creato usando \func{open} con
 \const{O\_TMPFILE}; ma si deve tenere presente che per questi file la funzione
 tempo il nome ad un file anonimo creato usando \func{open} con
 \const{O\_TMPFILE}; ma si deve tenere presente che per questi file la funzione
-ha un comportamento particolare. In generale infatti quando il file sorgente
-di \func{linkat} ha un numero di collegamenti nulli (cosa che avviene ad
-esempio quando si apre un file temporaneo e lo si cancella subito dopo oppure
-quando viene cancellato un file aperto in precedenza) la funzione non consente
-di ricollegarlo ad un altro file riassegnandogli un nuovo nome e fallisce
-sempre, qualunque siano i permessi del processo e che si usi questo approccio
-o \const{AT\_EMPTY\_PATH}, con un errore di \errval{ENOENT}.
-
-Questo non avviene se il file descriptor sorgente è stato ottenuto con
-\const{O\_TMPFILE} e la funzione ha successo, a meno che non si sia usato
-nell'apertura anche \const{O\_EXCL} per impedire questo specifico
-comportamento, e continuare ad ottenere l'errore di \errval{ENOENT}. In fig.
-
-Pertanto la modalità per creare in maniera sicura la versione iniziale di un
-file cui abbiamo accennato a pag.~\pageref{open_o_tmpfile_flag},
-
+ha un comportamento particolare.
+
+In generale infatti quando il file sorgente di \func{linkat} ha un numero di
+collegamenti nulli (cosa che avviene ad esempio quando si apre un file
+temporaneo e lo si cancella subito dopo oppure quando viene cancellato un file
+aperto in precedenza) la funzione non consente di ricollegarlo ad un altro
+file riassegnandogli un nuovo nome e fallisce sempre con un errore di
+\errval{ENOENT} qualunque siano i permessi del processo, e che si usi questo
+approccio o \const{AT\_EMPTY\_PATH}.  Ma questo non avviene se il file
+descriptor è stato ottenuto con \const{O\_TMPFILE}, in tal caso la funzione ha
+successo, a meno che non si sia usato nell'apertura anche \const{O\_EXCL} per
+impedire questo comportamento, e continuare ad ottenere \errval{ENOENT}.
+
+In fig.~\ref{fig:initfile} si è riportato il codice della funzione
+\func{InitFile}, che consente di creare in maniera sicura il contenuto
+iniziale di un file utilizzando \const{O\_TMPFILE} e \func{linkat}, come
+accennato a pag.~\pageref{open_o_tmpfile_flag}. La funzione richiede di
+indicare il file da creare usando la sintassi delle \textit{at-functions},
+specificando la directory in cui crearlo con il corrispondente file descriptor
+passato nell'argomento \texttt{dirfd} ed il pathname relativo ed essa passato
+l'argomento \texttt{file}; il contenuto iniziale del file deve essere fornito
+nel buffer \texttt{buf} di lunghezza \texttt{size}.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
-    \includecodesample{listati/initfile.c}
+    \includecodesample{listati/InitFile.c}
   \end{minipage}
   \end{minipage}
-  \caption{Esempio di codice creare in maniera sicura il contenuto iniziale di
-    un file.} 
+  \caption{Esempio di codice per creare in maniera sicura il contenuto
+    iniziale di un file.}
   \label{fig:initfile}
 \end{figure}
 
   \label{fig:initfile}
 \end{figure}
 
-
-
-
-
-
-% TODO: Trattare esempio di inzializzazione di file e successivo collegamento
-% con l'uso di O_TMPFILE e linkat, vedi man open
-
-
-
-% TODO manca prototipo di renameat2, introdotta nel 3.15, vedi
-% http://lwn.net/Articles/569134/ 
-
+La funzione come primo passo (\texttt{\small 6--10}) ottiene un file
+descriptor accessibile in lettura/scrittura invocando \func{openat} con il
+flag \const{O\_TMPFILE} per ottenere un file anonimo, facendo riferimento a
+quella che sarà la directory di destinazione in cui poi verrà collegato lo
+stesso passata dal chiamante in \texttt{dirfd}, usando ``\texttt{.}'' come
+\textit{pathname} relativo. Si noti come nella chiamata si impostino anche
+(per semplicità si è usato un valore fisso) i valori iniziali dei permessi del
+file (lettura e scrittura solo per il proprietario), e come dopo la chiamata
+si controlli la presenza di un eventuale errore, ritornandolo con un messaggio
+qualora avvenga.
+
+Il secondo passo (\texttt{\small 11--15}) è quello di chiamare la funzione
+\func{FullWrite} (che tratteremo in dettaglio in sez.~\ref{sec:sock_io_behav})
+per eseguire la scrittura del contenuto del buffer \texttt{buf} sul file
+anonimo ottenuto con \func{openat}; in sostanza la funzione scrive tutto il
+contenuto del buffer, iterando le scritture qualora non sia possibile eseguire
+tutto con una singola \func{write}, cosa che comunque per i file su disco in
+genere non avviene mai.
+
+Una volta completata con successo la scrittura l'ultimo passo (\texttt{\small
+  17--23}) è collegare il file anonimo con \func{linkat}, per questo però
+occorre utilizzare il \textit{pathname} ad esso associato sotto
+\texttt{/proc}, che viene ottenuto (\texttt{\small 16}) con una
+\func{snprintf} (vedi sez.~\ref{sec:file_formatted_io}) usando file descriptor
+restituito da \func{openat}. Con questo \textit{pathname} si può procedere
+(\texttt{\small 17}) a chiamare \func{linkat} per eseguire il collegamento, in
+cui occorre usare il flag \const{AT\_SYMLINK\_NOFOLLOW} come nell'esempio
+precedente.
 
 Altre due funzioni che utilizzano due \textit{pathname} (e due file
 descriptor) sono \funcd{renameat} e \funcd{renameat2}, corrispondenti alla
 
 Altre due funzioni che utilizzano due \textit{pathname} (e due file
 descriptor) sono \funcd{renameat} e \funcd{renameat2}, corrispondenti alla
@@ -2333,15 +2352,13 @@ aggiuntivo \param{flags}; in questo caso \func{renameat} è totalmente
 equivalente all'utilizzo di \func{renamat2} con un valore nullo per
 \param{flags}.
 
 equivalente all'utilizzo di \func{renamat2} con un valore nullo per
 \param{flags}.
 
-L'uso di \func{renameat} è identico a quello di \func{rename}, con le solite
-note relative alle estensioni delle \textit{at-functions}, applicate ad
-entrambi i \textit{pathname} passati come argomenti alla funzione. Con
-\func{renameat2} l'introduzione dell'argomento \func{flags} (i cui valori
-possibili sono riportati in tab.~\ref{tab:renameat2_flag_values}) ha permesso
-di aggiungere alcune funzionalità non previste al momento da nessuno standard,
-e specifiche di Linux. Si tenga conto che questa funzione di sistema non viene
-definita nella \acr{glibc} per cui deve essere chiamata utilizzando
-\func{syscall} come illustrato in sez.~\ref{sec:intro_syscall}.
+L'uso di \func{renameat} è identico a quello di \func{rename}, con la sintassi
+delle \textit{at-functions} applicabile ad entrambi i \textit{pathname} passati
+come argomenti alla funzione. Con \func{renameat2} l'introduzione
+dell'argomento \func{flags} (i cui valori possibili sono riportati in
+tab.~\ref{tab:renameat2_flag_values}) ha permesso di aggiungere alcune
+funzionalità specifiche di Linux non previste al momento da nessuno standard
+(la funzione è disponibile nelle \acr{glibc} a partire dalla versione 2.28).
 
 \begin{table}[htb]
   \centering
 
 \begin{table}[htb]
   \centering
@@ -2370,13 +2387,12 @@ L'uso dell'argomento \param{flags} in questo caso non attiene alle
 funzionalità relative alla \textit{at-functions}, ma consente di estendere le
 funzionalità di \func{rename}. In particolare \func{renameat2} consente di
 eseguire uno scambio di nomi in maniera atomica usando il flag
 funzionalità relative alla \textit{at-functions}, ma consente di estendere le
 funzionalità di \func{rename}. In particolare \func{renameat2} consente di
 eseguire uno scambio di nomi in maniera atomica usando il flag
-\constd{RENAME\_EXCHANGE}; quando viene specificato la funzione non solo
-rinomina \param{oldpath} in \param{newpath}, ma rinomina anche, senza dover
-effettuare un passaggio intermedio, \param{newpath} in \param{oldpath}. Quando
-si usa questo flag, entrambi i \textit{pathname} passati come argomenti alla
-funzione devono esistere, e non è possibile usare \const{RENAME\_NOREPLACE},
-non ci sono infine restrizioni sul tipo dei file (regolari, directory, link
-simbolici, ecc.) di cui si scambia il nome.
+\constd{RENAME\_EXCHANGE}; se specificato la funzione rinomina in un colpo
+solo \param{oldpath} in \param{newpath} e \param{newpath} in
+\param{oldpath}. Usando questo flag, entrambi i \textit{pathname} passati come
+argomenti devono esistere, e non è possibile usare \const{RENAME\_NOREPLACE},
+non ci sono infine restrizioni sul tipo di file (regolare, directory, link
+simbolici, dispositivo) di cui si scambia il nome.
 
 Il flag \constd{RENAME\_NOREPLACE} consente di richiedere la generazione di un
 errore nei casi in cui \func{rename} avrebbe causato una sovrascrittura della
 
 Il flag \constd{RENAME\_NOREPLACE} consente di richiedere la generazione di un
 errore nei casi in cui \func{rename} avrebbe causato una sovrascrittura della
@@ -2392,20 +2408,27 @@ Infine il flag \constd{RENAME\_WHITEOUT}, introdotto con il kernel 3.18,
 richiede un approfondimento specifico, in quanto attiene all'uso della
 funzione con dei filesystem di tipo \textit{overlay}/\textit{union}, dato che
 il flag ha senso solo quando applicato a file che stanno su questo tipo di
 richiede un approfondimento specifico, in quanto attiene all'uso della
 funzione con dei filesystem di tipo \textit{overlay}/\textit{union}, dato che
 il flag ha senso solo quando applicato a file che stanno su questo tipo di
-filesystem. 
-
-Un \textit{overlay} o \texttt{union filesystem} è un filesystem speciale
-strutturato in livelli, in cui si rende scrivibile un filesystem accessibile
-in sola lettura, \textsl{sovrapponendogli} un filesystem scrivibile su cui
-vanno tutte le modifiche. Un tale tipo di filesystem serve ad esempio a
-rendere scrivibili i dati processati quando si fa partire una distribuzione
-\textit{Live} basata su CD o DVD, ad esempio usando una chiavetta o uno spazio
-disco aggiuntivo.
+filesystem.  Un \textit{overlay} o \textit{union filesystem} è un filesystem
+speciale strutturato in livelli, in cui si rende scrivibile un filesystem
+accessibile in sola lettura, \textsl{sovrapponendogli} un filesystem
+scrivibile su cui vanno tutte le modifiche. Un tale tipo di filesystem serve
+ad esempio a rendere scrivibili i dati processati quando si fa partire una
+distribuzione \textit{Live} basata su CD o DVD, ad esempio usando una
+chiavetta o uno spazio disco aggiuntivo.
 
 In questo caso quando si rinomina un file che sta nello strato in sola lettura
 
 In questo caso quando si rinomina un file che sta nello strato in sola lettura
-quello che succede è questo viene copiato a destinazione sulla parte
-accessibile in scrittura, ma l'originale non può essere cancellato, per far si
-che esso non appaia più è possibile creare 
+questo viene copiato a destinazione sulla parte accessibile in scrittura, ma
+l'originale non può essere cancellato; per far si che esso non appaia più è
+possibile creare un oggetto speciale del filesystem, chiamato
+\textit{whiteout}, che serve a renderlo non più visibile. La funzione consente
+di creare questo oggetto, che in un filesystem ordinario verrebbe visto come
+un file di dispositivo con \textit{major minor} e \textit{minor number} nulli,
+in maniera atomica quando si rinomina un file.  Dato che l'uso di
+\const{RENAME\_WHITEOUT} comporta in sostanza la creazione di un file di
+dispositivo, l'operazione è privilegiata (occorre la \textit{capability}
+\texttt{CAP\_MKNOD}), inoltre occorre anche il supporto nel filesystem usato
+come supporto per la scrittura. Infine l'operazione non è compatibile con
+\const{RENAME\_EXCHANGE}.
 
 \itindend{overlay~filesytem}
 \itindend{union~filesytem}
 
 \itindend{overlay~filesytem}
 \itindend{union~filesytem}
@@ -2416,16 +2439,184 @@ che esso non appaia più è possibile creare
 % https://lwn.net/Articles/707602/ e
 % https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) 
 
 % https://lwn.net/Articles/707602/ e
 % https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) 
 
+Benché non rientri nelle \textit{at-functions} previste nello standard
+POSIX.1-2008, tratteremo qui anche la funzione di sistema \funcd{statx},
+introdotta con il kernel 4.11 e disponibile dalle versione 2.28 della
+\acr{glibc}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fhead{unistd.h}
+\fhead{fcntl.h}
+\fdecl{int statx(int dirfd, const char *pathname, int flags, \\
+\phantom{int statx(}unsigned int mask, struct statx *statxbuf)} 
+\fdesc{Legge le informazioni di un file.} 
+}
+
+{La funzione ritorna gli stessi valori e gli stessi codici di errore di
+  \func{stat}, \func{fstat}, o \func{lstat} a seconda del valore di
+  \param{flags}, ed in più:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
+  \item[\errcode{EINVAL}] \param{flags} non ha un valore valido o \param{mask}
+    ha un valore riservato.
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \textit{pathname} relativo,
+    ma \param{dirfd} fa riferimento ad un file.
+  \end{errlist}
+}  
+\end{funcproto}
+
+La funzione è una estensione specifica di Linux consente di leggere le
+informazioni di un file; ha la stessa sintassi di \func{fstatat} utilizzando
+con lo stesso significato gli argomenti \param{dirfd} e \param{pathname} ed i
+valori \const{AT\_EMPTY\_PATH}, \const{AT\_NO\_AUTOMOUNT} e
+\const{AT\_SYMLINK\_NOFOLLOW} per \param{flags}. Si può pertanto indicare il
+file di cui si vogliono ottenere i dati con un \textit{pathname} assoluto, con
+un \textit{pathname} relativo (sia alla directory corrente che a quella
+indicata da \param{dirfd}) o con un file descriptor ad esso associato.
+
+La funzione però consente di ottenere informazioni più dettagliate rispetto a
+quelle fornite dalle funzioni tradizionali come \func{stat} e \func{fstatat},
+ed è in grado di controllare le modalità con cui le ottiene nel caso un file
+sia posto su un filesystem remoto.  Per questo, oltre ai tre valori
+precedenti, l'argomento \param{flags} consente anche gli ulteriori valori
+elencati in tab.~\ref{tab:statx_flags_const}, con il significato ivi
+illustrato.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{AT\_STATX\_SYNC\_AS\_STAT}& si comporta esattamente come
+                                        \func{stat}, in questo caso (il default
+                                        se non viene indicato niente) il
+                                        risultato dipende dal tipo di
+                                        filesystem.\\
+    \constd{AT\_STATX\_FORCE\_SYNC}& richiede che i valori degli attributi
+                                     richiesti siano, in caso di un filesystem
+                                     di rete, siano sincronizzati con il server
+                                     remoto, questo può forzare una scrittura
+                                     dei dati (in particolare i tempi del file)
+                                     verso lo stesso.\\
+    \constd{AT\_STATX\_DONT\_SYNC} & chiede di non sincronizzare nessun dato,
+                                     ritornando quanto presente nella cache,
+                                     questo significa che i dati potrebbero
+                                     essere non coerenti ed aggiornati, ma si
+                                     evita, in caso di filesystem di rete, la
+                                     necessità di contattare il server remoto.\\ 
+    \hline
+  \end{tabular}  
+  \caption{Valori specifici di \func{statx} per l'argomento \param{flags}.}
+  \label{tab:statx_flags_const}
+\end{table}
+
+La funzione restituisce le informazioni relative al file richiesto nella
+struttura \struct{statx} puntata dall'argomento \param{statxbuf}.  Inoltre
+data la quantità di informazioni che possono essere richieste, la funzione
+consente, con l'argomento \param{mask} di selezionare quelle volute, questa
+deve essere assegnata ad una maschera binaria dei valori illustrati in
+tab.~\ref{tab:statx_mask_const}.
+
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{STATX\_TYPE}  & Tipo del file (\texttt{stx\_mode \& S\_IFMT}).\\
+    \constd{STATX\_MODE}  & Permessi del file (\texttt{stx\_mode \&
+                            \tild{}S\_IFMT}).\\ 
+    \constd{STATX\_NLINK} & Numero di collegamenti (\textit{hard link},
+                            \texttt{stx\_nlink}).\\ 
+    \constd{STATX\_UID}   & Proprietario del file (per \ids{UID},
+                            \texttt{stx\_uid}).\\
+    \constd{STATX\_GID}   & Gruppo proprietario del file (per \ids{GID},
+                            \texttt{stx\_gid}).\\
+    \constd{STATX\_ATIME} & Tempo di ultimo accesso (\texttt{stx\_atime}).\\
+    \constd{STATX\_MTIME} & Tempo di ultima modifica (\texttt{stx\_mtime}).\\
+    \constd{STATX\_CTIME} & Tempo di ultimo cambiamento (\texttt{stx\_mtime}).\\
+    \constd{STATX\_INO}   & Numero di \textit{inode} (\texttt{stx\_ino}).\\
+    \constd{STATX\_SIZE}  & Dimensione del file (\texttt{stx\_size}).\\
+    \constd{STATX\_BLOCKS}& Numero di blocchi del file (\texttt{stx\_blocks}).\\
+    \constd{STATX\_BASIC\_STATS}& Tutte le informazioni precedenti.\\
+    \constd{STATX\_BTIME} & Tempo di creazione (\texttt{stx\_btime}).\\
+%    \constd{}& .\\
+    \constd{STATX\_ALL}   & Tutte le informazioni.\\
+    \hline
+  \end{tabular}
+  \caption{Le costanti per i valori dell'argomento \param{mask} di
+    \func{statx}.}
+  \label{tab:statx_mask_const}
+\end{table}
+
+Si tenga presente che il kernel accetta non richiede che \param{mask} contenga
+solo i flag di tab.~\ref{tab:statx_mask_const}, valori ulteriori in genere
+vengono usualmente ignorati ma non si può comunque indicare un valore
+qualunque in quanto alcuni bit sono riservati per future
+estensioni.\footnote{in particolare il bit \constd{STATX\_\_RESERVED} che se
+  usato causa il fallimento della funzione con un errore di \errval{EINVAL}.}
+Inoltre non è detto che tutte le informazioni richieste con \param{mask} siano
+disponibili, per questo il kernel restituisce in un opportuno campo della
+struttura \struct{statx}, \val{stx\_mask}, quali sono i dati effettivamente
+restituiti, che possono in alcuni casi essere anche di più di quelli richiesti
+(se l'informazione aggiuntiva è ottenuta senza costi ulteriori) per cui è
+normale che questo valore possa essere diverso da quanto richiesto.
+
+In particolare se un filesystem ha dei campi che non sono supportati o con
+valori che non hanno corrispondenza in un sistema unix-like, questi potranno
+essere restituiti con valori fittizi se disponibili (ad esempio gli \ids{UID}
+e \ids{GID} impostati in fase di montaggio per filesystem che non supportano
+gli utenti) ma il relativo bit in \val{stx\_mask} sarà comunque
+cancellato. Infine è possibile che campi diversi possano avere informazioni
+ottenute in momenti diversi per cui in caso di cambiamenti al file eseguiti in
+concorrenza a \func{statx} si possono ottenere campi con valori precedenti o
+posteriori il cambiamento.
+
+
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{0.8\textwidth}
+    \includestruct{listati/statx.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \structd{statx} per la lettura delle informazioni dei 
+    file.}
+  \label{fig:file_statx_struct}
+\end{figure}
+
+
+Si è riportata in fig.~\ref{fig:file_statx_struct} la definizione della
+struttura \struct{statx} come presente in \headfile{sys/stat.h}.
+
 
 % TODO: manca prototipo e motivazione di fexecve, da trattare qui in quanto
 % inserita nello stesso standard e da usare con openat, vedi 
 % http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
 
 % TODO: manca prototipo e motivazione di fexecve, da trattare qui in quanto
 % inserita nello stesso standard e da usare con openat, vedi 
 % http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
+
 % TODO manca prototipo di execveat, introdotta nel 3.19, vedi
 % https://lwn.net/Articles/626150/ cerca anche fexecve
 % TODO manca prototipo di execveat, introdotta nel 3.19, vedi
 % https://lwn.net/Articles/626150/ cerca anche fexecve
+
 % TODO: manca prototipo e motivazione di execveat, vedi
 % http://man7.org/linux/man-pages/man2/execveat.2.html 
 
 
 % TODO: manca prototipo e motivazione di execveat, vedi
 % http://man7.org/linux/man-pages/man2/execveat.2.html 
 
 
+Infine trattiamo qui altre due funzioni che non attengono che in maniera
+indiretta all'uso dei file, ma sono comunque legate alla stessa interfaccia
+delle \textit{at-functions} per quanto riguarda l'accesso ad un file.
+
+
+
+
+
 % TODO: trattare i nuovi AT_flags quando e se arriveranno, vedi
 % https://lwn.net/Articles/767547/ 
 
 % TODO: trattare i nuovi AT_flags quando e se arriveranno, vedi
 % https://lwn.net/Articles/767547/ 
 
@@ -4807,9 +4998,9 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o
 % LocalWords:  FIONREAD epoll FIOQSIZE side effects SAFE BYCALLER QUERY EACCES
 % LocalWords:  EBUSY OpenBSD syncfs futimes timespec only init ESRCH kill NTPL
 % LocalWords:  ENXIO  NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK PGRP SZ
 % LocalWords:  FIONREAD epoll FIOQSIZE side effects SAFE BYCALLER QUERY EACCES
 % LocalWords:  EBUSY OpenBSD syncfs futimes timespec only init ESRCH kill NTPL
 % LocalWords:  ENXIO  NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK PGRP SZ
-% LocalWords:  EFAULT capabilities GETPIPE SETPIPE RESOURCE NFSv
-% LocalWords:  Documentation Urlich Drepper futimesat times
-% LocalWords:  futimens fs Tread TMPFILE EDQUOT extN Minix UDF XFS
+% LocalWords:  EFAULT capabilities GETPIPE SETPIPE RESOURCE NFSv InitFile stx
+% LocalWords:  Documentation Urlich Drepper futimesat times FullWrite major
+% LocalWords:  futimens fs Tread TMPFILE EDQUOT extN Minix UDF XFS mask
 % LocalWords:  shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF
 % LocalWords:  fstatfs SIGTTIN EDESTADDRREQ datagram connect seal pag
 % LocalWords:  dirty execveat execve scandirat statx AUTOMOUNT automount DAC
 % LocalWords:  shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF
 % LocalWords:  fstatfs SIGTTIN EDESTADDRREQ datagram connect seal pag
 % LocalWords:  dirty execveat execve scandirat statx AUTOMOUNT automount DAC
diff --git a/listati/InitFile.c b/listati/InitFile.c
new file mode 100644 (file)
index 0000000..e7d010a
--- /dev/null
@@ -0,0 +1,24 @@
+ssize_t InitFile(int dirfd, const char *file, const char *buf, size_t size) 
+{
+    int fd, written, res;
+    char path[PATH_MAX];
+   
+    fd = openat(dirfd, ".", O_TMPFILE|O_RDWR, S_IRUSR|S_IWUSR);
+    if (fd < 0) {
+       perror("Cannot get temporary filedescritor");
+       return(fd);
+    }
+    written = FullWrite(fd, buf, size);
+    if (written < 0) {
+       perror("error writing on tmp file");
+       return(res);
+    }
+    snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd);
+    res = linkat(AT_FDCWD, path, dirfd, file, AT_SYMLINK_FOLLOW);
+    if (res < 0) {
+       perror("error linking the file");
+       return(res);
+    } else {
+       return written;
+    }
+}
diff --git a/listati/statx.h b/listati/statx.h
new file mode 100644 (file)
index 0000000..4eecfd6
--- /dev/null
@@ -0,0 +1,27 @@
+struct statx {
+    __u32 stx_mask;        /* Mask of bits indicating filled fields */
+    __u32 stx_blksize;     /* Block size for filesystem I/O */
+    __u64 stx_attributes;  /* Extra file attribute indicators */
+    __u32 stx_nlink;       /* Number of hard links */
+    __u32 stx_uid;         /* User ID of owner */
+    __u32 stx_gid;         /* Group ID of owner */
+    __u16 stx_mode;        /* File type and mode */
+    __u64 stx_ino;         /* Inode number */
+    __u64 stx_size;        /* Total size in bytes */
+    __u64 stx_blocks;      /* Number of 512B blocks allocated */
+    __u64 stx_attributes_mask; 
+                           /* Mask to show what's supported in stx_attributes */
+    /* The following fields are file timestamps */
+    struct statx_timestamp stx_atime;  /* Last access */
+    struct statx_timestamp stx_btime;  /* Creation */
+    struct statx_timestamp stx_ctime;  /* Last status change */
+    struct statx_timestamp stx_mtime;  /* Last modification */
+    /* If this file represents a device, then the next two
+       fields contain the ID of the device */
+    __u32 stx_rdev_major;  /* Major ID */
+    __u32 stx_rdev_minor;  /* Minor ID */
+    /* The next two fields contain the ID of the device
+       containing the filesystem where the file resides */
+    __u32 stx_dev_major;   /* Major ID */
+    __u32 stx_dev_minor;   /* Minor ID */
+};
index c5a702f95f1b005b7890d714d5d11d0f9508d75d..429fc6f3552f5097f998f1d72fd4299d11a03a4a 100644 (file)
@@ -113,7 +113,7 @@ size_t full_fwrite(FILE *file, void *buf, size_t count);
 /* Function dir_scan: simple scan for a directory. See dir_scan.c */
 int dir_scan(char * dirname, int(*compute)(struct dirent *));
 /* Function InitFile: secure create of a file with initial content */
 /* Function dir_scan: simple scan for a directory. See dir_scan.c */
 int dir_scan(char * dirname, int(*compute)(struct dirent *));
 /* Function InitFile: secure create of a file with initial content */
-ssize_t InitFile(int dirfd, const char *file, const char *buf, size_t count);
+ssize_t InitFile(int dirfd, const char *file, const char *buf, size_t size);
 /* Function full_fread: to read from a standard file. See full_fread.c */
 /*
  * Shared memory handling functions. See SharedMem.c
 /* Function full_fread: to read from a standard file. See full_fread.c */
 /*
  * Shared memory handling functions. See SharedMem.c
index 307442a7cc2bcab2c9f7e78498a40217ffc7fd0c..a1e3e46feb07d48edfb369e24b70f0e64a638e53 100644 (file)
@@ -37,9 +37,9 @@
 #include "Gapil.h"
 #include "macros.h"
 
 #include "Gapil.h"
 #include "macros.h"
 
-ssize_t InitFile(int dirfd, const char *file, const char *buf, size_t count
+ssize_t InitFile(int dirfd, const char *file, const char *buf, size_t size
 {
 {
-    int fd, res;
+    int fd, written, res;
     char path[PATH_MAX];
    
     fd = openat(dirfd, ".", O_TMPFILE|O_RDWR, S_IRUSR|S_IWUSR);
     char path[PATH_MAX];
    
     fd = openat(dirfd, ".", O_TMPFILE|O_RDWR, S_IRUSR|S_IWUSR);
@@ -47,18 +47,18 @@ ssize_t InitFile(int dirfd, const char *file, const char *buf, size_t count)
        perror("Cannot get temporary filedescritor");
        return(fd);
     }
        perror("Cannot get temporary filedescritor");
        return(fd);
     }
-    res = FullWrite(fd, buf, count);
-    if (res < 0) {
+    written = FullWrite(fd, buf, size);
+    if (written < 0) {
        perror("error writing on tmp file");
        return(res);
     }
     snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd);
     res = linkat(AT_FDCWD, path, dirfd, file, AT_SYMLINK_FOLLOW);
     if (res < 0) {
        perror("error writing on tmp file");
        return(res);
     }
     snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd);
     res = linkat(AT_FDCWD, path, dirfd, file, AT_SYMLINK_FOLLOW);
     if (res < 0) {
-       perror("error writing on tmp file");
+       perror("error linking the file");
        return(res);
     } else {
        return(res);
     } else {
-       return 0;
+       return written;
     }
 }
 
     }
 }
 
index 12dc0280ec65548a6c7f24f28f6946756ca17f85..afd607391aba85f78b3febff105b6c52584aba95 100644 (file)
@@ -99,6 +99,10 @@ int main(int argc, char *argv[])
     int newfd, res, count;
     count = strlen(argv[optind+1]);
     newfd = open(dir, O_PATH|O_RDWR);
     int newfd, res, count;
     count = strlen(argv[optind+1]);
     newfd = open(dir, O_PATH|O_RDWR);
+    if (newfd < 0) {
+       perror("Cannot open destination dir");
+       exit(1);
+    }
     res = InitFile(newfd, file, argv[optind+1], count);
     free(path);
     return 0;
     res = InitFile(newfd, file, argv[optind+1], count);
     free(path);
     return 0;
@@ -107,8 +111,7 @@ int main(int argc, char *argv[])
  * routine to print usage info and exit
  */
 void usage(void) {
  * routine to print usage info and exit
  */
 void usage(void) {
-    printf("Program test_initfile : test initfile  \n");
-    printf("Create a link to a tempfile or a link to -f indicated file");
+    printf("Program test_initfile : create a file with initial content  \n");
     printf("Usage:\n");
     printf("  test_initfile [-h] pathname 'test to be written on pathname' \n");
     printf("  -h          print this help\n");
     printf("Usage:\n");
     printf("  test_initfile [-h] pathname 'test to be written on pathname' \n");
     printf("  -h          print this help\n");