C trên amd64 Linux, 36 byte (chỉ dấu thời gian), 52 49 byte (hoạt động của đĩa thực)
Tôi mã hóa các open(2)
cờ, vì vậy đây không phải là di động cho các ABI khác. Linux trên các nền tảng khác có thể sử dụng tương tự O_TRUNC
, v.v., nhưng các HĐH POSIX khác thì không.
+4 byte để vượt qua một quyền chính xác arg để đảm bảo tệp được tạo với quyền truy cập ghi chủ sở hữu, xem bên dưới. (Điều này xảy ra để làm việc với gcc 5.2)
ANSI C hơi di động, 38/51 byte (chỉ dấu thời gian), 52/67 byte (hoạt động đĩa thực)
Dựa trên câu trả lời của @ Cat, với một mẹo từ @Jens.
Số đầu tiên dành cho việc triển khai trong đó giá trị trả về int
có thể giữ FILE *fopen()
, số thứ hai nếu chúng ta không thể làm điều đó. Trên Linux, các địa chỉ heap xảy ra trong không gian địa chỉ 32 bit thấp, do đó, nó hoạt động ngay cả khi không có -m32
hoặc -mx32
. (Khai báo void*fopen();
ngắn hơn #include <stdio.h>
)
Chỉ có siêu dữ liệu dấu thời gian 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"));}
Viết một byte, thực sự nhấn đĩa trên Linux 4.2.0 + XFS + lazytime
:
main(){for(;write(open("a",577),"",1);close(3));}
write
là điều kiện for-loop, điều này tốt vì nó luôn trả về 1. close
là mức tăng.
// 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
Giải thích về phiên bản không di động:
Các tập tin được tạo ra với quyền rác ngẫu nhiên. Với gcc
5.2, với -O0
hoặc -O3
, nó bao gồm sự cho phép viết của chủ sở hữu, nhưng điều này không được đảm bảo. 0666
là số thập phân 438. Một đối số thứ 3 open
sẽ mất thêm 4 byte . Chúng tôi đã mã hóa O_TRUNC, v.v., nhưng điều này có thể phá vỡ với một trình biên dịch hoặc libc khác nhau trên cùng một ABI.
Chúng ta không thể bỏ qua đối số thứ 2 open
, bởi vì giá trị rác xảy ra bao gồm O_EXCL
, và O_TRUNC|O_APPEND
do đó, mở không thành công EINVAL
.
Chúng tôi không cần phải lưu giá trị trả về từ open()
. Chúng tôi cho rằng nó 3
, bởi vì nó sẽ luôn luôn như vậy. Ngay cả khi chúng ta bắt đầu với fd 3 mở, nó sẽ bị đóng sau lần lặp đầu tiên. Trường hợp xấu nhất, open
tiếp tục mở fds mới cho đến khi 3 là mô tả tệp có sẵn cuối cùng. Vì vậy, tối đa 65531 write()
cuộc gọi đầu tiên có thể thất bại EBADF
, nhưng sau đó sẽ hoạt động bình thường với mỗi lần open
tạo fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNC
trên x86-64 Linux. Nếu không O_TRUNC
, thời gian mod inode và thời gian thay đổi sẽ không được cập nhật, do đó không thể lập luận ngắn hơn. O_TRUNC
vẫn là điều cần thiết cho phiên bản gọi write
để tạo ra hoạt động đĩa thực tế, không phải viết lại tại chỗ.
Tôi thấy một số câu trả lời rằng open("a",1)
. O_CREAT là bắt buộc nếu a
không tồn tại. O_CREAT
được định nghĩa là bát phân 0100 (64, 0x40) trên Linux.
Không có rò rỉ tài nguyên, vì vậy nó có thể chạy mãi mãi. strace
đầu ra:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
hoặc là
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
Tôi đã nhận được giá trị thập phân của các open
cờ cho ABI này bằng strace -eraw=open
phiên bản C ++ của mình.
Trên hệ thống tệp có lazytime
bật tùy chọn gắn kết Linux , một thay đổi chỉ ảnh hưởng đến dấu thời gian inode sẽ chỉ gây ra một lần ghi trong 24 giờ. Với tùy chọn gắn kết bị tắt, cập nhật dấu thời gian có thể là một cách hữu hiệu để làm hao mòn ổ SSD của bạn. (Tuy nhiên, một số câu trả lời khác chỉ làm I / O siêu dữ liệu).
lựa chọn thay thế:
không làm việc ngắn hơn :
main(){for(;;)close(write(open("a",577),"",3));}
sử dụng write
giá trị trả về để vượt qua một 3
đối số để đóng. Nó lưu một byte khác, nhưng không hoạt động với gcc -O0 hoặc -O3 trên amd64. Rác trong đối số thứ 3 open
là khác nhau và không bao gồm quyền ghi. a
được tạo lần đầu tiên, nhưng tất cả các lần lặp lại trong tương lai đều thất bại -EACCESS
.
lâu hơn, làm việc, với các cuộc gọi hệ thống khác nhau :
main(c){for(open("a",65);pwrite(3,"",1);)sync();}
viết lại một byte tại chỗ và gọi sync()
để đồng bộ hóa tất cả các hệ thống tập tin trên toàn hệ thống. Điều này giữ cho đèn ổ đĩa sáng lên.
Chúng tôi không quan tâm byte nào, vì vậy chúng tôi không chuyển arg thứ 4 sang pwrite. Yay cho các tập tin thưa thớt:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Viết một byte ở độ lệch ~ 128TiB đã dẫn đến xfs sử dụng 300kiB không gian để giữ bản đồ tỷ lệ, tôi đoán vậy. Đừng thử điều này trên OS X với HFS +: IIRC, HFS + không hỗ trợ các tệp thưa thớt, vì vậy nó sẽ lấp đầy đĩa.
XFS là một hệ thống tệp 64 bit thích hợp, hỗ trợ các tệp riêng lẻ lên tới 8 exabyte . tức là 2 ^ 63-1, giá trị tối đa off_t
có thể giữ.
strace
đầu ra:
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
cái gì? (yes>/dev/null
Câu trả lời của Bash có hợp lệ không?)