mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +01:00
Add a unit test for fgets (currently fails)
- For a non-blocking pipe, check that on EAGAIN fgets returns NULL rather than a partial line
This commit is contained in:
parent
23e9f362a2
commit
8ee559bd63
@ -1247,6 +1247,93 @@ test_util_exit_status(void *ptr)
|
||||
;
|
||||
}
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
/** Check that fgets waits until a full line, and not return a partial line, on
|
||||
* a EAGAIN with a non-blocking pipe */
|
||||
static void
|
||||
test_util_fgets_eagain(void *ptr)
|
||||
{
|
||||
int test_pipe[2] = {-1, -1};
|
||||
int retval;
|
||||
ssize_t retlen;
|
||||
char *retptr;
|
||||
FILE *test_stream = NULL;
|
||||
char buf[10];
|
||||
|
||||
(void)ptr;
|
||||
|
||||
/* Set up a pipe to test on */
|
||||
retval = pipe(test_pipe);
|
||||
tt_int_op(retval, >=, 0);
|
||||
|
||||
/* Set up the read-end to be non-blocking */
|
||||
retval = fcntl(test_pipe[0], F_SETFL, O_NONBLOCK);
|
||||
tt_int_op(retval, >=, 0);
|
||||
|
||||
/* Open it as a stdio stream */
|
||||
test_stream = fdopen(test_pipe[0], "r");
|
||||
tt_ptr_op(test_stream, !=, NULL);
|
||||
|
||||
/* Send in a partial line */
|
||||
retlen = write(test_pipe[1], "A", 1);
|
||||
tt_int_op(retlen, ==, 1);
|
||||
retptr = fgets(buf, sizeof(buf), test_stream);
|
||||
tt_want(retptr == NULL);
|
||||
tt_int_op(errno, ==, EAGAIN);
|
||||
|
||||
/* Send in the rest */
|
||||
retlen = write(test_pipe[1], "B\n", 2);
|
||||
tt_int_op(retlen, ==, 2);
|
||||
retptr = fgets(buf, sizeof(buf), test_stream);
|
||||
tt_ptr_op(retptr, ==, buf);
|
||||
tt_str_op(buf, ==, "AB\n");
|
||||
|
||||
/* Send in a full line */
|
||||
retlen = write(test_pipe[1], "CD\n", 3);
|
||||
tt_int_op(retlen, ==, 3);
|
||||
retptr = fgets(buf, sizeof(buf), test_stream);
|
||||
tt_ptr_op(retptr, ==, buf);
|
||||
tt_str_op(buf, ==, "CD\n");
|
||||
|
||||
/* Send in a partial line */
|
||||
retlen = write(test_pipe[1], "E", 1);
|
||||
tt_int_op(retlen, ==, 1);
|
||||
retptr = fgets(buf, sizeof(buf), test_stream);
|
||||
tt_ptr_op(retptr, ==, NULL);
|
||||
tt_int_op(errno, ==, EAGAIN);
|
||||
|
||||
/* Send in the rest */
|
||||
retlen = write(test_pipe[1], "F\n", 2);
|
||||
tt_int_op(retlen, ==, 2);
|
||||
retptr = fgets(buf, sizeof(buf), test_stream);
|
||||
tt_ptr_op(retptr, ==, buf);
|
||||
tt_str_op(buf, ==, "EF\n");
|
||||
|
||||
/* Send in a full line and close */
|
||||
retlen = write(test_pipe[1], "GH", 2);
|
||||
tt_int_op(retlen, ==, 2);
|
||||
retval = close(test_pipe[1]);
|
||||
test_pipe[1] = -1;
|
||||
tt_int_op(retval, ==, 0);
|
||||
retptr = fgets(buf, sizeof(buf), test_stream);
|
||||
tt_ptr_op(retptr, ==, buf);
|
||||
tt_str_op(buf, ==, "GH");
|
||||
|
||||
/* Check for EOF */
|
||||
retptr = fgets(buf, sizeof(buf), test_stream);
|
||||
tt_ptr_op(retptr, ==, NULL);
|
||||
tt_int_op(feof(test_stream), >, 0);
|
||||
|
||||
done:
|
||||
if (test_stream != NULL)
|
||||
fclose(test_stream);
|
||||
if (test_pipe[0] != -1)
|
||||
close(test_pipe[0]);
|
||||
if (test_pipe[1] != -1)
|
||||
close(test_pipe[1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UTIL_LEGACY(name) \
|
||||
{ #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
|
||||
|
||||
@ -1274,6 +1361,9 @@ struct testcase_t util_tests[] = {
|
||||
UTIL_TEST(load_win_lib, 0),
|
||||
#endif
|
||||
UTIL_TEST(exit_status, 0),
|
||||
#ifndef MS_WINDOWS
|
||||
UTIL_TEST(fgets_eagain, 0),
|
||||
#endif
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user