On Sat, Jan 25 2014, Tomi Ollila <tomi.ollila@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