C su Linux amd64, 36 byte (solo timestamp), 52 49 byte (attività del disco reale)
open(2)Codifico le bandiere, quindi non è portabile ad altre ABI. Linux su altre piattaforme probabilmente usa lo stesso O_TRUNC, ecc., Ma altri sistemi operativi POSIX potrebbero non farlo.
+4 byte per passare una corretta autorizzazione arg per assicurarsi che il file sia creato con accesso in scrittura proprietario, vedi sotto. (Questo succede con gcc 5.2)
ANSI C un po 'portatile, 38/51 byte (solo timestamp), 52/67 byte (attività del disco reale)
Basato sulla risposta di @ Cat, con un suggerimento di @Jens.
Il primo numero è per le implementazioni in cui è intpossibile contenere FILE *fopen()il valore restituito, il secondo numero se non è possibile farlo. Su Linux, gli indirizzi heap si trovano nei 32 bit di spazio degli indirizzi bassi, quindi funziona anche senza -m32o -mx32. (La dichiarazione void*fopen();è più breve di #include <stdio.h>)
Solo I / O metadati data / ora :
main(){for(;;)close(open("a",577));} // Linux x86-64
//void*fopen(); // compile with -m32 or -mx32 or whatever, so an int holds a pointer.
main(){for(;;)fclose(fopen("a","w"));}
Scrivere un byte, colpire effettivamente il disco su Linux 4.2.0 + XFS + lazytime:
main(){for(;write(open("a",577),"",1);close(3));}
writeè la condizione for-loop, che va bene poiché restituisce sempre 1. closeè l'incremento.
// semi-portable: storing a FILE* in an int. Works on many systems
main(f){for(;f=fopen("a","w");fclose(f))fputc(0,f);} // 52 bytes
// Should be highly portable, except to systems that require prototypes for all functions.
void*f,*fopen();main(){for(;f=fopen("a","w");fclose(f))fputc(0,f);} // 67 bytes
Spiegazione della versione non portatile:
Il file viene creato con autorizzazioni di Garbage Casuali. Con gcc5.2, con -O0o -O3, sembra includere l'autorizzazione di scrittura del proprietario, ma questo non è garantito. 0666è 438 decimale. Un terzo argomento per openrichiedere altri 4 byte . Stiamo già codificando O_TRUNC e così via, ma questo potrebbe interrompersi con un compilatore o libc diverso sulla stessa ABI.
Non possiamo omettere il secondo argomento open, perché il valore di garbage include O_EXCLe O_TRUNC|O_APPENDquindi open non riesce EINVAL.
Non è necessario salvare il valore restituito da open(). Supponiamo che lo sia 3, perché lo sarà sempre. Anche se iniziamo con fd 3 aperto, verrà chiuso dopo la prima iterazione. Nel peggiore dei casi, opencontinua ad aprire nuovi fds fino a quando 3 non è l'ultimo descrittore di file disponibile. Quindi, fino alle prime 65531 write()chiamate potrebbero non riuscire EBADF, ma funzionerà normalmente con ogni opencreazione fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNCsu Linux x86-64. Senza O_TRUNC, il tempo di mod dell'inode e il tempo di cambio non vengono aggiornati, quindi un arg più breve non è possibile. O_TRUNCè ancora essenziale per la versione che chiama writeper produrre l'attività del disco effettiva, non riscriverla in atto.
Vedo alcune risposte che open("a",1). O_CREAT è richiesto se anon esiste già. O_CREATè definito come ottale 0100 (64, 0x40) su Linux.
Nessuna perdita di risorse, quindi può funzionare per sempre. straceproduzione:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
o
open("a", O_WRONLY|O_CREAT|O_TRUNC, 01) = 3
write(3, "\0", 1) = 1 # This is the terminating 0 byte in the empty string we pass to write(2)
close(3) = 0
Ho ottenuto il valore decimale dei openflag per questo ABI utilizzando strace -eraw=opensulla mia versione C ++.
Su un filesystem con l' lazytimeopzione di mount Linux abilitata, una modifica che riguarda solo i timestamp dell'inode causerà una sola scrittura ogni 24 ore. Con quell'opzione mount disabilitata, l'aggiornamento del timestamp potrebbe essere un modo fattibile per consumare il tuo SSD. (Tuttavia, molte altre risposte eseguono solo I / O sui metadati).
alternative:
breve non funzionante :
main(){for(;;)close(write(open("a",577),"",3));}usa writeil valore restituito per passare un 3arg alla chiusura. Salva un altro byte, ma non funziona con gcc -O0 o -O3 su amd64. La spazzatura nel 3 ° argomento openè diversa e non include l'autorizzazione in scrittura. aviene creato la prima volta, ma tutte le iterazioni future falliscono -EACCESS.
più a lungo, funzionante, con diverse chiamate di sistema :
main(c){for(open("a",65);pwrite(3,"",1);)sync();} riscrive un byte sul posto e chiama sync()per sincronizzare tutti i filesystem a livello di sistema. Ciò mantiene accesa la luce dell'unità.
Non ci interessa quale byte, quindi non passiamo il 4o argomento a pwrite. Sì per i file sparsi:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Scrivere un byte con un offset di ~ 128TiB ha portato a xfs usando 300 kB di spazio per contenere la mappa dell'estensione, immagino. Non provarlo su OS X con HFS +: IIRC, HFS + non supporta file sparsi, quindi riempirà il disco.
XFS è un vero filesystem a 64 bit, che supporta singoli file fino a 8 exabyte . cioè 2 ^ 63-1, il valore massimo off_tpuò contenere.
strace produzione:
open("a", O_WRONLY|O_CREAT, 03777711166007270) = 3
pwrite(3, "\0", 1, 139989929353760) = 1
sync() = 0
pwrite(3, "\0", 1, 139989929380071) = 1
sync() = 0
...
/dev/null? (Èyes>/dev/nullvalida una risposta di Bash?)