aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDaniel Colascione2019-06-23 18:19:08 -0700
committerDaniel Colascione2019-06-23 18:19:08 -0700
commitb9ac4f815ebaa1acb0d045fe9583f665efa6f628 (patch)
treef2bfcf685bb9f83a67c5f70fe8e4f65ef16d8690 /lib
parentf3b1b5fb5034de026adc41cf2403cff42f4a0b67 (diff)
downloademacs-b9ac4f815ebaa1acb0d045fe9583f665efa6f628.tar.gz
emacs-b9ac4f815ebaa1acb0d045fe9583f665efa6f628.zip
Fix locating pdump by symlink
* admin/merge-gnulib (GNULIB_MODULES): Add canonicalize-lgpl module * build-aux/config.guess, build-aux/gitlog-to-changelog, build-aux/update-copyright, lib/canonicalize-lgpl.c, lib/gnulib.mk.in, lib/malloca.c, lib/malloca.h, lib/pathmax.h, m4/canonicalize.m4, m4/double-slash-root.m4, m4/gnulib-comp.m4, m4/malloca.m4, my/pathmax.4: copy from GNUlib or regenerate from update * src/emacs.c: find dump by canonical path
Diffstat (limited to 'lib')
-rw-r--r--lib/canonicalize-lgpl.c428
-rw-r--r--lib/gnulib.mk.in38
-rw-r--r--lib/malloca.c105
-rw-r--r--lib/malloca.h127
-rw-r--r--lib/pathmax.h83
5 files changed, 781 insertions, 0 deletions
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
new file mode 100644
index 00000000000..4d1be6dc24b
--- /dev/null
+++ b/lib/canonicalize-lgpl.c
@@ -0,0 +1,428 @@
1/* Return the canonical absolute name of a given file.
2 Copyright (C) 1996-2019 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18#ifndef _LIBC
19/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
20 optimizes away the name == NULL test below. */
21# define _GL_ARG_NONNULL(params)
22
23# define _GL_USE_STDLIB_ALLOC 1
24# include <config.h>
25#endif
26
27#if !HAVE_CANONICALIZE_FILE_NAME || !FUNC_REALPATH_WORKS || defined _LIBC
28
29/* Specification. */
30#include <stdlib.h>
31
32#include <alloca.h>
33#include <string.h>
34#include <unistd.h>
35#include <limits.h>
36#if HAVE_SYS_PARAM_H || defined _LIBC
37# include <sys/param.h>
38#endif
39#include <sys/stat.h>
40#include <errno.h>
41#include <stddef.h>
42
43#ifdef _LIBC
44# include <shlib-compat.h>
45#else
46# define SHLIB_COMPAT(lib, introduced, obsoleted) 0
47# define versioned_symbol(lib, local, symbol, version) extern int dummy
48# define compat_symbol(lib, local, symbol, version)
49# define weak_alias(local, symbol)
50# define __canonicalize_file_name canonicalize_file_name
51# define __realpath realpath
52# include "pathmax.h"
53# include "malloca.h"
54# include "dosname.h"
55# if HAVE_GETCWD
56# if IN_RELOCWRAPPER
57 /* When building the relocatable program wrapper, use the system's getcwd
58 function, not the gnulib override, otherwise we would get a link error.
59 */
60# undef getcwd
61# endif
62# if defined VMS && !defined getcwd
63 /* We want the directory in Unix syntax, not in VMS syntax.
64 The gnulib override of 'getcwd' takes 2 arguments; the original VMS
65 'getcwd' takes 3 arguments. */
66# define __getcwd(buf, max) getcwd (buf, max, 0)
67# else
68# define __getcwd getcwd
69# endif
70# else
71# define __getcwd(buf, max) getwd (buf)
72# endif
73# define __readlink readlink
74# define __set_errno(e) errno = (e)
75# ifndef MAXSYMLINKS
76# ifdef SYMLOOP_MAX
77# define MAXSYMLINKS SYMLOOP_MAX
78# else
79# define MAXSYMLINKS 20
80# endif
81# endif
82#endif
83
84#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
85# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
86#endif
87
88/* Define this independently so that stdint.h is not a prerequisite. */
89#ifndef SIZE_MAX
90# define SIZE_MAX ((size_t) -1)
91#endif
92
93#if !FUNC_REALPATH_WORKS || defined _LIBC
94
95static void
96alloc_failed (void)
97{
98#if defined _WIN32 && ! defined __CYGWIN__
99 /* Avoid errno problem without using the malloc or realloc modules; see:
100 https://lists.gnu.org/r/bug-gnulib/2016-08/msg00025.html */
101 errno = ENOMEM;
102#endif
103}
104
105/* Return the canonical absolute name of file NAME. A canonical name
106 does not contain any ".", ".." components nor any repeated path
107 separators ('/') or symlinks. All path components must exist. If
108 RESOLVED is null, the result is malloc'd; otherwise, if the
109 canonical name is PATH_MAX chars or more, returns null with 'errno'
110 set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
111 returns the name in RESOLVED. If the name cannot be resolved and
112 RESOLVED is non-NULL, it contains the path of the first component
113 that cannot be resolved. If the path can be resolved, RESOLVED
114 holds the same value as the value returned. */
115
116char *
117__realpath (const char *name, char *resolved)
118{
119 char *rpath, *dest, *extra_buf = NULL;
120 const char *start, *end, *rpath_limit;
121 long int path_max;
122 int num_links = 0;
123 size_t prefix_len;
124
125 if (name == NULL)
126 {
127 /* As per Single Unix Specification V2 we must return an error if
128 either parameter is a null pointer. We extend this to allow
129 the RESOLVED parameter to be NULL in case the we are expected to
130 allocate the room for the return value. */
131 __set_errno (EINVAL);
132 return NULL;
133 }
134
135 if (name[0] == '\0')
136 {
137 /* As per Single Unix Specification V2 we must return an error if
138 the name argument points to an empty string. */
139 __set_errno (ENOENT);
140 return NULL;
141 }
142
143#ifdef PATH_MAX
144 path_max = PATH_MAX;
145#else
146 path_max = pathconf (name, _PC_PATH_MAX);
147 if (path_max <= 0)
148 path_max = 8192;
149#endif
150
151 if (resolved == NULL)
152 {
153 rpath = malloc (path_max);
154 if (rpath == NULL)
155 {
156 alloc_failed ();
157 return NULL;
158 }
159 }
160 else
161 rpath = resolved;
162 rpath_limit = rpath + path_max;
163
164 /* This is always zero for Posix hosts, but can be 2 for MS-Windows
165 and MS-DOS X:/foo/bar file names. */
166 prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
167
168 if (!IS_ABSOLUTE_FILE_NAME (name))
169 {
170 if (!__getcwd (rpath, path_max))
171 {
172 rpath[0] = '\0';
173 goto error;
174 }
175 dest = strchr (rpath, '\0');
176 start = name;
177 prefix_len = FILE_SYSTEM_PREFIX_LEN (rpath);
178 }
179 else
180 {
181 dest = rpath;
182 if (prefix_len)
183 {
184 memcpy (rpath, name, prefix_len);
185 dest += prefix_len;
186 }
187 *dest++ = '/';
188 if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
189 {
190 if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
191 *dest++ = '/';
192 *dest = '\0';
193 }
194 start = name + prefix_len;
195 }
196
197 for (end = start; *start; start = end)
198 {
199#ifdef _LIBC
200 struct stat64 st;
201#else
202 struct stat st;
203#endif
204
205 /* Skip sequence of multiple path-separators. */
206 while (ISSLASH (*start))
207 ++start;
208
209 /* Find end of path component. */
210 for (end = start; *end && !ISSLASH (*end); ++end)
211 /* Nothing. */;
212
213 if (end - start == 0)
214 break;
215 else if (end - start == 1 && start[0] == '.')
216 /* nothing */;
217 else if (end - start == 2 && start[0] == '.' && start[1] == '.')
218 {
219 /* Back up to previous component, ignore if at root already. */
220 if (dest > rpath + prefix_len + 1)
221 for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
222 continue;
223 if (DOUBLE_SLASH_IS_DISTINCT_ROOT
224 && dest == rpath + 1 && !prefix_len
225 && ISSLASH (*dest) && !ISSLASH (dest[1]))
226 dest++;
227 }
228 else
229 {
230 size_t new_size;
231
232 if (!ISSLASH (dest[-1]))
233 *dest++ = '/';
234
235 if (dest + (end - start) >= rpath_limit)
236 {
237 ptrdiff_t dest_offset = dest - rpath;
238 char *new_rpath;
239
240 if (resolved)
241 {
242 __set_errno (ENAMETOOLONG);
243 if (dest > rpath + prefix_len + 1)
244 dest--;
245 *dest = '\0';
246 goto error;
247 }
248 new_size = rpath_limit - rpath;
249 if (end - start + 1 > path_max)
250 new_size += end - start + 1;
251 else
252 new_size += path_max;
253 new_rpath = (char *) realloc (rpath, new_size);
254 if (new_rpath == NULL)
255 {
256 alloc_failed ();
257 goto error;
258 }
259 rpath = new_rpath;
260 rpath_limit = rpath + new_size;
261
262 dest = rpath + dest_offset;
263 }
264
265#ifdef _LIBC
266 dest = __mempcpy (dest, start, end - start);
267#else
268 memcpy (dest, start, end - start);
269 dest += end - start;
270#endif
271 *dest = '\0';
272
273 /* FIXME: if lstat fails with errno == EOVERFLOW,
274 the entry exists. */
275#ifdef _LIBC
276 if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
277#else
278 if (lstat (rpath, &st) < 0)
279#endif
280 goto error;
281
282 if (S_ISLNK (st.st_mode))
283 {
284 char *buf;
285 size_t len;
286 ssize_t n;
287
288 if (++num_links > MAXSYMLINKS)
289 {
290 __set_errno (ELOOP);
291 goto error;
292 }
293
294 buf = malloca (path_max);
295 if (!buf)
296 {
297 __set_errno (ENOMEM);
298 goto error;
299 }
300
301 n = __readlink (rpath, buf, path_max - 1);
302 if (n < 0)
303 {
304 int saved_errno = errno;
305 freea (buf);
306 __set_errno (saved_errno);
307 goto error;
308 }
309 buf[n] = '\0';
310
311 if (!extra_buf)
312 {
313 extra_buf = malloca (path_max);
314 if (!extra_buf)
315 {
316 freea (buf);
317 __set_errno (ENOMEM);
318 goto error;
319 }
320 }
321
322 len = strlen (end);
323 /* Check that n + len + 1 doesn't overflow and is <= path_max. */
324 if (n >= SIZE_MAX - len || n + len >= path_max)
325 {
326 freea (buf);
327 __set_errno (ENAMETOOLONG);
328 goto error;
329 }
330
331 /* Careful here, end may be a pointer into extra_buf... */
332 memmove (&extra_buf[n], end, len + 1);
333 name = end = memcpy (extra_buf, buf, n);
334
335 if (IS_ABSOLUTE_FILE_NAME (buf))
336 {
337 size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
338
339 if (pfxlen)
340 memcpy (rpath, buf, pfxlen);
341 dest = rpath + pfxlen;
342 *dest++ = '/'; /* It's an absolute symlink */
343 if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
344 {
345 if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
346 *dest++ = '/';
347 *dest = '\0';
348 }
349 /* Install the new prefix to be in effect hereafter. */
350 prefix_len = pfxlen;
351 }
352 else
353 {
354 /* Back up to previous component, ignore if at root
355 already: */
356 if (dest > rpath + prefix_len + 1)
357 for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
358 continue;
359 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
360 && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
361 dest++;
362 }
363 }
364 else if (!S_ISDIR (st.st_mode) && *end != '\0')
365 {
366 __set_errno (ENOTDIR);
367 goto error;
368 }
369 }
370 }
371 if (dest > rpath + prefix_len + 1 && ISSLASH (dest[-1]))
372 --dest;
373 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && !prefix_len
374 && ISSLASH (*dest) && !ISSLASH (dest[1]))
375 dest++;
376 *dest = '\0';
377
378 if (extra_buf)
379 freea (extra_buf);
380
381 return rpath;
382
383error:
384 {
385 int saved_errno = errno;
386 if (extra_buf)
387 freea (extra_buf);
388 if (resolved == NULL)
389 free (rpath);
390 __set_errno (saved_errno);
391 }
392 return NULL;
393}
394versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
395#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
396
397
398#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
399char *
400attribute_compat_text_section
401__old_realpath (const char *name, char *resolved)
402{
403 if (resolved == NULL)
404 {
405 __set_errno (EINVAL);
406 return NULL;
407 }
408
409 return __realpath (name, resolved);
410}
411compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0);
412#endif
413
414
415char *
416__canonicalize_file_name (const char *name)
417{
418 return __realpath (name, NULL);
419}
420weak_alias (__canonicalize_file_name, canonicalize_file_name)
421
422#else
423
424/* This declaration is solely to ensure that after preprocessing
425 this file is never empty. */
426typedef int dummy;
427
428#endif
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 6e817fa6897..d0bef0bd5de 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -72,6 +72,7 @@
72# byteswap \ 72# byteswap \
73# c-ctype \ 73# c-ctype \
74# c-strcase \ 74# c-strcase \
75# canonicalize-lgpl \
75# careadlinkat \ 76# careadlinkat \
76# close-stream \ 77# close-stream \
77# copy-file-range \ 78# copy-file-range \
@@ -484,6 +485,8 @@ GTK_CFLAGS = @GTK_CFLAGS@
484GTK_LIBS = @GTK_LIBS@ 485GTK_LIBS = @GTK_LIBS@
485GTK_OBJ = @GTK_OBJ@ 486GTK_OBJ = @GTK_OBJ@
486GZIP_PROG = @GZIP_PROG@ 487GZIP_PROG = @GZIP_PROG@
488HARFBUZZ_CFLAGS = @HARFBUZZ_CFLAGS@
489HARFBUZZ_LIBS = @HARFBUZZ_LIBS@
487HAVE_ALLOCA_H = @HAVE_ALLOCA_H@ 490HAVE_ALLOCA_H = @HAVE_ALLOCA_H@
488HAVE_ALPHASORT = @HAVE_ALPHASORT@ 491HAVE_ALPHASORT = @HAVE_ALPHASORT@
489HAVE_ATOLL = @HAVE_ATOLL@ 492HAVE_ATOLL = @HAVE_ATOLL@
@@ -1105,6 +1108,7 @@ pdfdir = @pdfdir@
1105prefix = @prefix@ 1108prefix = @prefix@
1106program_transform_name = @program_transform_name@ 1109program_transform_name = @program_transform_name@
1107psdir = @psdir@ 1110psdir = @psdir@
1111runstatedir = @runstatedir@
1108sbindir = @sbindir@ 1112sbindir = @sbindir@
1109sharedstatedir = @sharedstatedir@ 1113sharedstatedir = @sharedstatedir@
1110srcdir = @srcdir@ 1114srcdir = @srcdir@
@@ -1243,6 +1247,17 @@ libgnu_a_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c
1243endif 1247endif
1244## end gnulib module c-strcase 1248## end gnulib module c-strcase
1245 1249
1250## begin gnulib module canonicalize-lgpl
1251ifeq (,$(OMIT_GNULIB_MODULE_canonicalize-lgpl))
1252
1253
1254EXTRA_DIST += canonicalize-lgpl.c
1255
1256EXTRA_libgnu_a_SOURCES += canonicalize-lgpl.c
1257
1258endif
1259## end gnulib module canonicalize-lgpl
1260
1246## begin gnulib module careadlinkat 1261## begin gnulib module careadlinkat
1247ifeq (,$(OMIT_GNULIB_MODULE_careadlinkat)) 1262ifeq (,$(OMIT_GNULIB_MODULE_careadlinkat))
1248 1263
@@ -1980,6 +1995,18 @@ EXTRA_libgnu_a_SOURCES += lstat.c
1980endif 1995endif
1981## end gnulib module lstat 1996## end gnulib module lstat
1982 1997
1998## begin gnulib module malloca
1999ifeq (,$(OMIT_GNULIB_MODULE_malloca))
2000
2001ifneq (,$(gl_GNULIB_ENABLED_malloca))
2002libgnu_a_SOURCES += malloca.c
2003
2004endif
2005EXTRA_DIST += malloca.h
2006
2007endif
2008## end gnulib module malloca
2009
1983## begin gnulib module memmem-simple 2010## begin gnulib module memmem-simple
1984ifeq (,$(OMIT_GNULIB_MODULE_memmem-simple)) 2011ifeq (,$(OMIT_GNULIB_MODULE_memmem-simple))
1985 2012
@@ -2079,6 +2106,17 @@ EXTRA_DIST += openat.h
2079endif 2106endif
2080## end gnulib module openat-h 2107## end gnulib module openat-h
2081 2108
2109## begin gnulib module pathmax
2110ifeq (,$(OMIT_GNULIB_MODULE_pathmax))
2111
2112ifneq (,$(gl_GNULIB_ENABLED_pathmax))
2113
2114endif
2115EXTRA_DIST += pathmax.h
2116
2117endif
2118## end gnulib module pathmax
2119
2082## begin gnulib module pipe2 2120## begin gnulib module pipe2
2083ifeq (,$(OMIT_GNULIB_MODULE_pipe2)) 2121ifeq (,$(OMIT_GNULIB_MODULE_pipe2))
2084 2122
diff --git a/lib/malloca.c b/lib/malloca.c
new file mode 100644
index 00000000000..f60c5fb5d93
--- /dev/null
+++ b/lib/malloca.c
@@ -0,0 +1,105 @@
1/* Safe automatic memory allocation.
2 Copyright (C) 2003, 2006-2007, 2009-2019 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2003, 2018.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 This program 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
17
18#define _GL_USE_STDLIB_ALLOC 1
19#include <config.h>
20
21/* Specification. */
22#include "malloca.h"
23
24#include "verify.h"
25
26/* The speed critical point in this file is freea() applied to an alloca()
27 result: it must be fast, to match the speed of alloca(). The speed of
28 mmalloca() and freea() in the other case are not critical, because they
29 are only invoked for big memory sizes.
30 Here we use a bit in the address as an indicator, an idea by Ondřej Bílka.
31 malloca() can return three types of pointers:
32 - Pointers ≡ 0 mod 2*sa_alignment_max come from stack allocation.
33 - Pointers ≡ sa_alignment_max mod 2*sa_alignment_max come from heap
34 allocation.
35 - NULL comes from a failed heap allocation. */
36
37/* Type for holding very small pointer differences. */
38typedef unsigned char small_t;
39/* Verify that it is wide enough. */
40verify (2 * sa_alignment_max - 1 <= (small_t) -1);
41
42void *
43mmalloca (size_t n)
44{
45#if HAVE_ALLOCA
46 /* Allocate one more word, used to determine the address to pass to freea(),
47 and room for the alignment ≡ sa_alignment_max mod 2*sa_alignment_max. */
48 size_t nplus = n + sizeof (small_t) + 2 * sa_alignment_max - 1;
49
50 if (nplus >= n)
51 {
52 char *mem = (char *) malloc (nplus);
53
54 if (mem != NULL)
55 {
56 char *p =
57 (char *)((((uintptr_t)mem + sizeof (small_t) + sa_alignment_max - 1)
58 & ~(uintptr_t)(2 * sa_alignment_max - 1))
59 + sa_alignment_max);
60 /* Here p >= mem + sizeof (small_t),
61 and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1
62 hence p + n <= mem + nplus.
63 So, the memory range [p, p+n) lies in the allocated memory range
64 [mem, mem + nplus). */
65 ((small_t *) p)[-1] = p - mem;
66 /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */
67 return p;
68 }
69 }
70 /* Out of memory. */
71 return NULL;
72#else
73# if !MALLOC_0_IS_NONNULL
74 if (n == 0)
75 n = 1;
76# endif
77 return malloc (n);
78#endif
79}
80
81#if HAVE_ALLOCA
82void
83freea (void *p)
84{
85 /* Check argument. */
86 if ((uintptr_t) p & (sa_alignment_max - 1))
87 {
88 /* p was not the result of a malloca() call. Invalid argument. */
89 abort ();
90 }
91 /* Determine whether p was a non-NULL pointer returned by mmalloca(). */
92 if ((uintptr_t) p & sa_alignment_max)
93 {
94 void *mem = (char *) p - ((small_t *) p)[-1];
95 free (mem);
96 }
97}
98#endif
99
100/*
101 * Hey Emacs!
102 * Local Variables:
103 * coding: utf-8
104 * End:
105 */
diff --git a/lib/malloca.h b/lib/malloca.h
new file mode 100644
index 00000000000..d80c316caa9
--- /dev/null
+++ b/lib/malloca.h
@@ -0,0 +1,127 @@
1/* Safe automatic memory allocation.
2 Copyright (C) 2003-2007, 2009-2019 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 This program 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
17
18#ifndef _MALLOCA_H
19#define _MALLOCA_H
20
21#include <alloca.h>
22#include <stddef.h>
23#include <stdlib.h>
24#include <stdint.h>
25
26#include "xalloc-oversized.h"
27
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33
34/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
35 alloca(N); otherwise it returns NULL. It either returns N bytes of
36 memory allocated on the stack, that lasts until the function returns,
37 or NULL.
38 Use of safe_alloca should be avoided:
39 - inside arguments of function calls - undefined behaviour,
40 - in inline functions - the allocation may actually last until the
41 calling function returns.
42*/
43#if HAVE_ALLOCA
44/* The OS usually guarantees only one guard page at the bottom of the stack,
45 and a page size can be as small as 4096 bytes. So we cannot safely
46 allocate anything larger than 4096 bytes. Also care for the possibility
47 of a few compiler-allocated temporary stack slots.
48 This must be a macro, not a function. */
49# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
50#else
51# define safe_alloca(N) ((void) (N), NULL)
52#endif
53
54/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of
55 memory allocated on the stack, that must be freed using freea() before
56 the function returns. Upon failure, it returns NULL. */
57#if HAVE_ALLOCA
58# define malloca(N) \
59 ((N) < 4032 - (2 * sa_alignment_max - 1) \
60 ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \
61 + (2 * sa_alignment_max - 1)) \
62 & ~(uintptr_t)(2 * sa_alignment_max - 1)) \
63 : mmalloca (N))
64#else
65# define malloca(N) \
66 mmalloca (N)
67#endif
68extern void * mmalloca (size_t n);
69
70/* Free a block of memory allocated through malloca(). */
71#if HAVE_ALLOCA
72extern void freea (void *p);
73#else
74# define freea free
75#endif
76
77/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S).
78 It allocates an array of N objects, each with S bytes of memory,
79 on the stack. S must be positive and N must be nonnegative.
80 The array must be freed using freea() before the function returns. */
81#define nmalloca(n, s) (xalloc_oversized (n, s) ? NULL : malloca ((n) * (s)))
82
83
84#ifdef __cplusplus
85}
86#endif
87
88
89/* ------------------- Auxiliary, non-public definitions ------------------- */
90
91/* Determine the alignment of a type at compile time. */
92#if defined __GNUC__ || defined __IBM__ALIGNOF__
93# define sa_alignof __alignof__
94#elif defined __cplusplus
95 template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
96# define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
97#elif defined __hpux
98 /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
99 values. */
100# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
101#elif defined _AIX
102 /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof
103 values. */
104# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
105#else
106# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
107#endif
108
109enum
110{
111/* The desired alignment of memory allocations is the maximum alignment
112 among all elementary types. */
113 sa_alignment_long = sa_alignof (long),
114 sa_alignment_double = sa_alignof (double),
115#if HAVE_LONG_LONG_INT
116 sa_alignment_longlong = sa_alignof (long long),
117#endif
118 sa_alignment_longdouble = sa_alignof (long double),
119 sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
120#if HAVE_LONG_LONG_INT
121 | (sa_alignment_longlong - 1)
122#endif
123 | (sa_alignment_longdouble - 1)
124 ) + 1
125};
126
127#endif /* _MALLOCA_H */
diff --git a/lib/pathmax.h b/lib/pathmax.h
new file mode 100644
index 00000000000..9463a1fb2c6
--- /dev/null
+++ b/lib/pathmax.h
@@ -0,0 +1,83 @@
1/* Define PATH_MAX somehow. Requires sys/types.h.
2 Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2019 Free Software
3 Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 This program 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
17
18#ifndef _PATHMAX_H
19# define _PATHMAX_H
20
21/* POSIX:2008 defines PATH_MAX to be the maximum number of bytes in a filename,
22 including the terminating NUL byte.
23 <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html>
24 PATH_MAX is not defined on systems which have no limit on filename length,
25 such as GNU/Hurd.
26
27 This file does *not* define PATH_MAX always. Programs that use this file
28 can handle the GNU/Hurd case in several ways:
29 - Either with a package-wide handling, or with a per-file handling,
30 - Either through a
31 #ifdef PATH_MAX
32 or through a fallback like
33 #ifndef PATH_MAX
34 # define PATH_MAX 8192
35 #endif
36 or through a fallback like
37 #ifndef PATH_MAX
38 # define PATH_MAX pathconf ("/", _PC_PATH_MAX)
39 #endif
40 */
41
42# include <unistd.h>
43
44# include <limits.h>
45
46# ifndef _POSIX_PATH_MAX
47# define _POSIX_PATH_MAX 256
48# endif
49
50/* Don't include sys/param.h if it already has been. */
51# if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
52# include <sys/param.h>
53# endif
54
55# if !defined PATH_MAX && defined MAXPATHLEN
56# define PATH_MAX MAXPATHLEN
57# endif
58
59# ifdef __hpux
60/* On HP-UX, PATH_MAX designates the maximum number of bytes in a filename,
61 *not* including the terminating NUL byte, and is set to 1023.
62 Additionally, when _XOPEN_SOURCE is defined to 500 or more, PATH_MAX is
63 not defined at all any more. */
64# undef PATH_MAX
65# define PATH_MAX 1024
66# endif
67
68# if defined _WIN32 && ! defined __CYGWIN__
69/* The page "Naming Files, Paths, and Namespaces" on msdn.microsoft.com,
70 section "Maximum Path Length Limitation",
71 <https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation>
72 explains that the maximum size of a filename, including the terminating
73 NUL byte, is 260 = 3 + 256 + 1.
74 This is the same value as
75 - FILENAME_MAX in <stdio.h>,
76 - _MAX_PATH in <stdlib.h>,
77 - MAX_PATH in <windef.h>.
78 Undefine the original value, because mingw's <limits.h> gets it wrong. */
79# undef PATH_MAX
80# define PATH_MAX 260
81# endif
82
83#endif /* _PATHMAX_H */