Ticket #12503: 0001-Fixed-fgets_eagain-unit-test.patch

File 0001-Fixed-fgets_eagain-unit-test.patch, 4.1 KB (added by cypherpunks, 6 years ago)
  • src/test/test_util.c

    From 48abb8e68886c601c4f7597e08d405cd9b28d5a5 Mon Sep 17 00:00:00 2001
    From: cypherpunks <cypherpunks@torproject.org>
    Subject: [PATCH 1/2] Fixed fgets_eagain unit test.
    
    On a non-blocking pipe fgets sets EAGAIN when it encounters partial lines. No
    error is set on full lines or EOF. EOF is reached when the writing end of the
    pipe is closed. Partial lines and full lines are both returned by fgets, EOF
    results in NULL.
    
    Mention of this behaviour can be found in #1903 and #2045.
    ---
     src/test/test_util.c | 45 +++++++++++++++++++++++++++++++++------------
     1 file changed, 33 insertions(+), 12 deletions(-)
    
    diff --git a/src/test/test_util.c b/src/test/test_util.c
    index 6c72247..8236931 100644
    a b test_util_exit_status(void *ptr) 
    21862186}
    21872187
    21882188#ifndef _WIN32
    2189 /** Check that fgets waits until a full line, and not return a partial line, on
    2190  * a EAGAIN with a non-blocking pipe */
     2189/* Check that fgets with a non-blocking pipe returns partial lines and sets
     2190 * EAGAIN, returns full lines and sets no error, and returns NULL on EOF and
     2191 * sets no error */
    21912192static void
    21922193test_util_fgets_eagain(void *ptr)
    21932194{
    test_util_fgets_eagain(void *ptr) 
    21962197  ssize_t retlen;
    21972198  char *retptr;
    21982199  FILE *test_stream = NULL;
    2199   char buf[10];
     2200  char buf[4] = { 0 };
    22002201
    22012202  (void)ptr;
    22022203
     2204  errno = 0;
     2205
    22032206  /* Set up a pipe to test on */
    22042207  retval = pipe(test_pipe);
    2205   tt_int_op(retval, >=, 0);
     2208  tt_int_op(retval, ==, 0);
    22062209
    22072210  /* Set up the read-end to be non-blocking */
    22082211  retval = fcntl(test_pipe[0], F_SETFL, O_NONBLOCK);
    2209   tt_int_op(retval, >=, 0);
     2212  tt_int_op(retval, ==, 0);
    22102213
    22112214  /* Open it as a stdio stream */
    22122215  test_stream = fdopen(test_pipe[0], "r");
    test_util_fgets_eagain(void *ptr) 
    22162219  retlen = write(test_pipe[1], "A", 1);
    22172220  tt_int_op(retlen, ==, 1);
    22182221  retptr = fgets(buf, sizeof(buf), test_stream);
    2219   tt_want(retptr == NULL);
    22202222  tt_int_op(errno, ==, EAGAIN);
     2223  tt_ptr_op(retptr, ==, buf);
     2224  tt_str_op(buf, ==, "A");
     2225  errno = 0;
    22212226
    22222227  /* Send in the rest */
    22232228  retlen = write(test_pipe[1], "B\n", 2);
    22242229  tt_int_op(retlen, ==, 2);
    22252230  retptr = fgets(buf, sizeof(buf), test_stream);
     2231  tt_int_op(errno, ==, 0);
    22262232  tt_ptr_op(retptr, ==, buf);
    2227   tt_str_op(buf, ==, "AB\n");
     2233  tt_str_op(buf, ==, "B\n");
     2234  errno = 0;
    22282235
    22292236  /* Send in a full line */
    22302237  retlen = write(test_pipe[1], "CD\n", 3);
    22312238  tt_int_op(retlen, ==, 3);
    22322239  retptr = fgets(buf, sizeof(buf), test_stream);
     2240  tt_int_op(errno, ==, 0);
    22332241  tt_ptr_op(retptr, ==, buf);
    22342242  tt_str_op(buf, ==, "CD\n");
     2243  errno = 0;
    22352244
    22362245  /* Send in a partial line */
    22372246  retlen = write(test_pipe[1], "E", 1);
    22382247  tt_int_op(retlen, ==, 1);
    22392248  retptr = fgets(buf, sizeof(buf), test_stream);
    2240   tt_ptr_op(retptr, ==, NULL);
    22412249  tt_int_op(errno, ==, EAGAIN);
     2250  tt_ptr_op(retptr, ==, buf);
     2251  tt_str_op(buf, ==, "E");
     2252  errno = 0;
    22422253
    22432254  /* Send in the rest */
    22442255  retlen = write(test_pipe[1], "F\n", 2);
    22452256  tt_int_op(retlen, ==, 2);
    22462257  retptr = fgets(buf, sizeof(buf), test_stream);
     2258  tt_int_op(errno, ==, 0);
    22472259  tt_ptr_op(retptr, ==, buf);
    2248   tt_str_op(buf, ==, "EF\n");
     2260  tt_str_op(buf, ==, "F\n");
     2261  errno = 0;
    22492262
    22502263  /* Send in a full line and close */
    22512264  retlen = write(test_pipe[1], "GH", 2);
    22522265  tt_int_op(retlen, ==, 2);
    22532266  retval = close(test_pipe[1]);
    2254   test_pipe[1] = -1;
    22552267  tt_int_op(retval, ==, 0);
     2268  test_pipe[1] = -1;
    22562269  retptr = fgets(buf, sizeof(buf), test_stream);
     2270  tt_int_op(errno, ==, 0);
    22572271  tt_ptr_op(retptr, ==, buf);
    22582272  tt_str_op(buf, ==, "GH");
     2273  errno = 0;
    22592274
    22602275  /* Check for EOF */
    22612276  retptr = fgets(buf, sizeof(buf), test_stream);
     2277  tt_int_op(errno, ==, 0);
    22622278  tt_ptr_op(retptr, ==, NULL);
    2263   tt_int_op(feof(test_stream), >, 0);
     2279  retval = feof(test_stream);
     2280  tt_int_op(retval, !=, 0);
     2281  errno = 0;
     2282
     2283  /* Check that buf is unchanged according to C99 and C11 */
     2284  tt_str_op(buf, ==, "GH");
    22642285
    22652286 done:
    22662287  if (test_stream != NULL)
    struct testcase_t util_tests[] = { 
    31163137#endif
    31173138  UTIL_TEST(exit_status, 0),
    31183139#ifndef _WIN32
    3119   UTIL_TEST(fgets_eagain, TT_SKIP),
     3140  UTIL_TEST(fgets_eagain, 0),
    31203141#endif
    31213142  UTIL_TEST(spawn_background_ok, 0),
    31223143  UTIL_TEST(spawn_background_fail, 0),