Update.
[platform/upstream/glibc.git] / string / stratcliff.c
1 /* Test for string function add boundaries of usable memory.
2    Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #define _GNU_SOURCE 1
22
23 /* Make sure we don't test the optimized inline functions if we want to
24    test the real implementation.  */
25 #undef __USE_STRING_INLINES
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/mman.h>
32 #include <sys/param.h>
33
34 #ifndef MAX
35 #define MAX(a, b) ((a) > (b) ? (a) : (b))
36 #endif
37
38 int
39 main (int argc, char *argv[])
40 {
41   int size = sysconf (_SC_PAGESIZE);
42   char *adr, *dest;
43   int result = 0;
44
45   adr = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
46                        MAP_PRIVATE | MAP_ANON, -1, 0);
47   dest = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
48                         MAP_PRIVATE | MAP_ANON, -1, 0);
49   if (adr == MAP_FAILED || dest == MAP_FAILED)
50     {
51       if (errno == ENOSYS)
52         puts ("No test, mmap not available.");
53       else
54         {
55           printf ("mmap failed: %m");
56           result = 1;
57         }
58     }
59   else
60     {
61       int inner, middle, outer;
62
63       mprotect(adr, size, PROT_NONE);
64       mprotect(adr + 2 * size, size, PROT_NONE);
65       adr += size;
66
67       mprotect(dest, size, PROT_NONE);
68       mprotect(dest + 2 * size, size, PROT_NONE);
69       dest += size;
70
71       memset (adr, 'T', size);
72
73       /* strlen test */
74       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
75         {
76           for (inner = MAX (outer, size - 64); inner < size; ++inner)
77             {
78               adr[inner] = '\0';
79
80               if (strlen (&adr[outer]) != (size_t) (inner - outer))
81                 {
82                   printf ("strlen flunked for outer = %d, inner = %d\n",
83                           outer, inner);
84                   result = 1;
85                 }
86
87               adr[inner] = 'T';
88             }
89         }
90
91       /* strchr test */
92       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
93         {
94           for (middle = MAX (outer, size - 64); middle < size; ++middle)
95             {
96               for (inner = middle; inner < size; ++inner)
97                 {
98                   char *cp;
99                   adr[middle] = 'V';
100                   adr[inner] = '\0';
101
102                   cp = strchr (&adr[outer], 'V');
103
104                   if ((inner == middle && cp != NULL)
105                       || (inner != middle
106                           && (cp - &adr[outer]) != middle - outer))
107                     {
108                       printf ("strchr flunked for outer = %d, middle = %d, "
109                               "inner = %d\n", outer, middle, inner);
110                       result = 1;
111                     }
112
113                   adr[inner] = 'T';
114                   adr[middle] = 'T';
115                 }
116             }
117         }
118
119       /* Special test.  */
120       adr[size - 1] = '\0';
121       if (strchr (&adr[size - 1], '\n') != NULL)
122         {
123           puts ("strchr flunked for test of empty string at end of page");
124           result = 1;
125         }
126
127       /* strrchr test */
128       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
129         {
130           for (middle = MAX (outer, size - 64); middle < size; ++middle)
131             {
132               for (inner = middle; inner < size; ++inner)
133                 {
134                   char *cp;
135                   adr[middle] = 'V';
136                   adr[inner] = '\0';
137
138                   cp = strrchr (&adr[outer], 'V');
139
140                   if ((inner == middle && cp != NULL)
141                       || (inner != middle
142                           && (cp - &adr[outer]) != middle - outer))
143                     {
144                       printf ("strrchr flunked for outer = %d, middle = %d, "
145                               "inner = %d\n", outer, middle, inner);
146                       result = 1;
147                     }
148
149                   adr[inner] = 'T';
150                   adr[middle] = 'T';
151                 }
152             }
153         }
154
155       /* strcpy test */
156       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
157         {
158           for (inner = MAX (outer, size - 64); inner < size; ++inner)
159             {
160               adr[inner] = '\0';
161
162               if (strcpy (dest, &adr[outer]) != dest
163                   || strlen (dest) != (size_t) (inner - outer))
164                 {
165                   printf ("strcpy flunked for outer = %d, inner = %d\n",
166                           outer, inner);
167                   result = 1;
168                 }
169
170               adr[inner] = 'T';
171             }
172         }
173
174       /* stpcpy test */
175       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
176         {
177           for (inner = MAX (outer, size - 64); inner < size; ++inner)
178             {
179               adr[inner] = '\0';
180
181               if ((stpcpy (dest, &adr[outer]) - dest) != inner - outer)
182                 {
183                   printf ("stpcpy flunked for outer = %d, inner = %d\n",
184                           outer, inner);
185                   result = 1;
186                 }
187
188               adr[inner] = 'T';
189             }
190         }
191     }
192
193   return result;
194 }