C on amd64 Linux、36バイト(タイムスタンプのみ)、52 49バイト(実ディスクアクティビティ)
私はopen(2)
フラグをハードコーディングしているので、これは他のABIに移植できません。他のプラットフォーム上のLinuxはおそらく同じを使用しますO_TRUNC
が、他のPOSIX OSは使用しない場合があります。
正しい許可引数を渡して、ファイルが所有者の書き込みアクセスで作成されていることを確認するには、+ 4バイト。以下を参照してください。(これはたまたまgcc 5.2で動作します)
やや移植可能なANSI C、38/51バイト(タイムスタンプのみ)、52/67バイト(実ディスクアクティビティ)
@Censの回答に基づく、@ Jensからのヒント。
最初の数値はが戻り値をint
保持できる実装用で、FILE *fopen()
それができない場合は2番目の数値です。Linuxでは、ヒープアドレスはアドレス空間の下位32ビットにあるため、またはがなくて-m32
も機能し-mx32
ます。(宣言void*fopen();
はより短い#include <stdio.h>
)
タイムスタンプメタデータI / Oのみ:
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"));}
バイトを書き込んで、実際にLinux 4.2.0 + XFS +でディスクにヒットしますlazytime
:
main(){for(;write(open("a",577),"",1);close(3));}
write
forループ条件です。常に1を返すので問題ありません close
。増分です。
// 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
非ポータブルバージョンの説明:
ファイルはランダムなガベージアクセス許可で作成されます。ではgcc
5.2、-O0
または-O3
、所有者の書き込み権限が含まれるように起こるが、これは保証されません。 0666
10進数の438です 。3番目の引数open
はさらに4バイトかかります。O_TRUNCなどをすでにハードコーディングしていますが、これは同じABIの異なるコンパイラまたはlibcで壊れる可能性があります。
私たちは、への第2引数を省略することはできませんopen
ガベージ値が含まれてしまっているため、O_EXCL
とO_TRUNC|O_APPEND
とてもオープンで失敗し、EINVAL
。
からの戻り値を保存する必要はありませんopen()
。3
常にそうなるので、それがであると仮定します。fd 3を開いて開始した場合でも、最初の反復後に閉じます。最悪の場合、open
最後の利用可能なファイル記述子が3になるまで新しいfdsを開き続けます。したがって、最初の65531 write()
呼び出しまではで失敗しますがEBADF
、open
fd = 3を作成するたびに正常に動作します。
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNC
x86-64 Linuxの場合。なしO_TRUNC
では、inodeのmod時間と変更時間は更新されないため、短い引数は使用できません。 書き換えではなく、実際のディスクアクティビティを生成するO_TRUNC
ように呼び出すバージョンには、依然として不可欠ですwrite
。
その答えがいくつかありますopen("a",1)
。O_CREATは、a
まだ存在しない場合に必要です。 O_CREAT
Linuxでは8進数0100(64、0x40)として定義されます。
リソースリークがないため、永久に実行できます。 strace
出力:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
または
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
C ++バージョンでopen
使用strace -eraw=open
しているこのABI のフラグの10進数値を取得しました。
Linux lazytime
マウントオプションが有効になっているファイルシステムでは、iノードのタイムスタンプのみに影響する変更は、24時間ごとに1回だけ書き込みを行います。そのマウントオプションが無効になっていると、タイムスタンプの更新がSSDを使い果たす実行可能な方法になる可能性があります。(ただし、他のいくつかの回答はメタデータI / Oのみを行います)。
代替案:
短い非動作:
main(){for(;;)close(write(open("a",577),"",3));}
write
の戻り値を使用して3
、閉じる引数を渡します。別のバイトを保存しますが、amd64のgcc -O0または-O3では機能しません。3番目の引数のゴミopen
は異なり、書き込み権限は含まれていません。 a
最初に作成されますが、将来の反復はすべて失敗し-EACCESS
ます。
より長く、動作し、異なるシステムコールで:
main(c){for(open("a",65);pwrite(3,"",1);)sync();}
バイトをインプレースで書き換え、sync()
すべてのファイルシステムをシステム全体で同期するために呼び出します。これにより、ドライブのライトが点灯し続けます。
どのバイトでもかまいませんので、4番目の引数をpwriteに渡しません。スパースファイルの場合:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
〜128TiBのオフセットで1バイトを書き込むと、エクステントマップを保持するために300kiBのスペースを使用するxfsになりました。HFS +を搭載したOS Xではこれを試さないでください。IIRC、HFS +はスパースファイルをサポートしないため、ディスクがいっぱいになります。
XFSは適切な64ビットファイルシステムであり、最大8エクサバイトの個々のファイルをサポートします。すなわち、2 ^ 63-1、最大値off_t
を保持できます。
strace
出力:
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/null
有効なBashの答えは?)