#define _POSIX_C_SOURCE 200809L
#include <unistd.h> /* close, lseek */
#include <fcntl.h> /* openat */
#include <sys/mman.h> /* mmap, munmap */
#include <stdio.h> /* printf */
#include <errno.h> /* errno */
#include <err.h> /* NONPOSIX: err, errx */
/* Přečte soubor ‹file› a spočítá xor napříč všemi bajty. Soubor
* čte po namapování do paměti skrze ‹mmap›. */
int main( int argc, char** argv )
{
if ( argc < 2 )
errx( 1, "usage: %s file", argv[ 0 ] );
const char* filename = argv[ 1 ];
int fd = openat( AT_FDCWD, filename, O_RDONLY );
if ( fd == -1 )
err( 1, "openat %s", filename );
ssize_t size = lseek( fd, 0, SEEK_END );
if ( size == -1 )
err( 1, "lseek" );
unsigned char result = 0;
unsigned char* ptr = MAP_FAILED;
if ( size == 0 )
goto cleanup;
ptr = ( unsigned char* )mmap( 0, size, PROT_READ, MAP_PRIVATE, fd, 0 );
if ( ptr == MAP_FAILED ) err( 1, "mmap" );
for ( long long i = 0; i < size; ++i )
{
result ^= ptr[ i ];
}
munmap( ptr, size );
cleanup:
printf( "0x%02hhx\n", result );
if ( close( fd ) ) warn( "close %s", filename );
return 0;
}