1 /* Test of getcwd function.
2    Copyright (C) 2000-2022 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 <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/param.h>
25 #include <libc-diag.h>
26 
27 
28 #define TEST_FUNCTION do_test ()
29 static int
do_test(void)30 do_test (void)
31 {
32   char thepath[4096];	/* Yes, this limits the environment this test
33 			   can run it but I honestly don't care about
34 			   people which have this problem.  */
35   char *bufs[10];
36   size_t lens[10];
37   size_t sbs;
38   size_t len, i;
39 
40   if (getcwd (thepath, sizeof thepath) == NULL)
41     {
42       if (errno == ERANGE)
43 	/* The path is too long, skip all tests.  */
44 	return 0;
45 
46       puts ("getcwd (thepath, sizeof thepath) failed");
47       return 1;
48     }
49   len = strlen (thepath);
50 
51   sbs = 1;
52   while (sbs < len + 1)
53     sbs <<= 1;
54 
55   for (i = 0; i < 4; ++i)
56     {
57       lens[i] = sbs;
58       bufs[i] = (char *) malloc (sbs);
59     }
60 
61   /* Avoid warnings about the first argument being null when the second
62      is nonzero.  */
63   DIAG_PUSH_NEEDS_COMMENT;
64   DIAG_IGNORE_NEEDS_COMMENT (10.1, "-Wnonnull");
65   bufs[i] = getcwd (NULL, sbs);
66   DIAG_POP_NEEDS_COMMENT;
67 
68   lens[i] = sbs;
69   if (bufs[i] == NULL)
70     {
71       puts ("getcwd (NULL, sbs) failed");
72       return 1;
73     }
74   ++i;
75 
76   for (; i < 10; sbs >>= 1, ++i)
77     {
78       bufs[i] = (char *) malloc (MAX (1, sbs));
79       lens[i] = sbs;
80     }
81 
82   /* Before we test the result write something in the memory to see
83      whether the allocation went right.  */
84   for (i = 0; i < 10; ++i)
85     if (i != 4 && bufs[i] != NULL)
86       memset (bufs[i], '\xff', lens[i]);
87 
88   if (strcmp (thepath, bufs[4]) != 0)
89     {
90       printf ("\
91 getcwd (NULL, sbs) = \"%s\", getcwd (thepath, sizeof thepath) = \"%s\"\n",
92 	      bufs[4], thepath);
93       return 1;
94     }
95 
96   /* Now overwrite all buffers to see that getcwd allocated the buffer
97      of right size.  */
98   for (i = 0; i < 10; ++i)
99     memset (bufs[i], i, lens[i]);
100 
101   for (i = 0; i < 10; ++i)
102     free (bufs[i]);
103 
104   /* Test whether the function signals success despite the buffer
105      being too small.
106      Avoid warnings about the first argument being null when the second
107      is nonzero.  */
108   DIAG_PUSH_NEEDS_COMMENT;
109   DIAG_IGNORE_NEEDS_COMMENT (10.1, "-Wnonnull");
110   if (getcwd (NULL, len) != NULL)
111     {
112       puts ("getcwd (NULL, len) didn't failed");
113       return 1;
114     }
115   DIAG_POP_NEEDS_COMMENT;
116 
117   bufs[0] = malloc (len);
118   bufs[1] = malloc (len);
119   bufs[2] = malloc (len);
120   if (bufs[1] != NULL)
121     {
122       if (getcwd (bufs[1], len) != NULL)
123 	{
124 	  puts ("getcwd (bufs[1], len) didn't failed");
125 	  return 1;
126 	}
127       free (bufs[0]);
128       free (bufs[1]);
129       free (bufs[2]);
130     }
131 
132   memset (thepath, '\xfe', sizeof (thepath));
133   if (getcwd (thepath, len) != NULL)
134     {
135       puts ("getcwd (thepath, len) didn't failed");
136       return 1;
137     }
138 
139   for (i = len; i < sizeof thepath; ++i)
140     if (thepath[i] != '\xfe')
141       {
142 	puts ("thepath[i] != '\xfe'");
143 	return 1;
144       }
145 
146   /* Now test handling of correctly sized buffers.
147      Again. avoid warnings about the first argument being null when
148      the second is nonzero.  */
149   DIAG_PUSH_NEEDS_COMMENT;
150   DIAG_IGNORE_NEEDS_COMMENT (10.1, "-Wnonnull");
151   bufs[0] = getcwd (NULL, len + 1);
152   if (bufs[0] == NULL)
153     {
154       puts ("getcwd (NULL, len + 1) failed");
155       return 1;
156     }
157   DIAG_POP_NEEDS_COMMENT;
158   free (bufs[0]);
159 
160   memset (thepath, '\xff', sizeof thepath);
161   if (getcwd (thepath, len + 1) == NULL)
162     {
163       puts ("getcwd (thepath, len + 1) failed");
164       return 1;
165     }
166 
167   for (i = len + 1; i < sizeof thepath; ++i)
168     if (thepath[i] != '\xff')
169       {
170 	printf ("thepath[%zd] != '\xff'\n", i);
171 	return 1;
172       }
173 
174   puts ("everything OK");
175 
176   return 0;
177 }
178 
179 #include "../test-skeleton.c"
180