(root)/
glibc-2.38/
stdio-common/
tst-unlockedio.c
       1  /* Test for some *_unlocked stdio interfaces.
       2     Copyright (C) 2004-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stdlib.h>
      20  #include <stdio.h>
      21  #include <string.h>
      22  #include <libc-diag.h>
      23  
      24  int fd;
      25  static void do_prepare (void);
      26  static int do_test (void);
      27  #define PREPARE(argc, argv) do_prepare ()
      28  #define TEST_FUNCTION do_test ()
      29  #include "../test-skeleton.c"
      30  
      31  static int
      32  do_test (void)
      33  {
      34    const char blah[] = "BLAH";
      35    char buf[strlen (blah) + 1];
      36    FILE *fp, *f;
      37    const char *cp;
      38    char *wp;
      39  
      40    if ((fp = fdopen (fd, "w+")) == NULL)
      41      exit (1);
      42  
      43    flockfile (fp);
      44  
      45    f = fp;
      46    cp = blah;
      47    /* These tests deliberately use fwrite_unlocked with the size
      48       argument specified as 0, which results in "division by zero"
      49       warnings from the expansion of that macro (in code that is not
      50       evaluated for a size of 0).  This applies to the tests of
      51       fread_unlocked below as well.  */
      52    DIAG_PUSH_NEEDS_COMMENT;
      53    DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdiv-by-zero");
      54    if (ftello (fp) != 0
      55        || fwrite_unlocked (blah, blah - blah, strlen (blah), f++) != 0
      56        || f != fp + 1
      57        || fwrite_unlocked ("", 5.0, 0, --f) != 0
      58        || f != fp
      59        || fwrite_unlocked (cp++, 16, 0.25, fp) != 0
      60        || cp != blah + 1
      61        || fwrite_unlocked (--cp, 0.25, 16, fp) != 0
      62        || cp != blah
      63        || fwrite_unlocked (blah, 0, -0.0, fp) != 0
      64        || ftello (fp) != 0)
      65      {
      66        puts ("One of fwrite_unlocked tests failed");
      67        exit (1);
      68      }
      69    DIAG_POP_NEEDS_COMMENT;
      70  
      71    if (fwrite_unlocked (blah, 1, strlen (blah) - 2, fp) != strlen (blah) - 2)
      72      {
      73        puts ("Could not write string into file");
      74        exit (1);
      75      }
      76  
      77    if (putc_unlocked ('A' + 0x1000000, fp) != 'A')
      78      {
      79        puts ("putc_unlocked failed");
      80        exit (1);
      81      }
      82  
      83    f = fp;
      84    cp = blah + strlen (blah) - 1;
      85    if (putc_unlocked (*cp++, f++) != 'H'
      86        || f != fp + 1
      87        || cp != strchr (blah, '\0'))
      88      {
      89        puts ("fputc_unlocked failed");
      90        exit (1);
      91      }
      92  
      93    if (ftello (fp) != (off_t) strlen (blah))
      94      {
      95        printf ("Failed to write %zd bytes to temporary file", strlen (blah));
      96        exit (1);
      97      }
      98  
      99    rewind (fp);
     100  
     101    f = fp;
     102    wp = buf;
     103    memset (buf, ' ', sizeof (buf));
     104    /* See explanation above.  */
     105    DIAG_PUSH_NEEDS_COMMENT;
     106    DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdiv-by-zero");
     107    if (ftello (fp) != 0
     108        || fread_unlocked (buf, buf - buf, strlen (blah), f++) != 0
     109        || f != fp + 1
     110        || fread_unlocked (buf, 5.0, 0, --f) != 0
     111        || f != fp
     112        || fread_unlocked (wp++, 16, 0.25, fp) != 0
     113        || wp != buf + 1
     114        || fread_unlocked (--wp, 0.25, 16, fp) != 0
     115        || wp != buf
     116        || fread_unlocked (buf, 0, -0.0, fp) != 0
     117        || ftello (fp) != 0
     118        || memcmp (buf, "     ", sizeof (buf)) != 0)
     119      {
     120        puts ("One of fread_unlocked tests failed");
     121        exit (1);
     122      }
     123    DIAG_POP_NEEDS_COMMENT;
     124  
     125    if (fread_unlocked (buf, 1, strlen (blah) - 2, fp) != strlen (blah) - 2)
     126      {
     127        puts ("Could not read string from file");
     128        exit (1);
     129      }
     130  
     131    if (getc_unlocked (fp) != 'A')
     132      {
     133        puts ("getc_unlocked failed");
     134        exit (1);
     135      }
     136  
     137    f = fp;
     138    if (fgetc_unlocked (f++) != 'H'
     139        || f != fp + 1
     140        || fgetc_unlocked (--f) != EOF
     141        || f != fp)
     142      {
     143        puts ("fgetc_unlocked failed");
     144        exit (1);
     145      }
     146  
     147    if (ftello (fp) != (off_t) strlen (blah))
     148      {
     149        printf ("Failed to read %zd bytes from temporary file", strlen (blah));
     150        exit (1);
     151      }
     152  
     153    funlockfile (fp);
     154    fclose (fp);
     155  
     156    return 0;
     157  }
     158  
     159  static void
     160  do_prepare (void)
     161  {
     162    fd = create_temp_file ("tst-unlockedio.", NULL);
     163    if (fd == -1)
     164      {
     165        printf ("cannot create temporary file: %m\n");
     166        exit (1);
     167      }
     168  }