C unter amd64 Linux, 36 Bytes (nur Zeitstempel), 52 49 Bytes (echte Festplattenaktivität)
Ich codiere die open(2)
Flags hart , so dass dies nicht auf andere ABIs übertragbar ist. Linux auf anderen Plattformen verwendet wahrscheinlich dasselbe O_TRUNC
usw., andere POSIX-Betriebssysteme jedoch möglicherweise nicht.
+4 Bytes , um ein korrektes Berechtigungsargument zu übergeben, um sicherzustellen, dass die Datei mit dem Schreibzugriff des Besitzers erstellt wurde (siehe unten). (Dies funktioniert mit gcc 5.2)
etwas portables ANSI C, 38/51 Bytes (nur Zeitstempel), 52/67 Bytes (echte Festplattenaktivität)
Basierend auf der Antwort von @ Cat, mit einem Tipp von @Jens.
Die erste Zahl ist für Implementierungen int
gedacht FILE *fopen()
, bei denen der Rückgabewert eines can hold ist, die zweite Zahl, wenn wir das nicht können. Unter Linux befinden sich Heap-Adressen in den unteren 32 Bit des Adressraums, daher funktioniert dies auch ohne -m32
oder -mx32
. (Deklaration void*fopen();
ist kürzer als #include <stdio.h>
)
Nur Zeitstempel-Metadaten-E / A :
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"));}
Schreiben eines Bytes unter Linux 4.2.0 + XFS + lazytime
:
main(){for(;write(open("a",577),"",1);close(3));}
write
ist die for-Schleifenbedingung, die in Ordnung ist, da sie immer 1 zurückgibt. Ist close
das Inkrement.
// 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
Erklärung der nicht portierbaren Version:
Die Datei wird mit zufälligen Speicherbereinigungen erstellt. In gcc
Version 5.2, mit -O0
oder -O3
, ist möglicherweise eine Schreibberechtigung für den Eigentümer enthalten, dies kann jedoch nicht garantiert werden. 0666
ist dezimal 438. Ein drittes Argument für open
würde weitere 4 Bytes benötigen . Wir haben bereits O_TRUNC und so weiter hartcodiert, aber dies kann mit einem anderen Compiler oder einer anderen libc auf demselben ABI zu Problemen führen.
Wir können nicht die 2. arg verzichten open
, da der Garbage Wert enthalten geschieht O_EXCL
, und O_TRUNC|O_APPEND
, so offen nicht mit EINVAL
.
Der Rückgabewert von muss nicht gespeichert werden open()
. Wir gehen davon aus 3
, dass es so ist , weil es immer so sein wird. Auch wenn wir mit fd 3 open beginnen, wird es nach der ersten Iteration geschlossen. Im schlimmsten Fall werden so lange open
neue FDS geöffnet, bis 3 der letzte verfügbare Dateideskriptor ist. Bis zu den ersten 65531- write()
Aufrufen konnte dies fehlschlagen EBADF
, funktioniert dann aber normal mit jeder open
Erstellung von fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNC
unter x86-64 Linux. Ohne O_TRUNC
werden die Inode-Mod-Zeit und die Änderungszeit nicht aktualisiert, so dass ein kürzeres Argument nicht möglich ist. O_TRUNC
ist immer noch wichtig für die Version, die write
zum Erzeugen der tatsächlichen Festplattenaktivität aufruft , und nicht zum erneuten Schreiben.
Ich sehe einige Antworten darauf open("a",1)
. O_CREAT ist erforderlich, falls a
noch nicht vorhanden. O_CREAT
ist unter Linux als oktal 0100 (64, 0x40) definiert.
Keine Ressourcenlecks, daher kann es für immer ausgeführt werden. strace
Ausgabe:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
oder
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
Ich habe den Dezimalwert der open
Flags für dieses ABI strace -eraw=open
in meiner C ++ - Version erhalten.
Auf einem Dateisystem mit lazytime
aktivierter Linux- Mount-Option führt eine Änderung, die sich nur auf Inode-Zeitstempel auswirkt, nur zu einem Schreibvorgang pro 24 Stunden. Wenn diese Einhängeoption deaktiviert ist, kann die Zeitstempelaktualisierung möglicherweise die SSD strapazieren. (Einige andere Antworten führen jedoch nur Metadaten-E / A aus.)
Alternativen:
kürzer arbeitslos :
main(){for(;;)close(write(open("a",577),"",3));}
Verwendet write
den Rückgabewert von 's, um ein 3
Argument zum Schließen zu übergeben. Es speichert ein weiteres Byte, funktioniert aber nicht mit gcc -O0 oder -O3 auf amd64. Der Müll im 3. Argument open
ist anders und enthält keine Schreibrechte. a
wird das erste Mal erstellt, aber zukünftige Iterationen scheitern alle mit -EACCESS
.
länger arbeiten, mit verschiedenen Systemaufrufen :
main(c){for(open("a",65);pwrite(3,"",1);)sync();}
Schreibt ein Byte an Ort und Stelle neu und ruft sync()
auf, um alle Dateisysteme systemweit zu synchronisieren. Dadurch bleibt die Laufwerksanzeige eingeschaltet.
Es ist uns egal welches Byte, also übergeben wir das 4. Argument nicht an pwrite. Ja für spärliche Dateien:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Das Schreiben eines Bytes mit einem Offset von ~ 128 TB führte dazu, dass xfs 300 KB Speicherplatz für die Extent-Map benötigte. Versuchen Sie dies nicht unter OS X mit HFS +: IIRC, HFS + unterstützt keine Sparse-Dateien, daher wird die Festplatte gefüllt.
XFS ist ein richtiges 64-Bit-Dateisystem, das einzelne Dateien mit bis zu 8 Exabyte unterstützt . Dh 2 ^ 63-1, der Maximalwert off_t
kann halten.
strace
Ausgabe:
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
? (Istyes>/dev/null
eine gültige Bash-Antwort?)