(root)/
glibc-2.38/
libio/
tst-memstream3.c
       1  /* Test for open_memstream implementation.
       2     Copyright (C) 2016-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 <mcheck.h>
      20  #include <stdio.h>
      21  #include <stdlib.h>
      22  #include <string.h>
      23  #include <stdarg.h>
      24  #include <errno.h>
      25  
      26  
      27  #ifndef CHAR_T
      28  # define CHAR_T char
      29  # define W(o) o
      30  # define OPEN_MEMSTREAM open_memstream
      31  # define PRINTF printf
      32  # define FWRITE_FUNC fwrite
      33  # define FPUTC fputc
      34  # define STRCMP strcmp
      35  #endif
      36  
      37  #define S(s) S1 (s)
      38  #define S1(s) #s
      39  
      40  static void
      41  mcheck_abort (enum mcheck_status ev)
      42  {
      43    printf ("mecheck failed with status %d\n", (int) ev);
      44    exit (1);
      45  }
      46  
      47  static void
      48  error_printf (int line, const char *fmt, ...)
      49  {
      50    va_list ap;
      51  
      52    printf ("error: %s:%i: ", __FILE__, line);
      53    va_start (ap, fmt);
      54    vprintf (fmt, ap);
      55    va_end (ap);
      56  }
      57  
      58  #define ERROR_RET1(...) \
      59    { error_printf(__LINE__, __VA_ARGS__); return 1; }
      60  
      61  static int
      62  do_test_bz18241 (void)
      63  {
      64    CHAR_T *buf;
      65    size_t size;
      66  
      67    FILE *fp = OPEN_MEMSTREAM (&buf, &size);
      68    if (fp == NULL)
      69      ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM));
      70  
      71    if (FPUTC (W('a'), fp) != W('a'))
      72      ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno);
      73    if (fflush (fp) != 0)
      74      ERROR_RET1 ("fflush failed (errno = %d)\n", errno);
      75    if (fseek (fp, -2, SEEK_SET) != -1)
      76      ERROR_RET1 ("fseek failed (errno = %d)\n", errno);
      77    if (errno != EINVAL)
      78      ERROR_RET1 ("errno != EINVAL\n");
      79    if (ftell (fp) != 1)
      80      ERROR_RET1 ("ftell failed (errno = %d)\n", errno);
      81    if (ferror (fp) != 0)
      82      ERROR_RET1 ("ferror != 0\n");
      83  
      84    if (fseek (fp, -1, SEEK_CUR) == -1)
      85      ERROR_RET1 ("fseek failed (errno = %d)\n", errno);
      86    if (ftell (fp) != 0)
      87      ERROR_RET1 ("ftell failed (errno = %d)\n", errno);
      88    if (ferror (fp) != 0)
      89      ERROR_RET1 ("ferror != 0\n");
      90    if (FPUTC (W('b'), fp) != W('b'))
      91      ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno);
      92    if (fflush (fp) != 0)
      93      ERROR_RET1 ("fflush failed (errno = %d)\n", errno);
      94  
      95    if (fclose (fp) != 0)
      96      ERROR_RET1 ("fclose failed (errno = %d\n", errno);
      97  
      98    if (STRCMP (buf, W("b")) != 0)
      99      ERROR_RET1 ("%s failed\n", S(STRCMP));
     100  
     101    free (buf);
     102  
     103    return 0;
     104  }
     105  
     106  static int
     107  do_test_bz20181 (void)
     108  {
     109    CHAR_T *buf;
     110    size_t size;
     111    size_t ret;
     112  
     113    FILE *fp = OPEN_MEMSTREAM (&buf, &size);
     114    if (fp == NULL)
     115      ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM));
     116  
     117    if ((ret = FWRITE_FUNC (W("abc"), 1, 3, fp)) != 3)
     118      ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE_FUNC), errno);
     119  
     120    if (fseek (fp, 0, SEEK_SET) != 0)
     121      ERROR_RET1 ("fseek failed (errno = %d)\n", errno);
     122  
     123    if (FWRITE_FUNC (W("z"), 1, 1, fp) != 1)
     124      ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE_FUNC), errno);
     125  
     126    if (fflush (fp) != 0)
     127      ERROR_RET1 ("fflush failed (errno = %d)\n", errno);
     128  
     129    /* Avoid truncating the buffer on close.  */
     130    if (fseek (fp, 3, SEEK_SET) != 0)
     131      ERROR_RET1 ("fseek failed (errno = %d)\n", errno);
     132  
     133    if (fclose (fp) != 0)
     134      ERROR_RET1 ("fclose failed (errno = %d\n", errno);
     135  
     136    if (size != 3)
     137      ERROR_RET1 ("size != 3\n");
     138  
     139    if (buf[0] != W('z')
     140        || buf[1] != W('b')
     141        || buf[2] != W('c'))
     142      {
     143        PRINTF (W("error: buf {%c,%c,%c} != {z,b,c}\n"),
     144  	      buf[0], buf[1], buf[2]);
     145        return 1;
     146      }
     147  
     148    free (buf);
     149  
     150    return 0;
     151  }
     152  
     153  static int
     154  do_test (void)
     155  {
     156    int ret = 0;
     157  
     158    mcheck_pedantic (mcheck_abort);
     159  
     160    ret += do_test_bz18241 ();
     161    ret += do_test_bz20181 ();
     162  
     163    return ret;
     164  }
     165  
     166  #define TEST_FUNCTION do_test ()
     167  #include "../test-skeleton.c"