1
0
mirror of https://https.git.savannah.gnu.org/git/gnulib.git synced 2026-06-16 15:56:32 +00:00
Files
gnulib/tests/test-nonblocking-reader.h
Paul Eggert ded19662f1 In tests, prefer %zu to %lu+cast
* tests/test-dirname.c (main):
* tests/test-gc-pbkdf2-sha1.c (main):
* tests/test-gc-pbkdf2.c (main):
* tests/test-nonblocking-reader.h (full_read)
* tests/test-nonblocking-writer.h (main_writer_loop):
(full_read_from_nonblocking_fd):
* tests/test-read-file.c (test_read_file):
Prefer %zu to %lu plus a cast to unsigned long.
* tests/test-nonblocking-reader.h (full_read)
* tests/test-nonblocking-writer.h (main_writer_loop):
(full_read_from_nonblocking_fd):
Pacify -Wuseless-cast via compound literals.
2026-05-08 20:25:26 -07:00

202 lines
6.2 KiB
C

/* The reader part of a test program for non-blocking communication.
Copyright (C) 2011-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* This program implements 4 tests:
test == 0:
Test blocking write() with blocking read().
Timeline Main process Child process
0 s Start Start, read(10000)
1 s write(20000) Return from read(10000)
2 s Next read(10000)
2 s Return from write(20000) Return from read(10000)
test == 1:
Test non-blocking write() with blocking read().
Timeline Main process Child process
0 s Start Start, read(10000)
1 s write(20000) Return from read(10000)
Return with at least 10000,
Repeatedly continue
write() of the rest
2 s Next read(10000)
2 s Return from write(10000) Return from read(10000)
test == 2:
Test blocking write() with non-blocking read().
Timeline Main process Child process
0 s Start Start, read(10000)
repeatedly polling
1 s write(20000) Return from read(10000)
2 s Next read(10000)
2 s Return from write(20000) Return from read(10000)
test == 3:
Test non-blocking write() with non-blocking read().
*/
#include "test-nonblocking-misc.h"
static ssize_t
full_read (size_t fd, void *buf, size_t count)
{
size_t bytes_read;
bytes_read = 0;
while (bytes_read < count)
{
TIMING_DECLS
ssize_t ret;
int saved_errno;
dbgfprintf (stderr, "%s: >> read (%zu)\n", PROG_ROLE,
count - bytes_read);
START_TIMING
ret = read (fd, (char *) buf + bytes_read, count - bytes_read);
saved_errno = errno;
END_TIMING
dbgfprintf (stderr, "%s: << read -> %ld%s\n", PROG_ROLE,
(long) {ret}, dbgstrerror (ret < 0, saved_errno));
(void) spent_time;
if (ret < 0)
return -1;
else
{
ASSERT (ret > 0);
bytes_read += ret;
}
}
return bytes_read;
}
static ssize_t
full_read_from_nonblocking_fd (size_t fd, void *buf, size_t count)
{
size_t bytes_read;
bytes_read = 0;
while (bytes_read < count)
{
TIMING_DECLS
ssize_t ret;
int saved_errno;
dbgfprintf (stderr, "%s: >> read (%zu)\n", PROG_ROLE,
count - bytes_read);
START_TIMING
ret = read (fd, (char *) buf + bytes_read, count - bytes_read);
saved_errno = errno;
END_TIMING
dbgfprintf (stderr, "%s: << read -> %ld%s\n", PROG_ROLE,
(long) {ret}, dbgstrerror (ret < 0, saved_errno));
/* This assertion fails if the non-blocking flag is effectively not set
on fd. */
ASSERT (spent_time < 0.5);
if (ret < 0)
{
ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
usleep (SMALL_DELAY);
}
else
{
ASSERT (ret > 0);
bytes_read += ret;
}
}
return bytes_read;
}
/* Execute the reader loop. */
static void
main_reader_loop (int test, size_t data_block_size, int fd)
{
unsigned char *expected;
unsigned char *data;
/* Set up the expected data. */
expected = init_data (data_block_size);
data = (unsigned char *) malloc (2 * data_block_size);
ASSERT (data != NULL);
switch (test)
{
TIMING_DECLS
ssize_t ret;
case 0: /* Test blocking write() with blocking read(). */
case 1: /* Test non-blocking write() with blocking read(). */
START_TIMING
ret = full_read (fd, data, data_block_size);
END_TIMING
ASSERT (ret == data_block_size);
ASSERT (memeq (data, expected, data_block_size));
ASSERT (spent_time > 0.5);
/* This assertion fails if data_block_size is very large and
ENABLE_DEBUGGING is 1. */
ASSERT (spent_time < 1.5);
usleep (1000000);
START_TIMING
ret = full_read (fd, data, data_block_size);
END_TIMING
ASSERT (ret == data_block_size);
ASSERT (memeq (data, expected + data_block_size, data_block_size));
/* This assertion fails if data_block_size is much larger than needed
and SMALL_DELAY is too large. */
ASSERT (spent_time < 0.5);
break;
case 2: /* Test blocking write() with non-blocking read(). */
case 3: /* Test non-blocking write() with non-blocking read(). */
START_TIMING
ret = full_read_from_nonblocking_fd (fd, data, data_block_size);
END_TIMING
ASSERT (ret == data_block_size);
ASSERT (memeq (data, expected, data_block_size));
ASSERT (spent_time > 0.5);
/* This assertion fails if data_block_size is much larger than needed
and SMALL_DELAY is too large, or if data_block_size is very large and
ENABLE_DEBUGGING is 1. */
ASSERT (spent_time < 1.5);
usleep (1000000);
START_TIMING
ret = full_read_from_nonblocking_fd (fd, data, data_block_size);
END_TIMING
ASSERT (ret == data_block_size);
ASSERT (memeq (data, expected + data_block_size, data_block_size));
/* This assertion fails if data_block_size is much larger than needed
and SMALL_DELAY is too large. */
ASSERT (spent_time < 0.5);
break;
default:
abort ();
}
free (data);
free (expected);
}