biome: 1.9.2 -> 1.9.3
[NixPkgs.git] / pkgs / applications / version-management / cvs / getcwd-chroot.patch
blob3f827a1e6981efaecfbc8ea8d185e2b765c3d61b
1 Fix Gnulib's getcwd in chroots.
2 From Debian bug #456164, http://bugs.debian.org/456164 .
4 --- cvs-1.12.13.orig/debian/patches/20_readdir_errno
5 +++ cvs-1.12.13/debian/patches/20_readdir_errno
6 @@ -0,0 +1,121 @@
7 +# From Gnulib:
8 +# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=0b78641d85af3b72e3b9d94cb7b94e45f3c08ee5
9 +# We don't need this directly, but it's required so that 21_getcwd_chroot
10 +# applies cleanly.
12 +# 2005-10-29 Paul Eggert <eggert@cs.ucla.edu>
14 +# * getcwd.c (__getcwd): Don't assume that system calls after readdir
15 +# leave errno alone. Problem reported by Dmitry V. Levin.
17 +--- cvs-1.12.13-old/lib/getcwd.c
18 ++++ cvs-1.12.13/lib/getcwd.c
19 +@@ -201,6 +201,8 @@ __getcwd (char *buf, size_t size)
20 + ino_t dotino;
21 + bool mount_point;
22 + int parent_status;
23 ++ size_t dirroom;
24 ++ size_t namlen;
26 + /* Look at the parent directory. */
27 + #ifdef AT_FDCWD
28 +@@ -241,11 +243,20 @@ __getcwd (char *buf, size_t size)
29 + goto lose;
30 + dotlist[dotlen++] = '/';
31 + #endif
32 +- /* Clear errno to distinguish EOF from error if readdir returns
33 +- NULL. */
34 +- __set_errno (0);
35 +- while ((d = __readdir (dirstream)) != NULL)
36 ++ for (;;)
37 + {
38 ++ /* Clear errno to distinguish EOF from error if readdir returns
39 ++ NULL. */
40 ++ __set_errno (0);
41 ++ d = __readdir (dirstream);
42 ++ if (d == NULL)
43 ++ {
44 ++ if (errno == 0)
45 ++ /* EOF on dirstream, which means that the current directory
46 ++ has been removed. */
47 ++ __set_errno (ENOENT);
48 ++ goto lose;
49 ++ }
50 + if (d->d_name[0] == '.' &&
51 + (d->d_name[1] == '\0' ||
52 + (d->d_name[1] == '.' && d->d_name[2] == '\0')))
53 +@@ -303,48 +314,38 @@ __getcwd (char *buf, size_t size)
54 + break;
55 + }
56 + }
57 +- if (d == NULL)
58 +- {
59 +- if (errno == 0)
60 +- /* EOF on dirstream, which means that the current directory
61 +- has been removed. */
62 +- __set_errno (ENOENT);
63 +- goto lose;
64 +- }
65 +- else
66 +- {
67 +- size_t dirroom = dirp - dir;
68 +- size_t namlen = _D_EXACT_NAMLEN (d);
70 +- if (dirroom <= namlen)
71 ++ dirroom = dirp - dir;
72 ++ namlen = _D_EXACT_NAMLEN (d);
74 ++ if (dirroom <= namlen)
75 ++ {
76 ++ if (size != 0)
77 + {
78 +- if (size != 0)
79 +- {
80 +- __set_errno (ERANGE);
81 +- goto lose;
82 +- }
83 +- else
84 +- {
85 +- char *tmp;
86 +- size_t oldsize = allocated;
87 ++ __set_errno (ERANGE);
88 ++ goto lose;
89 ++ }
90 ++ else
91 ++ {
92 ++ char *tmp;
93 ++ size_t oldsize = allocated;
95 +- allocated += MAX (allocated, namlen);
96 +- if (allocated < oldsize
97 +- || ! (tmp = realloc (dir, allocated)))
98 +- goto memory_exhausted;
99 ++ allocated += MAX (allocated, namlen);
100 ++ if (allocated < oldsize
101 ++ || ! (tmp = realloc (dir, allocated)))
102 ++ goto memory_exhausted;
104 +- /* Move current contents up to the end of the buffer.
105 +- This is guaranteed to be non-overlapping. */
106 +- dirp = memcpy (tmp + allocated - (oldsize - dirroom),
107 +- tmp + dirroom,
108 +- oldsize - dirroom);
109 +- dir = tmp;
110 +- }
111 ++ /* Move current contents up to the end of the buffer.
112 ++ This is guaranteed to be non-overlapping. */
113 ++ dirp = memcpy (tmp + allocated - (oldsize - dirroom),
114 ++ tmp + dirroom,
115 ++ oldsize - dirroom);
116 ++ dir = tmp;
118 +- dirp -= namlen;
119 +- memcpy (dirp, d->d_name, namlen);
120 +- *--dirp = '/';
122 ++ dirp -= namlen;
123 ++ memcpy (dirp, d->d_name, namlen);
124 ++ *--dirp = '/';
126 + thisdev = dotdev;
127 + thisino = dotino;
128 --- cvs-1.12.13.orig/debian/patches/21_getcwd_chroot
129 +++ cvs-1.12.13/debian/patches/21_getcwd_chroot
130 @@ -0,0 +1,172 @@
131 +# From Gnulib:
132 +# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=79c0a43808d9ca85acd04600149fc1a9b75bd1b9
134 +# 2006-07-03 Paul Eggert <eggert@cs.ucla.edu>
136 +# Merge from coreutils.
138 +# 2006-03-19 Jim Meyering <jim@meyering.net>
140 +# Work even in a chroot where d_ino values for entries in "/"
141 +# don't match the stat.st_ino values for the same names.
142 +# * getcwd.c (__getcwd): When no d_ino value matches the target inode
143 +# number, iterate through all entries again, using lstat instead.
144 +# Reported by Kenshi Muto in http://bugs.debian.org/355810, and by
145 +# Zouhir Hafidi in https://bugzilla.redhat.com/bugzilla/190656.
147 +# * getcwd.c (__getcwd): Clarify a comment.
148 +# Use memcpy in place of a call to strcpy.
150 +--- cvs-1.12.13-old/lib/getcwd.c
151 ++++ cvs-1.12.13/lib/getcwd.c
152 +@@ -211,6 +211,7 @@ __getcwd (char *buf, size_t size)
153 + int parent_status;
154 + size_t dirroom;
155 + size_t namlen;
156 ++ bool use_d_ino = true;
158 + /* Look at the parent directory. */
159 + #ifdef AT_FDCWD
160 +@@ -257,11 +258,26 @@ __getcwd (char *buf, size_t size)
161 + NULL. */
162 + __set_errno (0);
163 + d = __readdir (dirstream);
165 ++ /* When we've iterated through all directory entries without finding
166 ++ one with a matching d_ino, rewind the stream and consider each
167 ++ name again, but this time, using lstat. This is necessary in a
168 ++ chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where
169 ++ .., ../.., ../../.., etc. all had the same device number, yet the
170 ++ d_ino values for entries in / did not match those obtained
171 ++ via lstat. */
172 ++ if (d == NULL && errno == 0 && use_d_ino)
173 ++ {
174 ++ use_d_ino = false;
175 ++ rewinddir (dirstream);
176 ++ d = __readdir (dirstream);
177 ++ }
179 + if (d == NULL)
181 + if (errno == 0)
182 +- /* EOF on dirstream, which means that the current directory
183 +- has been removed. */
184 ++ /* EOF on dirstream, which can mean e.g., that the current
185 ++ directory has been removed. */
186 + __set_errno (ENOENT);
187 + goto lose;
189 +@@ -269,58 +285,65 @@ __getcwd (char *buf, size_t size)
190 + (d->d_name[1] == '\0' ||
191 + (d->d_name[1] == '.' && d->d_name[2] == '\0')))
192 + continue;
193 +- if (MATCHING_INO (d, thisino) || mount_point)
195 ++ if (use_d_ino)
197 +- int entry_status;
198 ++ bool match = (MATCHING_INO (d, thisino) || mount_point);
199 ++ if (! match)
200 ++ continue;
201 ++ }
203 ++ {
204 ++ int entry_status;
205 + #ifdef AT_FDCWD
206 +- entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
207 ++ entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
208 + #else
209 +- /* Compute size needed for this file name, or for the file
210 +- name ".." in the same directory, whichever is larger.
211 +- Room for ".." might be needed the next time through
212 +- the outer loop. */
213 +- size_t name_alloc = _D_ALLOC_NAMLEN (d);
214 +- size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
216 +- if (filesize < dotlen)
217 +- goto memory_exhausted;
219 +- if (dotsize < filesize)
220 +- {
221 +- /* My, what a deep directory tree you have, Grandma. */
222 +- size_t newsize = MAX (filesize, dotsize * 2);
223 +- size_t i;
224 +- if (newsize < dotsize)
225 +- goto memory_exhausted;
226 +- if (dotlist != dots)
227 +- free (dotlist);
228 +- dotlist = malloc (newsize);
229 +- if (dotlist == NULL)
230 +- goto lose;
231 +- dotsize = newsize;
233 +- i = 0;
234 +- do
235 +- {
236 +- dotlist[i++] = '.';
237 +- dotlist[i++] = '.';
238 +- dotlist[i++] = '/';
239 +- }
240 +- while (i < dotlen);
241 +- }
243 +- strcpy (dotlist + dotlen, d->d_name);
244 +- entry_status = __lstat (dotlist, &st);
245 ++ /* Compute size needed for this file name, or for the file
246 ++ name ".." in the same directory, whichever is larger.
247 ++ Room for ".." might be needed the next time through
248 ++ the outer loop. */
249 ++ size_t name_alloc = _D_ALLOC_NAMLEN (d);
250 ++ size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
252 ++ if (filesize < dotlen)
253 ++ goto memory_exhausted;
255 ++ if (dotsize < filesize)
256 ++ {
257 ++ /* My, what a deep directory tree you have, Grandma. */
258 ++ size_t newsize = MAX (filesize, dotsize * 2);
259 ++ size_t i;
260 ++ if (newsize < dotsize)
261 ++ goto memory_exhausted;
262 ++ if (dotlist != dots)
263 ++ free (dotlist);
264 ++ dotlist = malloc (newsize);
265 ++ if (dotlist == NULL)
266 ++ goto lose;
267 ++ dotsize = newsize;
269 ++ i = 0;
270 ++ do
271 ++ {
272 ++ dotlist[i++] = '.';
273 ++ dotlist[i++] = '.';
274 ++ dotlist[i++] = '/';
275 ++ }
276 ++ while (i < dotlen);
277 ++ }
279 ++ memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
280 ++ entry_status = __lstat (dotlist, &st);
281 + #endif
282 +- /* We don't fail here if we cannot stat() a directory entry.
283 +- This can happen when (network) file systems fail. If this
284 +- entry is in fact the one we are looking for we will find
285 +- out soon as we reach the end of the directory without
286 +- having found anything. */
287 +- if (entry_status == 0 && S_ISDIR (st.st_mode)
288 +- && st.st_dev == thisdev && st.st_ino == thisino)
289 +- break;
290 +- }
291 ++ /* We don't fail here if we cannot stat() a directory entry.
292 ++ This can happen when (network) file systems fail. If this
293 ++ entry is in fact the one we are looking for we will find
294 ++ out soon as we reach the end of the directory without
295 ++ having found anything. */
296 ++ if (entry_status == 0 && S_ISDIR (st.st_mode)
297 ++ && st.st_dev == thisdev && st.st_ino == thisino)
298 ++ break;
299 ++ }
302 + dirroom = dirp - dir;