#define _POSIX_C_SOURCE 200809L #include /* assert */ #include /* close, read, unlink, write */ /* Implementujte podprogram ‹count_byte›, který spočítá kolikrát se * ve vstupu daném popisovačem ‹fd› objevuje zadaný bajt ‹byte›. * Vstup zpracovávejte postupně po malých částech (množství paměti * potřebné pro spuštění programu nesmí záviset na velikosti * vstupu). * * Návratová hodnota bude: * * • nezáporná hodnota – počet výskytů – proběhlo-li vše v pořádku, * • ‹-1› v případě selhání čtení nebo jiné systémové chyby. */ int count_byte( int fd, char byte ); /* ┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄┄┄┄ následují testy ┄┄┄┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄ */ #include /* open, openat */ #include /* open, openat */ #include /* open, openat, unlink */ #include /* err, warn */ #include /* errno, ENOENT */ #include /* strlen */ static void unlink_if_exists( const char *file ) { if ( unlink( file ) == -1 && errno != ENOENT ) err( 2, "unlink" ); } static void close_or_warn( int fd, const char *name ) { if ( close( fd ) == -1 ) warn( "closing %s", name ); } static int check_file( const char *file, char to_find ) { int fd, result; if ( ( fd = openat( AT_FDCWD, file, O_RDONLY ) ) == -1 ) err( 2, "opening %s", file ); result = count_byte( fd, to_find ); close_or_warn( fd, file ); return result; } static int check_string( const char *str, char to_find ) { int fd; const char *name = "zt.p1_test_in"; if ( ( fd = openat( AT_FDCWD, name, O_CREAT | O_TRUNC | O_WRONLY, 0666 ) ) == -1 ) err( 2, "creating %s", name ); if ( write( fd, str, strlen( str ) ) == -1 ) err( 2, "writing file %s", name ); close_or_warn( fd, name ); return check_file( name, to_find ); } int main( void ) { unlink_if_exists( "zt.p1_test_in" ); assert( check_string( "\n", 'a' ) == 0 ); assert( check_string( "abc\n", 'a' ) == 1 ); assert( check_string( "abc", 'A' ) == 0 ); assert( check_string( "aAAbAabAAAa", 'a' ) == 3 ); assert( check_string( "Roses are red,\n" "violets are blue,\n" "hello world\n" "possibly from Linux/GNU.\n", 'a' ) == 2 ); assert( check_string( "", 'a' ) == 0 ); assert( check_string( "aaa", 'a' ) == 3 ); assert( check_string( "--.. .. ...- --- - / .--- . / -... --- .---", '-' ) == 17 ); int fd_wronly = open( "/dev/null", O_WRONLY ); if ( fd_wronly == -1 ) err( 2, "opening /dev/null" ); assert( count_byte( fd_wronly, '.' ) == -1 ); assert( errno == EBADF ); close_or_warn( fd_wronly, "/dev/null" ); unlink_if_exists( "zt.p1_test_in" ); return 0; }