Skip to content

POSIX e File Descriptor

Le funzioni viste finora (fopen, fread, ecc.) fanno parte della Libreria Standard C. Sono altamente portabili e astratte, per garantire che il codice funzioni sia su una lavatrice che su un server.

Tuttavia, nel mondo reale, i programmi interagiscono fortemente con i file system moderni. Per questo motivo, nei sistemi operativi Unix/Linux (o macOS) si utilizzano le API a basso livello definite dallo standard POSIX.

Al posto della struttura astratta FILE *, lo standard POSIX lavora in modo diretto con il kernel del sistema operativo mediante un intero noto come File Descriptor (Descrittore di File). In POSIX non si usa fopen, ma la system call open:

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h> // essenziale per read, write, close
// I flag si combinano con l'operatore OR bit-a-bit (|)
// Qui: Apre in sola scrittura, crea il file se non esiste, cancella tutto se esiste
int fd = open("documento.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd == -1) {
// Gestione errore (open restituisce -1 e imposta la variabile 'errno')
}

Allo stesso modo, al posto di fclose, in POSIX si chiude un descrittore invocando direttamente il kernel tramite close(fd).

Per eliminare un file, lo standard C possiede remove(), ma in POSIX si usa unlink(path). Perché?

Sia il C standard che POSIX offrono invece la funzione rename("vecchionome.txt", "nuovonome.txt") per spostare e rinominare file.

Capita spesso di dover salvare dei dati su disco per pochi secondi (es. per non saturare la RAM) durante calcoli complessi, passandoli tra due processi. Evita i file temporanei classici (tmpfile() dello standard C può avere problemi di performance o privacy su alcune piattaforme): usa directory isolate e API POSIX apposite come mkstemp per generare un nome file casuale e aprirlo istantaneamente in modalità esclusiva, per prevenire vulnerabilità di sicurezza enormi derivate dalle cosiddette race conditions.

Nei programmi POSIX (come su Linux), stdin, stdout e stderr sono sempre mappati rispettivamente ai file descriptor 0, 1 e 2. Scrivi un messaggio d’errore sullo Standard Error (FD 2) usando la system call write(). La funzione write di POSIX prende: write(file_descriptor, buffer_memoria, quanti_byte);