(root)/
m4-1.4.19/
tests/
test-perror2.c
       1  /* Test of perror() function.
       2     Copyright (C) 2011-2021 Free Software Foundation, Inc.
       3  
       4     This program is free software; you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation; either version 3, or (at your option)
       7     any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program; if not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #include <config.h>
      18  
      19  #include <stdio.h>
      20  
      21  #include <errno.h>
      22  #include <string.h>
      23  #include <unistd.h>
      24  
      25  /* This test intentionally parses stderr.  So, we arrange to have fd 10
      26     (outside the range of interesting fd's during the test) set up to
      27     duplicate the original stderr.  */
      28  #define BACKUP_STDERR_FILENO 10
      29  #define ASSERT_STREAM myerr
      30  #include "macros.h"
      31  
      32  static FILE *myerr;
      33  
      34  #define BASE "test-perror2"
      35  
      36  int
      37  main (void)
      38  {
      39    /* We change fd 2 later, so save it in fd 10.  */
      40    if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
      41        || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
      42      return 2;
      43  
      44    ASSERT (freopen (BASE ".tmp", "w+", stderr) == stderr);
      45  
      46    /* Test that perror does not clobber strerror buffer.  */
      47    {
      48      const char *msg1;
      49      const char *msg2;
      50      const char *msg3;
      51      const char *msg4;
      52      char *str1;
      53      char *str2;
      54      char *str3;
      55      char *str4;
      56  
      57      msg1 = strerror (ENOENT);
      58      ASSERT (msg1);
      59      str1 = strdup (msg1);
      60      ASSERT (str1);
      61  
      62      msg2 = strerror (ERANGE);
      63      ASSERT (msg2);
      64      str2 = strdup (msg2);
      65      ASSERT (str2);
      66  
      67      msg3 = strerror (-4);
      68      ASSERT (msg3);
      69      str3 = strdup (msg3);
      70      ASSERT (str3);
      71  
      72      msg4 = strerror (1729576);
      73      ASSERT (msg4);
      74      str4 = strdup (msg4);
      75      ASSERT (str4);
      76  
      77      errno = EACCES;
      78      perror ("");
      79      errno = -5;
      80      perror ("");
      81      ASSERT (!ferror (stderr));
      82      ASSERT (STREQ (msg4, str4));
      83  
      84      free (str1);
      85      free (str2);
      86      free (str3);
      87      free (str4);
      88    }
      89  
      90    /* Test that perror uses the same message as strerror.  */
      91    {
      92      int errs[] = { EACCES, 0, -3, };
      93      int i;
      94      for (i = 0; i < SIZEOF (errs); i++)
      95        {
      96          char buf[256];
      97          const char *err = strerror (errs[i]);
      98  
      99          ASSERT (err);
     100          ASSERT (strlen (err) < sizeof buf);
     101          rewind (stderr);
     102          ASSERT (ftruncate (fileno (stderr), 0) == 0);
     103          errno = errs[i];
     104          perror (NULL);
     105          ASSERT (!ferror (stderr));
     106          rewind (stderr);
     107          ASSERT (fgets (buf, sizeof buf, stderr) == buf);
     108          ASSERT (strstr (buf, err));
     109        }
     110    }
     111  
     112    /* Test that perror reports write failure.  */
     113    {
     114      ASSERT (freopen (BASE ".tmp", "r", stderr) == stderr);
     115      ASSERT (setvbuf (stderr, NULL, _IONBF, BUFSIZ) == 0);
     116      errno = -1;
     117      ASSERT (!ferror (stderr));
     118      perror (NULL);
     119  #if 0
     120      /* Commented out until cygwin behaves:
     121         https://sourceware.org/ml/newlib/2011/msg00228.html */
     122      ASSERT (errno > 0);
     123      /* Commented out until glibc behaves:
     124         https://sourceware.org/bugzilla/show_bug.cgi?id=12792 */
     125      ASSERT (ferror (stderr));
     126  #endif
     127    }
     128  
     129    ASSERT (fclose (stderr) == 0);
     130    ASSERT (remove (BASE ".tmp") == 0);
     131  
     132    return 0;
     133  }