compat: add canonicalize_file_name

the POSIX 2008 behaviour of realpath is not available everywhere so we
provide a simple wrapper function.  We use (and provide) the gnu
extension canonicalize_file_name to make it cleaner to test for the
feature we need; otherwise we have to rely on realpath segfaulting if
the second argument is null.
This commit is contained in:
David Bremner 2014-01-27 10:12:12 -04:00
parent 134dbadaf5
commit af5c3afa91
6 changed files with 57 additions and 1 deletions

View file

@ -5,6 +5,10 @@ extra_cflags += -I$(srcdir)/$(dir)
notmuch_compat_srcs := notmuch_compat_srcs :=
ifneq ($(HAVE_CANONICALIZE_FILE_NAME),1)
notmuch_compat_srcs += $(dir)/canonicalize_file_name.c
endif
ifneq ($(HAVE_GETLINE),1) ifneq ($(HAVE_GETLINE),1)
notmuch_compat_srcs += $(dir)/getline.c $(dir)/getdelim.c notmuch_compat_srcs += $(dir)/getline.c $(dir)/getdelim.c
endif endif

View file

@ -0,0 +1,18 @@
#include "compat.h"
#include <limits.h>
#undef _GNU_SOURCE
#include <stdlib.h>
char *
canonicalize_file_name (const char * path)
{
#ifdef PATH_MAX
char *resolved_path = malloc (PATH_MAX+1);
if (resolved_path == NULL)
return NULL;
return realpath (path, resolved_path);
#else
#error undefined PATH_MAX _and_ missing canonicalize_file_name not supported
#endif
}

View file

@ -37,6 +37,14 @@ extern "C" {
#define _POSIX_PTHREAD_SEMANTICS 1 #define _POSIX_PTHREAD_SEMANTICS 1
#endif #endif
#if !HAVE_CANONICALIZE_FILE_NAME
/* we only call this function from C, and this makes testing easier */
#ifndef __cplusplus
char *
canonicalize_file_name (const char *path);
#endif
#endif
#if !HAVE_GETLINE #if !HAVE_GETLINE
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>

View file

@ -0,0 +1,10 @@
#define _GNU_SOURCE
#include <stdlib.h>
int main()
{
char *found;
char *string;
found = canonicalize_file_name (string);
}

16
configure vendored
View file

@ -556,6 +556,18 @@ EOF
exit 1 exit 1
fi fi
printf "Checking for canonicalize_file_name... "
if ${CC} -o compat/have_canonicalize_file_name "$srcdir"/compat/have_canonicalize_file_name.c > /dev/null 2>&1
then
printf "Yes.\n"
have_canonicalize_file_name=1
else
printf "No (will use our own instead).\n"
have_canonicalize_file_name=0
fi
rm -f compat/have_canonicalize_file_name
printf "Checking for getline... " printf "Checking for getline... "
if ${CC} -o compat/have_getline "$srcdir"/compat/have_getline.c > /dev/null 2>&1 if ${CC} -o compat/have_getline "$srcdir"/compat/have_getline.c > /dev/null 2>&1
then then
@ -800,6 +812,10 @@ bash_completion_dir = ${BASHCOMPLETIONDIR:=\$(sysconfdir)/bash_completion.d}
# The directory to which zsh completions files should be installed # The directory to which zsh completions files should be installed
zsh_completion_dir = ${ZSHCOMLETIONDIR:=\$(prefix)/share/zsh/functions/Completion/Unix} zsh_completion_dir = ${ZSHCOMLETIONDIR:=\$(prefix)/share/zsh/functions/Completion/Unix}
# Whether the getline function is available (if not, then notmuch will
# build its own version)
HAVE_CANONICALIZE_FILE_NAME = ${have_canonicalize_file_name}
# Whether the getline function is available (if not, then notmuch will # Whether the getline function is available (if not, then notmuch will
# build its own version) # build its own version)
HAVE_GETLINE = ${have_getline} HAVE_GETLINE = ${have_getline}

View file

@ -454,7 +454,7 @@ notmuch_config_save (notmuch_config_t *config)
} }
/* Try not to overwrite symlinks. */ /* Try not to overwrite symlinks. */
filename = realpath (config->filename, NULL); filename = canonicalize_file_name (config->filename);
if (! filename) { if (! filename) {
if (errno == ENOENT) { if (errno == ENOENT) {
filename = strdup (config->filename); filename = strdup (config->filename);