C en amd64 Linux, 36 bytes (solo marca de tiempo), 52 49 bytes (actividad de disco real)
Codifico las open(2)banderas, por lo que esto no es portátil para otras ABI. Linux en otras plataformas probablemente usa lo mismo O_TRUNC, etc., pero otros sistemas operativos POSIX pueden no hacerlo.
+4 bytes para pasar un argumento de permiso correcto para asegurarse de que el archivo se crea con acceso de escritura del propietario, vea a continuación. (Esto sucede para trabajar con gcc 5.2)
ANSI C algo portátil, 38/51 bytes (solo marca de tiempo), 52/67 bytes (actividad real del disco)
Basado en la respuesta de @ Cat, con un consejo de @Jens.
El primer número es para implementaciones donde un valor de retorno intpuede contener FILE *fopen(), el segundo número si no podemos hacer eso. En Linux, las direcciones de montón se encuentran en los bajos 32 bits de espacio de direcciones, por lo que funciona incluso sin -m32o -mx32. (La declaración void*fopen();es más corta que #include <stdio.h>)
Marca de tiempo de E / S de metadatos solamente :
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"));}
Escribir un byte, en realidad golpear el disco en Linux 4.2.0 + XFS + lazytime:
main(){for(;write(open("a",577),"",1);close(3));}
writees la condición for-loop, que está bien ya que siempre devuelve 1. closees el incremento.
// 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
Explicación de la versión no portátil:
El archivo se crea con permisos de basura aleatorios. Con gcc5.2, con -O0o -O3, resulta que incluye permiso de escritura del propietario, pero esto no está garantizado. 0666es decimal 438. Un tercer argumento para opentomaría otros 4 bytes . Ya estamos codificando O_TRUNC, etc., pero esto podría romperse con un compilador o libc diferente en el mismo ABI.
No podemos omitir el segundo argumento open, porque el valor de la basura incluye O_EXCL, y O_TRUNC|O_APPEND, por lo tanto, open falla EINVAL.
No necesitamos guardar el valor de retorno de open(). Asumimos que es 3, porque siempre lo será. Incluso si comenzamos con fd 3 abierto, se cerrará después de la primera iteración. En el peor de los casos, opensigue abriendo nuevos fds hasta que 3 es el último descriptor de archivo disponible. Por lo tanto, hasta las primeras 65531 write()llamadas podrían fallar EBADF, pero luego funcionarán normalmente con cada opencreación de fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNCen Linux x86-64. Sin O_TRUNC, el tiempo de modificación del inodo y el tiempo de cambio no se actualizan, por lo que no es posible un argumento más corto. O_TRUNCsigue siendo esencial para la versión que llama writea producir actividad de disco real, no a reescribir en su lugar.
Veo algunas respuestas que open("a",1). O_CREAT es obligatorio si aaún no existe. O_CREATse define como octal 0100 (64, 0x40) en Linux.
No hay fugas de recursos, por lo que puede ejecutarse para siempre. stracesalida:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
o
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
Obtuve el valor decimal de las openbanderas para este ABI usando strace -eraw=openen mi versión C ++.
En un sistema de archivos con la lazytimeopción de montaje de Linux habilitada, un cambio que solo afecta a las marcas de tiempo del inodo solo causará una escritura cada 24 horas. Con esa opción de montaje desactivada, la actualización de la marca de tiempo podría ser una forma viable de desgastar su SSD. (Sin embargo, varias otras respuestas solo hacen E / S de metadatos).
alternativas:
más corto que no funciona :
main(){for(;;)close(write(open("a",577),"",3));}usa writeel valor de retorno para pasar un 3argumento para cerrar. Guarda otro byte, pero no funciona con gcc -O0 u -O3 en amd64. La basura en el 3er argumento openes diferente y no incluye permiso de escritura. ase crea la primera vez, pero todas las iteraciones futuras fallan -EACCESS.
más largo, trabajando, con diferentes llamadas al sistema :
main(c){for(open("a",65);pwrite(3,"",1);)sync();} reescribe un byte en el lugar y llama sync() para sincronizar todos los sistemas de archivos en todo el sistema. Esto mantiene la luz de la unidad encendida.
No nos importa qué byte, por lo que no pasamos el 4to argumento para escribir. Yay para archivos dispersos:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Supongo que escribir un byte en un desplazamiento de ~ 128TiB condujo a xfs usando 300kB de espacio para contener el mapa de extensión. No intente esto en OS X con HFS +: IIRC, HFS + no admite archivos dispersos, por lo que llenará el disco.
XFS es un sistema de archivos de 64 bits adecuado, que admite archivos individuales de hasta 8 exabytes . es decir, 2 ^ 63-1, el valor máximo off_tpuede mantenerse.
strace salida:
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? (¿Esyes>/dev/nulluna respuesta Bash válida?)