amd64 Linux의 C, 36 바이트 (타임 스탬프 만), 52 49 바이트 (실제 디스크 활동)
open(2)플래그를 하드 코딩 하므로 다른 ABI에서 이식 할 수 없습니다. 다른 플랫폼의 Linux는 동일한 O_TRUNC등을 사용하지만 다른 POSIX OS는 그렇지 않을 수 있습니다.
파일이 소유자 쓰기 액세스로 작성되도록 올바른 권한 인수를 전달하려면 +4 바이트 ( 아래 참조) (이것은 gcc 5.2에서 작동합니다)
다소 이식 가능한 ANSI C, 38/51 바이트 (타임 스탬프 만), 52/67 바이트 (실제 디스크 활동)
@Jens의 팁과 함께 @Cat의 답변을 기반으로합니다.
첫 번째 숫자는 의 반환 값을 int보유 할 수있는 구현을위한 FILE *fopen()것이고, 우리가 그것을 할 수 없다면 두 번째 숫자입니다. 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));}
writefor-loop 조건이며 항상 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
이식 불가능한 버전에 대한 설명 :
파일은 임의의 가비지 권한으로 생성됩니다. 로 gcc5.2, -O0또는 -O3, 소유자의 쓰기 권한을 포함하는 일이 있지만이 보장되지 않습니다. 066610 진수는 438입니다 . 세 번째 인수 open는 다른 4 바이트를 갖습니다 . 우리는 이미 O_TRUNC 등을 하드 코딩하고 있지만 동일한 ABI에서 다른 컴파일러 또는 libc와 충돌 할 수 있습니다.
우리의 두번째 인수를 생략 할 수없는 open쓰레기 값을 포함 할 일이 있기 때문에 O_EXCL, 그리고 O_TRUNC|O_APPEND너무 개방 실패, EINVAL.
의 반환 값을 저장할 필요는 없습니다 open(). 3항상 그렇기 때문에 이라고 가정합니다 . fd 3 open으로 시작하더라도 첫 번째 반복 후에 닫힙니다. 최악의 경우, open3이 마지막으로 사용 가능한 파일 디스크립터가 될 때까지 새 fd를 계속 엽니 다. 따라서 처음 65531까지의 write()호출은로 실패 EBADF하지만 openfd = 3을 만들 때마다 정상적으로 작동합니다 .
O_WRONLY|O_CREAT|O_TRUNCx86-64 Linux에서 577 = 0x241 = 이 없으면 O_TRUNCinode 모드 시간 및 변경 시간이 업데이트되지 않으므로 더 짧은 인수가 불가능합니다. 실제 디스크 작업을 생성하기 위해 O_TRUNC호출하는 버전에는 여전히 중요하며, write다시 작성하지는 않습니다.
나는 몇 가지 대답을 참조하십시오 open("a",1). a존재하지 않는 경우 O_CREAT가 필요 합니다. O_CREATLinux에서는 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에서이 ABI 에 대한 플래그 의 십진수 값을 얻었습니다 strace -eraw=open.
Linux lazytime마운트 옵션이 활성화 된 파일 시스템에서, inode 타임 스탬프에만 영향을주는 변경은 24 시간마다 한 번만 기록합니다. 해당 마운트 옵션을 비활성화하면 타임 스탬프 업데이트가 SSD를 닳게하는 실용적인 방법 일 수 있습니다. 그러나 여러 다른 답변은 메타 데이터 I / O 만 수행합니다.
대안 :
더 짧은 비 작동 :
main(){for(;;)close(write(open("a",577),"",3));}write의 반환 값을 사용 하여 3arg를 닫아 전달합니다 . 다른 바이트를 저장하지만 amd64의 gcc -O0 또는 -O3에서는 작동하지 않습니다. 세 번째 인수의 가비지 open는 다르며 쓰기 권한이 없습니다. a처음으로 생성되지만 향후 반복은 모두 실패합니다 -EACCESS.
다른 시스템 호출로 더 오래 작동합니다 .
main(c){for(open("a",65);pwrite(3,"",1);)sync();} 바이트를 제자리에 다시 쓰고 sync()시스템 전체의 모든 파일 시스템을 동기화하기 위해 호출 합니다. 이렇게하면 드라이브 표시등이 켜집니다.
우리는 어떤 바이트를 신경 쓰지 않으므로 pwrite에 4 번째 인수를 전달하지 않습니다. 희소 파일의 경우 예 :
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
~ 128TiB의 오프셋에서 1 바이트를 쓰면 범위 맵을 보유하기 위해 300kiB의 공간을 사용하는 xfs가 발생했습니다. HFS + : IIRC가있는 OS X에서는이 작업을 시도하지 마십시오. 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 답변입니까?)