[RFC PATCH] configure: check for POSIX.1-2008 realpath(3) implementation.
Tomi Ollila
tomi.ollila at iki.fi
Sat Jan 25 14:22:47 PST 2014
On Sat, Jan 25 2014, Tomi Ollila <tomi.ollila at iki.fi> wrote:
> Check whether realpath(3) supports the resolved_path == NULL feature,
> standardized in POSIX.1-2008.
>
> This is tested by executing the realpath(3) with NULL as second
> argument and the program is expected to SIGSEGV in case the
> feature is not supported.
>
> If the feature is not supported the compatibility code calls realpath(3)
> with second argument pointing to buffer with MAX_PATH in size. With
> this more systems are supported; those that have POSIX.1-2008 -capable
> realpath(3) and those that have MAX_PATH defined and realpath(3) does
> not exceed that limit.
> ---
>
> I tested running configure and then make test; then make clean,
> edited Makefile.config POSIX_2008_REALPATH = 0 and make clean
> again. then tested sigsegv'ing with (memcpy(0, 0, 4)...
>
>
> configure | 32 ++++++++++++++++++++++++++++++--
> notmuch-config.c | 21 ++++++++++++++++++++-
> 2 files changed, 50 insertions(+), 3 deletions(-)
>
> diff --git a/configure b/configure
> index 13b6062..8174219 100755
> --- a/configure
> +++ b/configure
> @@ -454,6 +454,29 @@ echo $util_byte_order
>
> rm -f _byteorder _byteorder.c
>
> +printf "Checking for posix 2008 realpath()... "
> +# resolved_path == NULL is standardized in POSIX.1-2008
> +cat > _posix_2008_realpath.c <<EOF
> +#define _BSD_SOURCE
> +#include <limits.h>
> +#include <stdlib.h>
> +#include <signal.h>
> +void exit1(int sig) { exit(1); }
> +int main () {
> + signal(SIGSEGV, exit1);
> + int main () { realpath (".", (char*)0); return 0;
> +}
> +EOF
> +${CC} ${CFLAGS} _posix_2008_realpath.c -o _posix_2008_realpath > /dev/null 2>&1
> +if ./_posix_2008_realpath; then
> + echo Yes.
> + posix_2008_realpath=1
> +else
> + echo No.
> + posix_2008_realpath=0
> +fi
> +rm -f _posix_2008_realpath _posix_2008_realpath.c
> +
> if [ $errors -gt 0 ]; then
> cat <<EOF
>
> @@ -718,6 +741,9 @@ libdir = ${LIBDIR:=\$(prefix)/lib}
> # byte order within a 32 bit word. 1234 = little, 4321 = big, 0 = guess
> UTIL_BYTE_ORDER = ${util_byte_order}
>
> +# Whether realpath(3) supports resolved_path == NULL feature
> +POSIX_2008_REALPATH = ${posix_2008_realpath}
> +
> # Whether libdir is in a path configured into ldconfig
> LIBDIR_IN_LDCONFIG = ${libdir_in_ldconfig}
>
> @@ -824,7 +850,8 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
> -DSTD_GETPWUID=\$(STD_GETPWUID) \\
> -DSTD_ASCTIME=\$(STD_ASCTIME) \\
> -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
> - -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
> + -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER) \\
> + -DPOSIX_2008_REALPATH=\$(POSIX_2008_REALPATH)
>
> CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
> \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
> @@ -834,7 +861,8 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
> -DSTD_GETPWUID=\$(STD_GETPWUID) \\
> -DSTD_ASCTIME=\$(STD_ASCTIME) \\
> -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
> - -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
> + -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER) \\
> + -DPOSIX_2008_REALPATH=\$(POSIX_2008_REALPATH)
>
> CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
> EOF
> diff --git a/notmuch-config.c b/notmuch-config.c
> index 8d28653..14d0e5c 100644
> --- a/notmuch-config.c
> +++ b/notmuch-config.c
> @@ -454,10 +454,26 @@ notmuch_config_save (notmuch_config_t *config)
> }
>
> /* Try not to overwrite symlinks. */
> +#if POSIX_2008_REALPATH
> filename = realpath (config->filename, NULL);
> +#else
> + /* compatibility with minor effort, not elegance, is the ruling factor
> + in these (two) else branches... */
> + char resolved_path[PATH_MAX];
> + filename = realpath (config->filename, resolved_path);
> +#endif
> if (! filename) {
> if (errno == ENOENT) {
> +#if POSIX_2008_REALPATH
> filename = strdup (config->filename);
> +#else
> + /* ... this is the other else... */
> + resolved_path[sizeof resolved_path - 1] = '\0';
> + strncpy(resolved_path, config->filename, sizeof resolved_path);
> + /* "faking" out of memory in case path too long -- close enough? */
> + filename = resolved_path[sizeof resolved_path - 1]?
> + resolved_path: NULL;
Ok, this above is wrong (should be other way around). Tests pass though
meaning this is not within test coverage...
Tomi
> +#endif
> if (! filename) {
> fprintf (stderr, "Out of memory.\n");
> g_free (data);
> @@ -480,12 +496,15 @@ notmuch_config_save (notmuch_config_t *config)
> filename, error->message);
> }
> g_error_free (error);
> +#if POSIX_2008_REALPATH
> free (filename);
> +#endif
> g_free (data);
> return 1;
> }
> -
> +#if POSIX_2008_REALPATH
> free (filename);
> +#endif
> g_free (data);
> return 0;
> }
> --
> 1.8.5.3
More information about the notmuch
mailing list