[PATCH] compat: add canonicalize_file_name
authorDavid Bremner <david@tethera.net>
Mon, 27 Jan 2014 14:12:12 +0000 (10:12 +2000)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:59:27 +0000 (09:59 -0800)
bb/ec268bebdc0fc1d0b6160017f3ce3c5cde4ea6 [new file with mode: 0644]

diff --git a/bb/ec268bebdc0fc1d0b6160017f3ce3c5cde4ea6 b/bb/ec268bebdc0fc1d0b6160017f3ce3c5cde4ea6
new file mode 100644 (file)
index 0000000..b78c7ee
--- /dev/null
@@ -0,0 +1,188 @@
+Return-Path: <bremner@tethera.net>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id C276C431FBD\r
+       for <notmuch@notmuchmail.org>; Mon, 27 Jan 2014 06:12:37 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+       autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id dRa8c9ENhinp for <notmuch@notmuchmail.org>;\r
+       Mon, 27 Jan 2014 06:12:31 -0800 (PST)\r
+Received: from yantan.tethera.net (yantan.tethera.net [199.188.72.155])\r
+       (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id E1301431FBF\r
+       for <notmuch@notmuchmail.org>; Mon, 27 Jan 2014 06:12:29 -0800 (PST)\r
+Received: from remotemail by yantan.tethera.net with local (Exim 4.80)\r
+       (envelope-from <bremner@tethera.net>)\r
+       id 1W7mvL-00060d-Bb; Mon, 27 Jan 2014 10:12:27 -0400\r
+Received: (nullmailer pid 7908 invoked by uid 1000); Mon, 27 Jan 2014\r
+       14:12:23 -0000\r
+From: David Bremner <david@tethera.net>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] compat: add canonicalize_file_name\r
+Date: Mon, 27 Jan 2014 10:12:12 -0400\r
+Message-Id: <1390831932-7865-1-git-send-email-david@tethera.net>\r
+X-Mailer: git-send-email 1.8.5.2\r
+In-Reply-To: <8761p6n0wc.fsf@zancas.localnet>\r
+References: <8761p6n0wc.fsf@zancas.localnet>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Mon, 27 Jan 2014 14:12:37 -0000\r
+\r
+the POSIX 2008 behaviour of realpath is not available everywhere so we\r
+provide a simple wrapper function.  We use (and provide) the gnu\r
+extension canonicalize_file_name to make it cleaner to test for the\r
+feature we need; otherwise we have to rely on realpath segfaulting if\r
+the second argument is null.\r
+---\r
+ compat/Makefile.local                |  4 ++++\r
+ compat/canonicalize_file_name.c      | 18 ++++++++++++++++++\r
+ compat/compat.h                      |  8 ++++++++\r
+ compat/have_canonicalize_file_name.c | 10 ++++++++++\r
+ configure                            | 16 ++++++++++++++++\r
+ notmuch-config.c                     |  2 +-\r
+ 6 files changed, 57 insertions(+), 1 deletion(-)\r
+ create mode 100644 compat/canonicalize_file_name.c\r
+ create mode 100644 compat/have_canonicalize_file_name.c\r
+\r
+diff --git a/compat/Makefile.local b/compat/Makefile.local\r
+index b0d5417..bcb9f0e 100644\r
+--- a/compat/Makefile.local\r
++++ b/compat/Makefile.local\r
+@@ -5,6 +5,10 @@ extra_cflags += -I$(srcdir)/$(dir)\r
\r
+ notmuch_compat_srcs :=\r
\r
++ifneq ($(HAVE_CANONICALIZE_FILE_NAME),1)\r
++notmuch_compat_srcs += $(dir)/canonicalize_file_name.c\r
++endif\r
++\r
+ ifneq ($(HAVE_GETLINE),1)\r
+ notmuch_compat_srcs += $(dir)/getline.c $(dir)/getdelim.c\r
+ endif\r
+diff --git a/compat/canonicalize_file_name.c b/compat/canonicalize_file_name.c\r
+new file mode 100644\r
+index 0000000..e92c0f6\r
+--- /dev/null\r
++++ b/compat/canonicalize_file_name.c\r
+@@ -0,0 +1,18 @@\r
++#include "compat.h"\r
++#include <limits.h>\r
++#undef _GNU_SOURCE\r
++#include <stdlib.h>\r
++\r
++char *\r
++canonicalize_file_name (const char * path)\r
++{\r
++#ifdef PATH_MAX\r
++    char *resolved_path =  malloc (PATH_MAX+1);\r
++    if (resolved_path == NULL)\r
++      return NULL;\r
++\r
++    return realpath (path, resolved_path);\r
++#else\r
++#error undefined PATH_MAX _and_ missing canonicalize_file_name not supported\r
++#endif\r
++}\r
+diff --git a/compat/compat.h b/compat/compat.h\r
+index 5a402d5..634d505 100644\r
+--- a/compat/compat.h\r
++++ b/compat/compat.h\r
+@@ -37,6 +37,14 @@ extern "C" {\r
+ #define _POSIX_PTHREAD_SEMANTICS 1\r
+ #endif\r
\r
++#if !HAVE_CANONICALIZE_FILE_NAME\r
++/* we only call this function from C, and this makes testing easier */\r
++#ifndef __cplusplus\r
++char *\r
++canonicalize_file_name (const char *path);\r
++#endif\r
++#endif\r
++\r
+ #if !HAVE_GETLINE\r
+ #include <stdio.h>\r
+ #include <unistd.h>\r
+diff --git a/compat/have_canonicalize_file_name.c b/compat/have_canonicalize_file_name.c\r
+new file mode 100644\r
+index 0000000..24c848e\r
+--- /dev/null\r
++++ b/compat/have_canonicalize_file_name.c\r
+@@ -0,0 +1,10 @@\r
++#define _GNU_SOURCE\r
++#include <stdlib.h>\r
++\r
++int main()\r
++{\r
++    char *found;\r
++    char *string;\r
++\r
++    found = canonicalize_file_name (string);\r
++}\r
+diff --git a/configure b/configure\r
+index 13b6062..5b7c941 100755\r
+--- a/configure\r
++++ b/configure\r
+@@ -526,6 +526,18 @@ EOF\r
+     exit 1\r
+ fi\r
\r
++printf "Checking for canonicalize_file_name... "\r
++if ${CC} -o compat/have_canonicalize_file_name "$srcdir"/compat/have_canonicalize_file_name.c > /dev/null 2>&1\r
++then\r
++    printf "Yes.\n"\r
++    have_canonicalize_file_name=1\r
++else\r
++    printf "No (will use our own instead).\n"\r
++    have_canonicalize_file_name=0\r
++fi\r
++rm -f compat/have_canonicalize_file_name\r
++\r
++\r
+ printf "Checking for getline... "\r
+ if ${CC} -o compat/have_getline "$srcdir"/compat/have_getline.c > /dev/null 2>&1\r
+ then\r
+@@ -751,6 +763,10 @@ zsh_completion_dir = ${ZSHCOMLETIONDIR:=\$(prefix)/share/zsh/functions/Completio\r
\r
+ # Whether the getline function is available (if not, then notmuch will\r
+ # build its own version)\r
++HAVE_CANONICALIZE_FILE_NAME = ${have_canonicalize_file_name}\r
++\r
++# Whether the getline function is available (if not, then notmuch will\r
++# build its own version)\r
+ HAVE_GETLINE = ${have_getline}\r
\r
+ # Whether the strcasestr function is available (if not, then notmuch will\r
+diff --git a/notmuch-config.c b/notmuch-config.c\r
+index 8d28653..4886d36 100644\r
+--- a/notmuch-config.c\r
++++ b/notmuch-config.c\r
+@@ -454,7 +454,7 @@ notmuch_config_save (notmuch_config_t *config)\r
+     }\r
\r
+     /* Try not to overwrite symlinks. */\r
+-    filename = realpath (config->filename, NULL);\r
++    filename = canonicalize_file_name (config->filename);\r
+     if (! filename) {\r
+       if (errno == ENOENT) {\r
+           filename = strdup (config->filename);\r
+-- \r
+1.8.5.2\r
+\r