Amd64 Linux'ta C, 36 bayt (yalnızca zaman damgası), 52 49 bayt (gerçek disk etkinliği)
open(2)Bayrakları zor kodluyorum, bu yüzden diğer ABI'lara taşınabilir değil. Diğer platformlarda Linux muhtemelen aynı O_TRUNC, vb kullanır , ancak diğer POSIX işletim sistemleri olmayabilir.
+4 bayt , dosyanın sahibinin yazma erişimiyle oluşturulduğundan emin olmak için doğru bir izin argümanı iletmek için aşağıya bakın. (Bu, gcc 5.2 ile çalışır)
biraz taşınabilir ANSI C, 38/51 bayt (yalnızca zaman damgası), 52/67 bayt (gerçek disk etkinliği)
@Jens'in cevabına göre @Jens'tan bir ipucu ile.
İlk sayı, bir intkişinin FILE *fopen()dönüş değerini tutabileceği uygulamalar için , bunu yapamazsak ikinci sayıdır. Linux'ta, yığın adresleri düşük 32 bit adres alanı içinde olur, bu yüzden -m32ya da olmadan çalışır -mx32. (Beyanı void*fopen();daha kısa #include <stdio.h>)
Yalnızca zaman damgası meta verileri G / Ç :
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"));}
Bir bayt yazmak, aslında Linux 4.2.0 + XFS + diskine basmaklazytime :
main(){for(;write(open("a",577),"",1);close(3));}
writefor-loop koşulu, her zaman 1 döndürdüğü için gayet iyi close. Artım.
// 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
Taşınabilir olmayan versiyonun açıklaması:
Dosya rasgele çöp izinleriyle oluşturulur. İle gccbirlikte 5.2, -O0veya -O3, sahibi yazma izni dahil olur, ancak bu garanti edilmemektedir. 0666ondalık: 438. Başka bir 4 byte alabilen üçüncü bir argümanopen . Zaten O_TRUNC kodlaması yapıyoruz, ancak bu aynı ABI'da farklı bir derleyici veya libc ile bozulabilir.
2. argümanı atlayamayız open, çünkü çöp değeri buna dahil olur O_EXCLve O_TRUNC|O_APPENDaçık bu nedenle başarısız olur EINVAL.
Dönüş değerini kaydetmemize gerek yok open(). Bunu varsayıyoruz 3, çünkü her zaman olacak. Fd 3 open ile başlasak bile, ilk yinelemeden sonra kapanacaktır. En kötüsü open, en son kullanılabilir dosya tanıtıcısı 3 olana kadar yeni fds açmaya devam ediyor. Böylece, ilk 65531'e kadar write()çağrı başarısız olabilir EBADF, ancak daha sonra her openyaratmada normal olarak çalışacaktır fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNCx86-64 Linux'ta. Olmadan O_TRUNC, inode mod zamanı ve değişim zamanı güncellenmez, bu nedenle kısa bir argüman mümkün değildir. O_TRUNChala writeyerine oturtulmadan değil, gerçek disk etkinliği oluşturmaya çalışan sürüm için hala gereklidir .
Buna bazı cevaplar görüyorum open("a",1). Henüz mevcut değilse a, O_CREAT gereklidir . O_CREATLinux'ta sekizlik 0100 (64, 0x40) olarak tanımlanmıştır.
Kaynak sızıntısı yok, bu yüzden sonsuza kadar çalışabilir. straceçıktı:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
veya
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
Ben C ++ sürümünde openkullanarak bu ABI için bayrakların ondalık değerini aldım strace -eraw=open.
Linux lazytimemount seçeneğinin etkin olduğu bir dosya sisteminde , yalnızca inode zaman damgalarını etkileyen bir değişiklik 24 saatte yalnızca bir yazmaya neden olur. Bu takma seçeneği devre dışı bırakıldığında, zaman damgası güncellemesi SSD'nizi yıpratmanın uygun bir yolu olabilir. (Ancak, diğer bazı yanıtlar yalnızca meta veri G / Ç yapar).
alternatifler:
kısa olmayan çalışma :
main(){for(;;)close(write(open("a",577),"",3));}Kapatılacak writebir 3argümanı iletmek için 'return' değerini kullanır . Başka bir bayttan tasarruf eder, ancak amd64'te gcc -O0 veya -O3 ile çalışmaz. 3. argümandaki çöpler openfarklıdır ve yazma izni içermez. ailk kez yaratıldı, ancak gelecekteki yinelemelerin hepsi başarısızlıkla sonuçlandı -EACCESS.
daha uzun, çalışıyor, farklı sistem çağrılarıyla :
main(c){for(open("a",65);pwrite(3,"",1);)sync();} yerinde bir bayt yazar ve sync()tüm dosya sistemlerini sistem genelinde senkronize etmek için çağırır . Bu, sürüş ışığının yanmasını sağlar.
Hangi baytı umursamıyoruz, o yüzden 4. arg'ı yazmak için geçmiyoruz. Seyrek dosyalar için Yay:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Sanırım ~ 128 TB'lık bir ofsette bir bayt yazmak, genişlik haritasını tutmak için 300 kB'lik bir alan kullanan xfs'ye yol açtı. OS X'te HFS + ile deneme: IIRC, HFS + seyrek dosyaları desteklemediğinden diski doldurur.
XFS, 8 exabayta kadar tek tek dosyaları destekleyen uygun bir 64bit dosya sistemidir . yani 2 ^ 63-1, maksimum değer off_ttutabilir.
strace çıktı:
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/nullGeçerli bir Bash cevap mı?)