Blesk

mread.c

Stáhnout

#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;
}