root/maint/gnulib/tests/test-strerror_r.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

   1 /* Test of strerror_r() function.
   2    Copyright (C) 2007-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 <string.h>
  20 
  21 #include "signature.h"
  22 SIGNATURE_CHECK (strerror_r, int, (int, char *, size_t));
  23 
  24 #include <errno.h>
  25 
  26 #include "macros.h"
  27 
  28 int
  29 main (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31   char buf[100];
  32   int ret;
  33 
  34   /* Test results with valid errnum and enough room.  */
  35 
  36   errno = 0;
  37   buf[0] = '\0';
  38   ASSERT (strerror_r (EACCES, buf, sizeof buf) == 0);
  39   ASSERT (buf[0] != '\0');
  40   ASSERT (errno == 0);
  41   ASSERT (strlen (buf) < sizeof buf);
  42 
  43   errno = 0;
  44   buf[0] = '\0';
  45   ASSERT (strerror_r (ETIMEDOUT, buf, sizeof buf) == 0);
  46   ASSERT (buf[0] != '\0');
  47   ASSERT (errno == 0);
  48   ASSERT (strlen (buf) < sizeof buf);
  49 
  50   errno = 0;
  51   buf[0] = '\0';
  52   ASSERT (strerror_r (EOVERFLOW, buf, sizeof buf) == 0);
  53   ASSERT (buf[0] != '\0');
  54   ASSERT (errno == 0);
  55   ASSERT (strlen (buf) < sizeof buf);
  56 
  57   /* POSIX requires strerror (0) to succeed.  Reject use of "Unknown
  58      error", but allow "Success", "No error", or even Solaris' "Error
  59      0" which are distinct patterns from true out-of-range strings.
  60      http://austingroupbugs.net/view.php?id=382  */
  61   errno = 0;
  62   buf[0] = '\0';
  63   ret = strerror_r (0, buf, sizeof buf);
  64   ASSERT (ret == 0);
  65   ASSERT (buf[0]);
  66   ASSERT (errno == 0);
  67   ASSERT (strstr (buf, "nknown") == NULL);
  68   ASSERT (strstr (buf, "ndefined") == NULL);
  69 
  70   /* Test results with out-of-range errnum and enough room.  POSIX
  71      allows an empty string on success, and allows an unchanged buf on
  72      error, but these are not useful, so we guarantee contents.  */
  73   errno = 0;
  74   buf[0] = '^';
  75   ret = strerror_r (-3, buf, sizeof buf);
  76   ASSERT (ret == 0 || ret == EINVAL);
  77   ASSERT (buf[0] != '^');
  78   ASSERT (*buf);
  79   ASSERT (errno == 0);
  80   ASSERT (strlen (buf) < sizeof buf);
  81 
  82   /* Test results with a too small buffer.  POSIX requires an error;
  83      only ERANGE for 0 and valid errors, and a choice of ERANGE or
  84      EINVAL for out-of-range values.  On error, POSIX permits buf to
  85      be empty, unchanged, or unterminated, but these are not useful,
  86      so we guarantee NUL-terminated truncated contents for all but
  87      size 0.  http://austingroupbugs.net/view.php?id=398.  Also ensure
  88      that no out-of-bounds writes occur.  */
  89   {
  90     int errs[] = { EACCES, 0, -3, };
  91     int j;
  92 
  93     buf[sizeof buf - 1] = '\0';
  94     for (j = 0; j < SIZEOF (errs); j++)
  95       {
  96         int err = errs[j];
  97         char buf2[sizeof buf] = "";
  98         size_t len;
  99         size_t i;
 100 
 101         strerror_r (err, buf2, sizeof buf2);
 102         len = strlen (buf2);
 103         ASSERT (len < sizeof buf);
 104 
 105         for (i = 0; i <= len; i++)
 106           {
 107             memset (buf, '^', sizeof buf - 1);
 108             errno = 0;
 109             ret = strerror_r (err, buf, i);
 110             ASSERT (errno == 0);
 111             if (j == 2)
 112               ASSERT (ret == ERANGE || ret == EINVAL);
 113             else
 114               ASSERT (ret == ERANGE);
 115             if (i)
 116               {
 117                 ASSERT (strncmp (buf, buf2, i - 1) == 0);
 118                 ASSERT (buf[i - 1] == '\0');
 119               }
 120             ASSERT (strspn (buf + i, "^") == sizeof buf - 1 - i);
 121           }
 122 
 123         strcpy (buf, "BADFACE");
 124         errno = 0;
 125         ret = strerror_r (err, buf, len + 1);
 126         ASSERT (ret != ERANGE);
 127         ASSERT (errno == 0);
 128         ASSERT (strcmp (buf, buf2) == 0);
 129       }
 130   }
 131 
 132 #if GNULIB_STRERROR
 133   /* Test that strerror_r does not clobber strerror buffer.  On some
 134      platforms, this test can only succeed if gnulib also replaces
 135      strerror.  */
 136   {
 137     const char *msg1;
 138     const char *msg2;
 139     const char *msg3;
 140     const char *msg4;
 141     char *str1;
 142     char *str2;
 143     char *str3;
 144     char *str4;
 145 
 146     msg1 = strerror (ENOENT);
 147     ASSERT (msg1);
 148     str1 = strdup (msg1);
 149     ASSERT (str1);
 150 
 151     msg2 = strerror (ERANGE);
 152     ASSERT (msg2);
 153     str2 = strdup (msg2);
 154     ASSERT (str2);
 155 
 156     msg3 = strerror (-4);
 157     ASSERT (msg3);
 158     str3 = strdup (msg3);
 159     ASSERT (str3);
 160 
 161     msg4 = strerror (1729576);
 162     ASSERT (msg4);
 163     str4 = strdup (msg4);
 164     ASSERT (str4);
 165 
 166     strerror_r (EACCES, buf, sizeof buf);
 167     strerror_r (-5, buf, sizeof buf);
 168     ASSERT (STREQ (msg4, str4));
 169 
 170     free (str1);
 171     free (str2);
 172     free (str3);
 173     free (str4);
 174   }
 175 #endif
 176 
 177   return 0;
 178 }

/* [previous][next][first][last][top][bottom][index][help] */