* [PATCH v2 1/6] Import idx.h from gnulib
@ 2020-12-28 13:59 Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 2/6] Import filename.h " Adhemerval Zanella
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Adhemerval Zanella @ 2020-12-28 13:59 UTC (permalink / raw)
To: libc-alpha, Paul Eggert; +Cc: bug-gnulib
Changes from previous version:
- Change idx.h comment to LGPLv2.1+.
--
And use to simplify stdlib/canonicalize.c implementation.
---
include/idx.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
create mode 100644 include/idx.h
diff --git a/include/idx.h b/include/idx.h
new file mode 100644
index 0000000000..024b44ae98
--- /dev/null
+++ b/include/idx.h
@@ -0,0 +1,114 @@
+/* A type for indices and sizes.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _IDX_H
+#define _IDX_H
+
+/* Get ptrdiff_t. */
+#include <stddef.h>
+
+/* Get PTRDIFF_MAX. */
+#include <stdint.h>
+
+/* The type 'idx_t' holds an (array) index or an (object) size.
+ Its implementation promotes to a signed integer type,
+ which can hold the values
+ 0..2^63-1 (on 64-bit platforms) or
+ 0..2^31-1 (on 32-bit platforms).
+
+ Why a signed integer type?
+
+ * Security: Signed types can be checked for overflow via
+ '-fsanitize=undefined', but unsigned types cannot.
+
+ * Comparisons without surprises: ISO C99 § 6.3.1.8 specifies a few
+ surprising results for comparisons, such as
+
+ (int) -3 < (unsigned long) 7 => false
+ (int) -3 < (unsigned int) 7 => false
+ and on 32-bit machines:
+ (long) -3 < (unsigned int) 7 => false
+
+ This is surprising because the natural comparison order is by
+ value in the realm of infinite-precision signed integers (ℤ).
+
+ The best way to get rid of such surprises is to use signed types
+ for numerical integer values, and use unsigned types only for
+ bit masks and enums.
+
+ Why not use 'size_t' directly?
+
+ * Because 'size_t' is an unsigned type, and a signed type is better.
+ See above.
+
+ Why not use 'ptrdiff_t' directly?
+
+ * Maintainability: When reading and modifying code, it helps to know that
+ a certain variable cannot have negative values. For example, when you
+ have a loop
+
+ int n = ...;
+ for (int i = 0; i < n; i++) ...
+
+ or
+
+ ptrdiff_t n = ...;
+ for (ptrdiff_t i = 0; i < n; i++) ...
+
+ you have to ask yourself "what if n < 0?". Whereas in
+
+ idx_t n = ...;
+ for (idx_t i = 0; i < n; i++) ...
+
+ you know that this case cannot happen.
+
+ Similarly, when a programmer writes
+
+ idx_t = ptr2 - ptr1;
+
+ there is an implied assertion that ptr1 and ptr2 point into the same
+ object and that ptr1 <= ptr2.
+
+ * Being future-proof: In the future, range types (integers which are
+ constrained to a certain range of values) may be added to C compilers
+ or to the C standard. Several programming languages (Ada, Haskell,
+ Common Lisp, Pascal) already have range types. Such range types may
+ help producing good code and good warnings. The type 'idx_t' could
+ then be typedef'ed to a range type that is signed after promotion. */
+
+/* In the future, idx_t could be typedef'ed to a signed range type.
+ The clang "extended integer types", supported in Clang 11 or newer
+ <https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types>,
+ are a special case of range types. However, these types don't support binary
+ operators with plain integer types (e.g. expressions such as x > 1).
+ Therefore, they don't behave like signed types (and not like unsigned types
+ either). So, we cannot use them here. */
+
+/* Use the signed type 'ptrdiff_t'. */
+/* Note: ISO C does not mandate that 'size_t' and 'ptrdiff_t' have the same
+ size, but it is so on all platforms we have seen since 1990. */
+typedef ptrdiff_t idx_t;
+
+/* IDX_MAX is the maximum value of an idx_t. */
+#define IDX_MAX PTRDIFF_MAX
+
+/* So far no need has been found for an IDX_WIDTH macro.
+ Perhaps there should be another macro IDX_VALUE_BITS that does not
+ count the sign bit and is therefore one less than PTRDIFF_WIDTH. */
+
+#endif /* _IDX_H */
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/6] Import filename.h from gnulib
2020-12-28 13:59 [PATCH v2 1/6] Import idx.h from gnulib Adhemerval Zanella
@ 2020-12-28 13:59 ` Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 3/6] malloc: Add scratch_buffer_dupfree Adhemerval Zanella
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Adhemerval Zanella @ 2020-12-28 13:59 UTC (permalink / raw)
To: libc-alpha, Paul Eggert; +Cc: bug-gnulib
And use to simplify stdlib/canonicalize.c implementation.
---
include/filename.h | 110 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
create mode 100644 include/filename.h
diff --git a/include/filename.h b/include/filename.h
new file mode 100644
index 0000000000..4598fb1d63
--- /dev/null
+++ b/include/filename.h
@@ -0,0 +1,110 @@
+/* Basic filename support macros.
+ Copyright (C) 2001-2004, 2007-2020 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* From Paul Eggert and Jim Meyering. */
+
+#ifndef _FILENAME_H
+#define _FILENAME_H
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Filename support.
+ ISSLASH(C) tests whether C is a directory separator
+ character.
+ HAS_DEVICE(Filename) tests whether Filename contains a device
+ specification.
+ FILE_SYSTEM_PREFIX_LEN(Filename) length of the device specification
+ at the beginning of Filename,
+ index of the part consisting of
+ alternating components and slashes.
+ FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+ 1 when a non-empty device specification
+ can be followed by an empty or relative
+ part,
+ 0 when a non-empty device specification
+ must be followed by a slash,
+ 0 when device specification don't exist.
+ IS_ABSOLUTE_FILE_NAME(Filename)
+ tests whether Filename is independent of
+ any notion of "current directory".
+ IS_RELATIVE_FILE_NAME(Filename)
+ tests whether Filename may be concatenated
+ to a directory filename.
+ Note: On native Windows, OS/2, DOS, "c:" is neither an absolute nor a
+ relative file name!
+ IS_FILE_NAME_WITH_DIR(Filename) tests whether Filename contains a device
+ or directory specification.
+ */
+#if defined _WIN32 || defined __CYGWIN__ \
+ || defined __EMX__ || defined __MSDOS__ || defined __DJGPP__
+ /* Native Windows, Cygwin, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+ /* Internal macro: Tests whether a character is a drive letter. */
+# define _IS_DRIVE_LETTER(C) \
+ (((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z'))
+ /* Help the compiler optimizing it. This assumes ASCII. */
+# undef _IS_DRIVE_LETTER
+# define _IS_DRIVE_LETTER(C) \
+ (((unsigned int) (C) | ('a' - 'A')) - 'a' <= 'z' - 'a')
+# define HAS_DEVICE(Filename) \
+ (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':')
+# define FILE_SYSTEM_PREFIX_LEN(Filename) (HAS_DEVICE (Filename) ? 2 : 0)
+# ifdef __CYGWIN__
+# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
+# else
+ /* On native Windows, OS/2, DOS, the system has the notion of a
+ "current directory" on each drive. */
+# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1
+# endif
+# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+# define IS_ABSOLUTE_FILE_NAME(Filename) \
+ ISSLASH ((Filename)[FILE_SYSTEM_PREFIX_LEN (Filename)])
+# else
+# define IS_ABSOLUTE_FILE_NAME(Filename) \
+ (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename))
+# endif
+# define IS_RELATIVE_FILE_NAME(Filename) \
+ (! (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename)))
+# define IS_FILE_NAME_WITH_DIR(Filename) \
+ (strchr ((Filename), '/') != NULL || strchr ((Filename), '\\') != NULL \
+ || HAS_DEVICE (Filename))
+#else
+ /* Unix */
+# define ISSLASH(C) ((C) == '/')
+# define HAS_DEVICE(Filename) ((void) (Filename), 0)
+# define FILE_SYSTEM_PREFIX_LEN(Filename) ((void) (Filename), 0)
+# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
+# define IS_ABSOLUTE_FILE_NAME(Filename) ISSLASH ((Filename)[0])
+# define IS_RELATIVE_FILE_NAME(Filename) (! ISSLASH ((Filename)[0]))
+# define IS_FILE_NAME_WITH_DIR(Filename) (strchr ((Filename), '/') != NULL)
+#endif
+
+/* Deprecated macros. For backward compatibility with old users of the
+ 'filename' module. */
+#define IS_ABSOLUTE_PATH IS_ABSOLUTE_FILE_NAME
+#define IS_PATH_WITH_DIR IS_FILE_NAME_WITH_DIR
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FILENAME_H */
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/6] malloc: Add scratch_buffer_dupfree
2020-12-28 13:59 [PATCH v2 1/6] Import idx.h from gnulib Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 2/6] Import filename.h " Adhemerval Zanella
@ 2020-12-28 13:59 ` Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 4/6] stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970] Adhemerval Zanella
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Adhemerval Zanella @ 2020-12-28 13:59 UTC (permalink / raw)
To: libc-alpha, Paul Eggert; +Cc: bug-gnulib
It returns a copy of the buffer up to a defined size. It will be used
on realpath sync with gnulib.
---
include/scratch_buffer.h | 16 +++++++++++++
malloc/Makefile | 1 +
malloc/Versions | 1 +
malloc/scratch_buffer_dupfree.c | 41 +++++++++++++++++++++++++++++++++
malloc/tst-scratch_buffer.c | 26 +++++++++++++++++++--
5 files changed, 83 insertions(+), 2 deletions(-)
create mode 100644 malloc/scratch_buffer_dupfree.c
diff --git a/include/scratch_buffer.h b/include/scratch_buffer.h
index c39da78629..48d651b41a 100644
--- a/include/scratch_buffer.h
+++ b/include/scratch_buffer.h
@@ -132,4 +132,20 @@ scratch_buffer_set_array_size (struct scratch_buffer *buffer,
(buffer, nelem, size));
}
+/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block,
+ deallocating *BUFFER if it was heap-allocated. SIZE must be at
+ most *BUFFER's size. Return NULL (setting errno) on memory
+ exhaustion. */
+void *__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer,
+ size_t size);
+libc_hidden_proto (__libc_scratch_buffer_dupfree)
+
+/* Alias for __libc_scratch_dupfree. */
+static __always_inline void *
+scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size)
+{
+ void *r = __libc_scratch_buffer_dupfree (buffer, size);
+ return __glibc_likely (r != NULL) ? r : NULL;
+}
+
#endif /* _SCRATCH_BUFFER_H */
diff --git a/malloc/Makefile b/malloc/Makefile
index ab64dcfd73..f0ec3dae6b 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -63,6 +63,7 @@ tests += $(tests-static)
test-srcs = tst-mtrace
routines = malloc morecore mcheck mtrace obstack reallocarray \
+ scratch_buffer_dupfree \
scratch_buffer_grow scratch_buffer_grow_preserve \
scratch_buffer_set_array_size \
dynarray_at_failure \
diff --git a/malloc/Versions b/malloc/Versions
index 94c8ba8040..6693c46ee2 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -75,6 +75,7 @@ libc {
__libc_thread_freeres;
# struct scratch_buffer support
+ __libc_scratch_buffer_dupfree;
__libc_scratch_buffer_grow;
__libc_scratch_buffer_grow_preserve;
__libc_scratch_buffer_set_array_size;
diff --git a/malloc/scratch_buffer_dupfree.c b/malloc/scratch_buffer_dupfree.c
new file mode 100644
index 0000000000..5561e99b0a
--- /dev/null
+++ b/malloc/scratch_buffer_dupfree.c
@@ -0,0 +1,41 @@
+/* Variable-sized buffer with on-stack default allocation.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC
+# include <libc-config.h>
+#endif
+
+#include <scratch_buffer.h>
+#include <string.h>
+
+void *
+__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size)
+{
+ void *data = buffer->data;
+ if (data == buffer->__space.__c)
+ {
+ void *copy = malloc (size);
+ return copy != NULL ? memcpy (copy, data, size) : NULL;
+ }
+ else
+ {
+ void *copy = realloc (data, size);
+ return copy != NULL ? copy : data;
+ }
+}
+libc_hidden_def (__libc_scratch_buffer_dupfree)
diff --git a/malloc/tst-scratch_buffer.c b/malloc/tst-scratch_buffer.c
index ef5fb0a8eb..6008113174 100644
--- a/malloc/tst-scratch_buffer.c
+++ b/malloc/tst-scratch_buffer.c
@@ -16,7 +16,10 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <array_length.h>
#include <scratch_buffer.h>
+#include <support/check.h>
+#include <support/support.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@@ -148,8 +151,27 @@ do_test (void)
&& array_size_must_fail (4, ((size_t)-1) / 4)))
return 1;
}
+ {
+ struct scratch_buffer buf;
+ scratch_buffer_init (&buf);
+ memset (buf.data, '@', buf.length);
+
+ size_t sizes[] = { 16, buf.length, buf.length + 16 };
+ for (int i = 0; i < array_length (sizes); i++)
+ {
+ /* The extra size is unitialized through realloc. */
+ size_t l = sizes[i] > buf.length ? sizes[i] : buf.length;
+ void *r = scratch_buffer_dupfree (&buf, l);
+ void *c = xmalloc (l);
+ memset (c, '@', l);
+ TEST_COMPARE_BLOB (r, l, buf.data, l);
+ free (r);
+ free (c);
+ }
+
+ scratch_buffer_free (&buf);
+ }
return 0;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/6] stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970]
2020-12-28 13:59 [PATCH v2 1/6] Import idx.h from gnulib Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 2/6] Import filename.h " Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 3/6] malloc: Add scratch_buffer_dupfree Adhemerval Zanella
@ 2020-12-28 13:59 ` Adhemerval Zanella
2020-12-28 21:07 ` Paul Eggert
2020-12-28 13:59 ` [PATCH v2 5/6] stdlibc: Simplify realpath via scratch_buffer_dupfree Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 6/6] stdlib: Assume FACCESSAT_NEVER_EOVERFLOWS on realpath Adhemerval Zanella
4 siblings, 1 reply; 9+ messages in thread
From: Adhemerval Zanella @ 2020-12-28 13:59 UTC (permalink / raw)
To: libc-alpha, Paul Eggert; +Cc: bug-gnulib
It sync with gnulib version bbaba6ce5 with the following difference
require fix a glibc build:
--- stdlib/canonicalize.c
+++ lib/canonicalize-lgpl.c
@@ -52,7 +52,6 @@
# endif
# define GCC_LINT 1
# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
-# define FUNC_REALPATH_WORKS 1
#else
# define __canonicalize_file_name canonicalize_file_name
# define __realpath realpath
(it is due the glibc is built with -Wundef -Werror).
It fixes multiple realpath issues:
- Portability fixes for errno clobbering on free (BZ#10635). The
function does not call free directly anymore, although it might be
done through scratch_buffer_free. The free errno clobbering is
being tracked by BZ#17924.
- Pointer arithmetic overflows in realpath (BZ#26592).
- Realpath cyclically call __alloca(path_max) to consume too much
stack space (BZ#26341).
- Realpath mishandles EOVERFLOW; stat not needed anyway (BZ#24970).
The check is done through faccessat now.
Checked on x86_64-linux-gnu.
---
stdlib/canonicalize.c | 564 ++++++++++++++++++++--------
sysdeps/unix/sysv/linux/faccessat.c | 3 +-
2 files changed, 403 insertions(+), 164 deletions(-)
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 3fcb399a5d..24a027b83f 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -16,43 +16,212 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <assert.h>
+#ifndef _LIBC
+/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
+ optimizes away the name == NULL test below. */
+# define _GL_ARG_NONNULL(params)
+
+# define _GL_USE_STDLIB_ALLOC 1
+# include <libc-config.h>
+#endif
+
+/* Specification. */
#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/stat.h>
+
#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <eloop-threshold.h>
-#include <shlib-compat.h>
+#include <filename.h>
+#include <idx.h>
+#include <scratch_buffer.h>
+
+#ifdef _LIBC
+# include <shlib-compat.h>
+# include <sysdep.h>
+# ifdef __ASSUME_FACCESSAT2
+# define FACCESSAT_NEVER_EOVERFLOWS __ASSUME_FACCESSAT2
+# else
+# define FACCESSAT_NEVER_EOVERFLOWS true
+# endif
+# define GCC_LINT 1
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# define FUNC_REALPATH_WORKS 1
+#else
+# define __canonicalize_file_name canonicalize_file_name
+# define __realpath realpath
+# include "pathmax.h"
+# define __faccessat faccessat
+# if defined _WIN32 && !defined __CYGWIN__
+# define __getcwd _getcwd
+# elif HAVE_GETCWD
+# if IN_RELOCWRAPPER
+ /* When building the relocatable program wrapper, use the system's getcwd
+ function, not the gnulib override, otherwise we would get a link error.
+ */
+# undef getcwd
+# endif
+# if defined VMS && !defined getcwd
+ /* We want the directory in Unix syntax, not in VMS syntax.
+ The gnulib override of 'getcwd' takes 2 arguments; the original VMS
+ 'getcwd' takes 3 arguments. */
+# define __getcwd(buf, max) getcwd (buf, max, 0)
+# else
+# define __getcwd getcwd
+# endif
+# else
+# define __getcwd(buf, max) getwd (buf)
+# endif
+# define __mempcpy mempcpy
+# define __pathconf pathconf
+# define __rawmemchr rawmemchr
+# define __readlink readlink
+# define __stat stat
+#endif
-/* Return the canonical absolute name of file NAME. A canonical name
- does not contain any `.', `..' components nor any repeated path
- separators ('/') or symlinks. All path components must exist. If
- RESOLVED is null, the result is malloc'd; otherwise, if the
- canonical name is PATH_MAX chars or more, returns null with `errno'
- set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
- returns the name in RESOLVED. If the name cannot be resolved and
- RESOLVED is non-NULL, it contains the path of the first component
- that cannot be resolved. If the path can be resolved, RESOLVED
- holds the same value as the value returned. */
+/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */
+#if defined GCC_LINT || defined lint
+# define IF_LINT(Code) Code
+#else
+# define IF_LINT(Code) /* empty */
+#endif
-char *
-__realpath (const char *name, char *resolved)
+#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
+# define DOUBLE_SLASH_IS_DISTINCT_ROOT false
+#endif
+#ifndef FACCESSAT_NEVER_EOVERFLOWS
+# define FACCESSAT_NEVER_EOVERFLOWS false
+#endif
+
+#if !FUNC_REALPATH_WORKS || defined _LIBC
+
+/* Return true if FILE's existence can be shown, false (setting errno)
+ otherwise. Follow symbolic links. */
+static bool
+file_accessible (char const *file)
+{
+# if defined _LIBC || HAVE_FACCESSAT
+ int r = __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS);
+# else
+ struct stat st;
+ int r = __stat (file, &st);
+# endif
+
+ return ((!FACCESSAT_NEVER_EOVERFLOWS && r < 0 && errno == EOVERFLOW)
+ || r == 0);
+}
+
+/* True if concatenating END as a suffix to a file name means that the
+ code needs to check that the file name is that of a searchable
+ directory, since the canonicalize_filename_mode_stk code won't
+ check this later anyway when it checks an ordinary file name
+ component within END. END must either be empty, or start with a
+ slash. */
+
+static bool _GL_ATTRIBUTE_PURE
+suffix_requires_dir_check (char const *end)
+{
+ /* If END does not start with a slash, the suffix is OK. */
+ while (ISSLASH (*end))
+ {
+ /* Two or more slashes act like a single slash. */
+ do
+ end++;
+ while (ISSLASH (*end));
+
+ switch (*end++)
+ {
+ default: return false; /* An ordinary file name component is OK. */
+ case '\0': return true; /* Trailing "/" is trouble. */
+ case '.': break; /* Possibly "." or "..". */
+ }
+ /* Trailing "/.", or "/.." even if not trailing, is trouble. */
+ if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1]))))
+ return true;
+ }
+
+ return false;
+}
+
+/* Append this to a file name to test whether it is a searchable directory.
+ On POSIX platforms "/" suffices, but "/./" is sometimes needed on
+ macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on
+ platforms like AIX 7.2 that need at least "/.". */
+
+#if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK
+static char const dir_suffix[] = "/";
+#else
+static char const dir_suffix[] = "/./";
+#endif
+
+/* Return true if DIR is a searchable dir, false (setting errno) otherwise.
+ DIREND points to the NUL byte at the end of the DIR string.
+ Store garbage into DIREND[0 .. strlen (dir_suffix)]. */
+
+static bool
+dir_check (char *dir, char *dirend)
+{
+ strcpy (dirend, dir_suffix);
+ return file_accessible (dir);
+}
+
+static idx_t
+get_path_max (void)
+{
+# ifdef PATH_MAX
+ long int path_max = PATH_MAX;
+# else
+ /* The caller invoked realpath with a null RESOLVED, even though
+ PATH_MAX is not defined as a constant. The glibc manual says
+ programs should not do this, and POSIX says the behavior is undefined.
+ Historically, glibc here used the result of pathconf, or 1024 if that
+ failed; stay consistent with this (dubious) historical practice. */
+ int err = errno;
+ long int path_max = __pathconf ("/", _PC_PATH_MAX);
+ __set_errno (err);
+# endif
+ return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX;
+}
+
+/* Act like __realpath (see below), with an additional argument
+ rname_buf that can be used as temporary storage.
+
+ If GCC_LINT is defined, do not inline this function with GCC 10.1
+ and later, to avoid creating a pointer to the stack that GCC
+ -Wreturn-local-addr incorrectly complains about. See:
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644
+ Although the noinline attribute can hurt performance a bit, no better way
+ to pacify GCC is known; even an explicit #pragma does not pacify GCC.
+ When the GCC bug is fixed this workaround should be limited to the
+ broken GCC versions. */
+#if __GNUC_PREREQ (10, 1)
+# if defined GCC_LINT || defined lint
+__attribute__ ((__noinline__))
+# elif __OPTIMIZE__ && !__NO_INLINE__
+# define GCC_BOGUS_WRETURN_LOCAL_ADDR
+# endif
+#endif
+static char *
+realpath_stk (const char *name, char *resolved,
+ struct scratch_buffer *rname_buf)
{
- char *rpath, *dest, *extra_buf = NULL;
- const char *start, *end, *rpath_limit;
- long int path_max;
+ char *dest;
+ char const *start;
+ char const *end;
int num_links = 0;
if (name == NULL)
{
/* As per Single Unix Specification V2 we must return an error if
- either parameter is a null pointer. We extend this to allow
- the RESOLVED parameter to be NULL in case the we are expected to
- allocate the room for the return value. */
+ either parameter is a null pointer. We extend this to allow
+ the RESOLVED parameter to be NULL in case the we are expected to
+ allocate the room for the return value. */
__set_errno (EINVAL);
return NULL;
}
@@ -60,166 +229,235 @@ __realpath (const char *name, char *resolved)
if (name[0] == '\0')
{
/* As per Single Unix Specification V2 we must return an error if
- the name argument points to an empty string. */
+ the name argument points to an empty string. */
__set_errno (ENOENT);
return NULL;
}
-#ifdef PATH_MAX
- path_max = PATH_MAX;
-#else
- path_max = __pathconf (name, _PC_PATH_MAX);
- if (path_max <= 0)
- path_max = 1024;
-#endif
+ struct scratch_buffer extra_buffer, link_buffer;
+ scratch_buffer_init (&extra_buffer);
+ scratch_buffer_init (&link_buffer);
+ scratch_buffer_init (rname_buf);
+ char *rname_on_stack = rname_buf->data;
+ char *rname = rname_on_stack;
+ bool end_in_extra_buffer = false;
+ bool failed = true;
- if (resolved == NULL)
- {
- rpath = malloc (path_max);
- if (rpath == NULL)
- return NULL;
- }
- else
- rpath = resolved;
- rpath_limit = rpath + path_max;
+ /* This is always zero for Posix hosts, but can be 2 for MS-Windows
+ and MS-DOS X:/foo/bar file names. */
+ idx_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
- if (name[0] != '/')
+ if (!IS_ABSOLUTE_FILE_NAME (name))
{
- if (!__getcwd (rpath, path_max))
- {
- rpath[0] = '\0';
- goto error;
- }
- dest = __rawmemchr (rpath, '\0');
+ while (!__getcwd (rname, rname_buf->length))
+ {
+ if (errno != ERANGE)
+ {
+ dest = rname;
+ goto error;
+ }
+ if (!scratch_buffer_grow (rname_buf))
+ goto error_nomem;
+ rname = rname_buf->data;
+ }
+ dest = __rawmemchr (rname, '\0');
+ start = name;
+ prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
}
else
{
- rpath[0] = '/';
- dest = rpath + 1;
+ dest = __mempcpy (rname, name, prefix_len);
+ *dest++ = '/';
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
+ {
+ if (prefix_len == 0 /* implies ISSLASH (name[0]) */
+ && ISSLASH (name[1]) && !ISSLASH (name[2]))
+ *dest++ = '/';
+ *dest = '\0';
+ }
+ start = name + prefix_len;
}
- for (start = end = name; *start; start = end)
+ for ( ; *start; start = end)
{
- struct stat64 st;
- int n;
-
- /* Skip sequence of multiple path-separators. */
- while (*start == '/')
- ++start;
-
- /* Find end of path component. */
- for (end = start; *end && *end != '/'; ++end)
- /* Nothing. */;
-
- if (end - start == 0)
- break;
- else if (end - start == 1 && start[0] == '.')
- /* nothing */;
- else if (end - start == 2 && start[0] == '.' && start[1] == '.')
- {
- /* Back up to previous component, ignore if at root already. */
- if (dest > rpath + 1)
- while ((--dest)[-1] != '/');
- }
+ /* Skip sequence of multiple file name separators. */
+ while (ISSLASH (*start))
+ ++start;
+
+ /* Find end of component. */
+ for (end = start; *end && !ISSLASH (*end); ++end)
+ /* Nothing. */;
+
+ /* Length of this file name component; it can be zero if a file
+ name ends in '/'. */
+ idx_t startlen = end - start;
+
+ if (startlen == 0)
+ break;
+ else if (startlen == 1 && start[0] == '.')
+ /* nothing */;
+ else if (startlen == 2 && start[0] == '.' && start[1] == '.')
+ {
+ /* Back up to previous component, ignore if at root already. */
+ if (dest > rname + prefix_len + 1)
+ for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
+ continue;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT
+ && dest == rname + 1 && !prefix_len
+ && ISSLASH (*dest) && !ISSLASH (dest[1]))
+ dest++;
+ }
else
- {
- size_t new_size;
-
- if (dest[-1] != '/')
- *dest++ = '/';
-
- if (dest + (end - start) >= rpath_limit)
- {
- ptrdiff_t dest_offset = dest - rpath;
- char *new_rpath;
-
- if (resolved)
- {
- __set_errno (ENAMETOOLONG);
- if (dest > rpath + 1)
- dest--;
- *dest = '\0';
- goto error;
- }
- new_size = rpath_limit - rpath;
- if (end - start + 1 > path_max)
- new_size += end - start + 1;
- else
- new_size += path_max;
- new_rpath = (char *) realloc (rpath, new_size);
- if (new_rpath == NULL)
- goto error;
- rpath = new_rpath;
- rpath_limit = rpath + new_size;
-
- dest = rpath + dest_offset;
- }
-
- dest = __mempcpy (dest, start, end - start);
- *dest = '\0';
-
- if (__lstat64 (rpath, &st) < 0)
- goto error;
-
- if (S_ISLNK (st.st_mode))
- {
- char *buf = __alloca (path_max);
- size_t len;
-
- if (++num_links > __eloop_threshold ())
- {
- __set_errno (ELOOP);
- goto error;
- }
-
- n = __readlink (rpath, buf, path_max - 1);
- if (n < 0)
- goto error;
- buf[n] = '\0';
-
- if (!extra_buf)
- extra_buf = __alloca (path_max);
-
- len = strlen (end);
- if (path_max - n <= len)
- {
- __set_errno (ENAMETOOLONG);
- goto error;
- }
-
- /* Careful here, end may be a pointer into extra_buf... */
- memmove (&extra_buf[n], end, len + 1);
- name = end = memcpy (extra_buf, buf, n);
-
- if (buf[0] == '/')
- dest = rpath + 1; /* It's an absolute symlink */
- else
- /* Back up to previous component, ignore if at root already: */
- if (dest > rpath + 1)
- while ((--dest)[-1] != '/');
- }
- else if (!S_ISDIR (st.st_mode) && *end != '\0')
- {
- __set_errno (ENOTDIR);
- goto error;
- }
- }
+ {
+ if (!ISSLASH (dest[-1]))
+ *dest++ = '/';
+
+ while (rname + rname_buf->length - dest
+ < startlen + sizeof dir_suffix)
+ {
+ idx_t dest_offset = dest - rname;
+ if (!scratch_buffer_grow_preserve (rname_buf))
+ goto error_nomem;
+ rname = rname_buf->data;
+ dest = rname + dest_offset;
+ }
+
+ dest = __mempcpy (dest, start, startlen);
+ *dest = '\0';
+
+ char *buf;
+ ssize_t n;
+ while (true)
+ {
+ buf = link_buffer.data;
+ idx_t bufsize = link_buffer.length;
+ n = __readlink (rname, buf, bufsize - 1);
+ if (n < bufsize - 1)
+ break;
+ if (!scratch_buffer_grow (&link_buffer))
+ goto error_nomem;
+ }
+ if (0 <= n)
+ {
+ if (++num_links > __eloop_threshold ())
+ {
+ __set_errno (ELOOP);
+ goto error;
+ }
+
+ buf[n] = '\0';
+
+ char *extra_buf = extra_buffer.data;
+ idx_t end_idx IF_LINT (= 0);
+ if (end_in_extra_buffer)
+ end_idx = end - extra_buf;
+ idx_t len = strlen (end);
+ while (extra_buffer.length <= len + n)
+ {
+ if (!scratch_buffer_grow_preserve (&extra_buffer))
+ goto error_nomem;
+ extra_buf = extra_buffer.data;
+ }
+ if (end_in_extra_buffer)
+ end = extra_buf + end_idx;
+
+ /* Careful here, end may be a pointer into extra_buf... */
+ memmove (&extra_buf[n], end, len + 1);
+ name = end = memcpy (extra_buf, buf, n);
+ end_in_extra_buffer = true;
+
+ if (IS_ABSOLUTE_FILE_NAME (buf))
+ {
+ idx_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
+
+ dest = __mempcpy (rname, buf, pfxlen);
+ *dest++ = '/'; /* It's an absolute symlink */
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
+ {
+ if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
+ *dest++ = '/';
+ *dest = '\0';
+ }
+ /* Install the new prefix to be in effect hereafter. */
+ prefix_len = pfxlen;
+ }
+ else
+ {
+ /* Back up to previous component, ignore if at root
+ already: */
+ if (dest > rname + prefix_len + 1)
+ for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
+ continue;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
+ && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
+ dest++;
+ }
+ }
+ else if (! (suffix_requires_dir_check (end)
+ ? dir_check (rname, dest)
+ : errno == EINVAL))
+ goto error;
+ }
}
- if (dest > rpath + 1 && dest[-1] == '/')
+ if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1]))
--dest;
- *dest = '\0';
-
- assert (resolved == NULL || resolved == rpath);
- return rpath;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len
+ && ISSLASH (*dest) && !ISSLASH (dest[1]))
+ dest++;
+ failed = false;
error:
- assert (resolved == NULL || resolved == rpath);
- if (resolved == NULL)
- free (rpath);
- return NULL;
+ *dest++ = '\0';
+ if (resolved != NULL && dest - rname <= get_path_max ())
+ rname = strcpy (resolved, rname);
+
+error_nomem:
+ scratch_buffer_free (&extra_buffer);
+ scratch_buffer_free (&link_buffer);
+ if (failed || rname == resolved)
+ scratch_buffer_free (rname_buf);
+
+ if (failed)
+ return NULL;
+
+ if (rname == resolved)
+ return rname;
+ idx_t rname_size = dest - rname;
+ if (rname == rname_on_stack)
+ {
+ rname = malloc (rname_size);
+ if (rname == NULL)
+ return NULL;
+ return memcpy (rname, rname_on_stack, rname_size);
+ }
+ char *result = realloc (rname, rname_size);
+ return result != NULL ? result : rname;
+}
+
+/* Return the canonical absolute name of file NAME. A canonical name
+ does not contain any ".", ".." components nor any repeated file name
+ separators ('/') or symlinks. All file name components must exist. If
+ RESOLVED is null, the result is malloc'd; otherwise, if the
+ canonical name is PATH_MAX chars or more, returns null with 'errno'
+ set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
+ returns the name in RESOLVED. If the name cannot be resolved and
+ RESOLVED is non-NULL, it contains the name of the first component
+ that cannot be resolved. If the name can be resolved, RESOLVED
+ holds the same value as the value returned. */
+
+char *
+__realpath (const char *name, char *resolved)
+{
+ #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR
+ #warning "GCC might issue a bogus -Wreturn-local-addr warning here."
+ #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>."
+ #endif
+ struct scratch_buffer rname_buffer;
+ return realpath_stk (name, resolved, &rname_buffer);
}
libc_hidden_def (__realpath)
versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
+#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
diff --git a/sysdeps/unix/sysv/linux/faccessat.c b/sysdeps/unix/sysv/linux/faccessat.c
index 5d078371b5..5bb1051c06 100644
--- a/sysdeps/unix/sysv/linux/faccessat.c
+++ b/sysdeps/unix/sysv/linux/faccessat.c
@@ -24,7 +24,7 @@
int
-faccessat (int fd, const char *file, int mode, int flag)
+__faccessat (int fd, const char *file, int mode, int flag)
{
int ret = INLINE_SYSCALL_CALL (faccessat2, fd, file, mode, flag);
#if __ASSUME_FACCESSAT2
@@ -73,3 +73,4 @@ faccessat (int fd, const char *file, int mode, int flag)
return INLINE_SYSCALL_ERROR_RETURN_VALUE (EACCES);
#endif /* !__ASSUME_FACCESSAT2 */
}
+weak_alias (__faccessat, faccessat)
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 5/6] stdlibc: Simplify realpath via scratch_buffer_dupfree
2020-12-28 13:59 [PATCH v2 1/6] Import idx.h from gnulib Adhemerval Zanella
` (2 preceding siblings ...)
2020-12-28 13:59 ` [PATCH v2 4/6] stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970] Adhemerval Zanella
@ 2020-12-28 13:59 ` Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 6/6] stdlib: Assume FACCESSAT_NEVER_EOVERFLOWS on realpath Adhemerval Zanella
4 siblings, 0 replies; 9+ messages in thread
From: Adhemerval Zanella @ 2020-12-28 13:59 UTC (permalink / raw)
To: libc-alpha, Paul Eggert; +Cc: bug-gnulib
From: Paul Eggert <eggert@cs.ucla.edu>
Checked on x86_64-linux-gnu.
---
stdlib/canonicalize.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 24a027b83f..69f978da78 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -414,24 +414,14 @@ error:
error_nomem:
scratch_buffer_free (&extra_buffer);
scratch_buffer_free (&link_buffer);
- if (failed || rname == resolved)
- scratch_buffer_free (rname_buf);
-
- if (failed)
- return NULL;
- if (rname == resolved)
- return rname;
- idx_t rname_size = dest - rname;
- if (rname == rname_on_stack)
+ if (failed || rname == resolved)
{
- rname = malloc (rname_size);
- if (rname == NULL)
- return NULL;
- return memcpy (rname, rname_on_stack, rname_size);
+ scratch_buffer_free (rname_buf);
+ return failed ? NULL : resolved;
}
- char *result = realloc (rname, rname_size);
- return result != NULL ? result : rname;
+
+ return scratch_buffer_dupfree (rname_buf, dest - rname);
}
/* Return the canonical absolute name of file NAME. A canonical name
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 6/6] stdlib: Assume FACCESSAT_NEVER_EOVERFLOWS on realpath
2020-12-28 13:59 [PATCH v2 1/6] Import idx.h from gnulib Adhemerval Zanella
` (3 preceding siblings ...)
2020-12-28 13:59 ` [PATCH v2 5/6] stdlibc: Simplify realpath via scratch_buffer_dupfree Adhemerval Zanella
@ 2020-12-28 13:59 ` Adhemerval Zanella
2020-12-28 21:14 ` Paul Eggert
4 siblings, 1 reply; 9+ messages in thread
From: Adhemerval Zanella @ 2020-12-28 13:59 UTC (permalink / raw)
To: libc-alpha, Paul Eggert; +Cc: bug-gnulib
The faccessat (..., AT_EACCESS) on Linux fallback will either use
__NR_faccessat for __libc_enable_secure or LFS fstatat call. Neither
fallbacks returns EOVERFLOW in failure case.
Checked on x86_64-linux-gnu.
---
stdlib/canonicalize.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 69f978da78..5aac8d457c 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -44,15 +44,10 @@
#ifdef _LIBC
# include <shlib-compat.h>
-# include <sysdep.h>
-# ifdef __ASSUME_FACCESSAT2
-# define FACCESSAT_NEVER_EOVERFLOWS __ASSUME_FACCESSAT2
-# else
-# define FACCESSAT_NEVER_EOVERFLOWS true
-# endif
# define GCC_LINT 1
# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
# define FUNC_REALPATH_WORKS 1
+# define FACCESSAT_NEVER_EOVERFLOWS true
#else
# define __canonicalize_file_name canonicalize_file_name
# define __realpath realpath
@@ -82,7 +77,7 @@
# define __pathconf pathconf
# define __rawmemchr rawmemchr
# define __readlink readlink
-# define __stat stat
+# define FACCESSAT_NEVER_EOVERFLOWS false
#endif
/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */
@@ -95,9 +90,6 @@
#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
# define DOUBLE_SLASH_IS_DISTINCT_ROOT false
#endif
-#ifndef FACCESSAT_NEVER_EOVERFLOWS
-# define FACCESSAT_NEVER_EOVERFLOWS false
-#endif
#if !FUNC_REALPATH_WORKS || defined _LIBC
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 4/6] stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970]
2020-12-28 13:59 ` [PATCH v2 4/6] stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970] Adhemerval Zanella
@ 2020-12-28 21:07 ` Paul Eggert
0 siblings, 0 replies; 9+ messages in thread
From: Paul Eggert @ 2020-12-28 21:07 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: libc-alpha, bug-gnulib
On 12/28/20 5:59 AM, Adhemerval Zanella wrote:
> It sync with gnulib version bbaba6ce5 with the following difference
> require fix a glibc build:
>
> --- stdlib/canonicalize.c
> +++ lib/canonicalize-lgpl.c
> @@ -52,7 +52,6 @@
> # endif
> # define GCC_LINT 1
> # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
> -# define FUNC_REALPATH_WORKS 1
I hope a better fix for that problem is this change:
-#if !FUNC_REALPATH_WORKS || defined _LIBC
+#if defined _LIBC || !FUNC_REALPATH_WORKS
which I just installed into Gnulib
<https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=18bc1ab1feca304d2a357407af8e29b3354496f2>.
This sort of technique works in the "# if defined _LIBC ||
HAVE_FACCESSAT" line later on.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 6/6] stdlib: Assume FACCESSAT_NEVER_EOVERFLOWS on realpath
2020-12-28 13:59 ` [PATCH v2 6/6] stdlib: Assume FACCESSAT_NEVER_EOVERFLOWS on realpath Adhemerval Zanella
@ 2020-12-28 21:14 ` Paul Eggert
2020-12-28 21:50 ` Adhemerval Zanella
0 siblings, 1 reply; 9+ messages in thread
From: Paul Eggert @ 2020-12-28 21:14 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: libc-alpha, bug-gnulib
On 12/28/20 5:59 AM, Adhemerval Zanella wrote:
> The faccessat (..., AT_EACCESS) on Linux fallback will either use
> __NR_faccessat for __libc_enable_secure or LFS fstatat call. Neither
> fallbacks returns EOVERFLOW in failure case.
Argh, I had misread the glibc source code in this area. So I installed
this further Gnulib patch:
https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=d82dfeb8a7c9b276c8c7db94d077eb7a43a6760c
which should result in even simpler code than the v2 6/6 patch.
So, to summarize this series of 6 patches to glibc:
* Patches 1, 2, and 3 are fine.
* Patch 4 (stdlib: Sync canonicalize with gnulib) can now sync with
today's Gnulib instead.
* Patch 5 and 6 are no longer needed, since today's Gnulib subsumes them.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 6/6] stdlib: Assume FACCESSAT_NEVER_EOVERFLOWS on realpath
2020-12-28 21:14 ` Paul Eggert
@ 2020-12-28 21:50 ` Adhemerval Zanella
0 siblings, 0 replies; 9+ messages in thread
From: Adhemerval Zanella @ 2020-12-28 21:50 UTC (permalink / raw)
To: Paul Eggert; +Cc: libc-alpha, bug-gnulib
On 28/12/2020 18:14, Paul Eggert wrote:
> On 12/28/20 5:59 AM, Adhemerval Zanella wrote:
>> The faccessat (..., AT_EACCESS) on Linux fallback will either use
>> __NR_faccessat for __libc_enable_secure or LFS fstatat call. Neither
>> fallbacks returns EOVERFLOW in failure case.
> Argh, I had misread the glibc source code in this area. So I installed this further Gnulib patch:
>
> https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=d82dfeb8a7c9b276c8c7db94d077eb7a43a6760c
>
> which should result in even simpler code than the v2 6/6 patch.
>
> So, to summarize this series of 6 patches to glibc:
>
> * Patches 1, 2, and 3 are fine.
>
> * Patch 4 (stdlib: Sync canonicalize with gnulib) can now sync with today's Gnulib instead.
>
> * Patch 5 and 6 are no longer needed, since today's Gnulib subsumes them.
Right, I will sort this out and push a version synced with gnulib master.
I forgot to send a testcase for BZ#26341, which I will push as well.
Thanks for working on this to accommodate both gnulib and glibc requirements.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2020-12-28 21:51 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-28 13:59 [PATCH v2 1/6] Import idx.h from gnulib Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 2/6] Import filename.h " Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 3/6] malloc: Add scratch_buffer_dupfree Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 4/6] stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970] Adhemerval Zanella
2020-12-28 21:07 ` Paul Eggert
2020-12-28 13:59 ` [PATCH v2 5/6] stdlibc: Simplify realpath via scratch_buffer_dupfree Adhemerval Zanella
2020-12-28 13:59 ` [PATCH v2 6/6] stdlib: Assume FACCESSAT_NEVER_EOVERFLOWS on realpath Adhemerval Zanella
2020-12-28 21:14 ` Paul Eggert
2020-12-28 21:50 ` Adhemerval Zanella
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).