-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a workaround for a broken (or old) implementation of realpath.
Part of the fix for #806.
- Loading branch information
Showing
6 changed files
with
352 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# 00gnulib.m4 serial 3 | ||
dnl Copyright (C) 2009-2016 Free Software Foundation, Inc. | ||
dnl This file is free software; the Free Software Foundation | ||
dnl gives unlimited permission to copy and/or distribute it, | ||
dnl with or without modifications, as long as this notice is preserved. | ||
|
||
dnl This file must be named something that sorts before all other | ||
dnl gnulib-provided .m4 files. It is needed until such time as we can | ||
dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE and | ||
dnl m4_divert semantics. | ||
|
||
# Until autoconf 2.63, handling of the diversion stack required m4_init | ||
# to be called first; but this does not happen with aclocal. Wrapping | ||
# the entire execution in another layer of the diversion stack fixes this. | ||
# Worse, prior to autoconf 2.62, m4_wrap depended on the underlying m4 | ||
# for whether it was FIFO or LIFO; in order to properly balance with | ||
# m4_init, we need to undo our push just before anything wrapped within | ||
# the m4_init body. The way to ensure this is to wrap both sides of | ||
# m4_init with a one-shot macro that does the pop at the right time. | ||
m4_ifndef([_m4_divert_diversion], | ||
[m4_divert_push([KILL]) | ||
m4_define([gl_divert_fixup], [m4_divert_pop()m4_define([$0])]) | ||
m4_define([m4_init], | ||
[gl_divert_fixup()]m4_defn([m4_init])[gl_divert_fixup()])]) | ||
|
||
|
||
# AC_DEFUN_ONCE([NAME], VALUE) | ||
# ---------------------------- | ||
# Define NAME to expand to VALUE on the first use (whether by direct | ||
# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses. | ||
# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This | ||
# definition is slower than the version in Autoconf 2.64, because it | ||
# can only use interfaces that existed since 2.59; but it achieves the | ||
# same effect. Quoting is necessary to avoid confusing Automake. | ||
m4_version_prereq([2.63.263], [], | ||
[m4_define([AC][_DEFUN_ONCE], | ||
[AC][_DEFUN([$1], | ||
[AC_REQUIRE([_gl_DEFUN_ONCE([$1])], | ||
[m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl | ||
[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])]) | ||
|
||
# gl_00GNULIB | ||
# ----------- | ||
# Witness macro that this file has been included. Needed to force | ||
# Automake to include this file prior to all other gnulib .m4 files. | ||
AC_DEFUN([gl_00GNULIB]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# canonicalize.m4 serial 26 | ||
|
||
dnl Copyright (C) 2003-2007, 2009-2016 Free Software Foundation, Inc. | ||
|
||
dnl This file is free software; the Free Software Foundation | ||
dnl gives unlimited permission to copy and/or distribute it, | ||
dnl with or without modifications, as long as this notice is preserved. | ||
|
||
# Provides canonicalize_file_name and canonicalize_filename_mode, but does | ||
# not provide or fix realpath. | ||
AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE], | ||
[ | ||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) | ||
AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) | ||
AC_REQUIRE([gl_FUNC_REALPATH_WORKS]) | ||
if test $ac_cv_func_canonicalize_file_name = no; then | ||
HAVE_CANONICALIZE_FILE_NAME=0 | ||
else | ||
case "$gl_cv_func_realpath_works" in | ||
*yes) ;; | ||
*) REPLACE_CANONICALIZE_FILE_NAME=1 ;; | ||
esac | ||
fi | ||
]) | ||
|
||
# Provides canonicalize_file_name and realpath. | ||
AC_DEFUN([gl_CANONICALIZE_LGPL], | ||
[ | ||
AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | ||
AC_REQUIRE([gl_CANONICALIZE_LGPL_SEPARATE]) | ||
if test $ac_cv_func_canonicalize_file_name = no; then | ||
HAVE_CANONICALIZE_FILE_NAME=0 | ||
if test $ac_cv_func_realpath = no; then | ||
HAVE_REALPATH=0 | ||
else | ||
case "$gl_cv_func_realpath_works" in | ||
*yes) ;; | ||
*) REPLACE_REALPATH=1 ;; | ||
esac | ||
fi | ||
else | ||
case "$gl_cv_func_realpath_works" in | ||
*yes) | ||
;; | ||
*) | ||
REPLACE_CANONICALIZE_FILE_NAME=1 | ||
REPLACE_REALPATH=1 | ||
;; | ||
esac | ||
fi | ||
]) | ||
|
||
# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation | ||
# (no REPLACE_CANONICALIZE_FILE_NAME, no REPLACE_REALPATH, no AC_LIBOBJ). | ||
AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], | ||
[ | ||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
AC_CHECK_FUNCS_ONCE([canonicalize_file_name getcwd readlink]) | ||
AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) | ||
AC_REQUIRE([gl_FUNC_REALPATH_WORKS]) | ||
AC_CHECK_HEADERS_ONCE([sys/param.h]) | ||
]) | ||
|
||
# Check whether realpath works. Assume that if a platform has both | ||
# realpath and canonicalize_file_name, but the former is broken, then | ||
# so is the latter. | ||
AC_DEFUN([gl_FUNC_REALPATH_WORKS], | ||
[ | ||
AC_CHECK_FUNCS_ONCE([realpath]) | ||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [ | ||
touch conftest.a | ||
mkdir conftest.d | ||
AC_RUN_IFELSE([ | ||
AC_LANG_PROGRAM([[ | ||
]GL_NOCRASH[ | ||
#include <stdlib.h> | ||
#include <string.h> | ||
]], [[ | ||
int result = 0; | ||
{ | ||
char *name = realpath ("conftest.a", NULL); | ||
if (!(name && *name == '/')) | ||
result |= 1; | ||
} | ||
{ | ||
char *name = realpath ("conftest.b/../conftest.a", NULL); | ||
if (name != NULL) | ||
result |= 2; | ||
} | ||
{ | ||
char *name = realpath ("conftest.a/", NULL); | ||
if (name != NULL) | ||
result |= 4; | ||
} | ||
{ | ||
char *name1 = realpath (".", NULL); | ||
char *name2 = realpath ("conftest.d//./..", NULL); | ||
if (strcmp (name1, name2) != 0) | ||
result |= 8; | ||
} | ||
return result; | ||
]]) | ||
], | ||
[gl_cv_func_realpath_works=yes], | ||
[gl_cv_func_realpath_works=no], | ||
[case "$host_os" in | ||
# Guess yes on glibc systems. | ||
*-gnu* | gnu*) gl_cv_func_realpath_works="guessing yes" ;; | ||
# If we don't know, assume the worst. | ||
*) gl_cv_func_realpath_works="guessing no" ;; | ||
esac | ||
]) | ||
rm -rf conftest.a conftest.d | ||
]) | ||
case "$gl_cv_func_realpath_works" in | ||
*yes) | ||
AC_DEFINE([FUNC_REALPATH_WORKS], [1], [Define to 1 if realpath() | ||
can malloc memory, always gives an absolute path, and handles | ||
trailing slash correctly.]) | ||
;; | ||
esac | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# double-slash-root.m4 serial 4 -*- Autoconf -*- | ||
dnl Copyright (C) 2006, 2008-2016 Free Software Foundation, Inc. | ||
dnl This file is free software; the Free Software Foundation | ||
dnl gives unlimited permission to copy and/or distribute it, | ||
dnl with or without modifications, as long as this notice is preserved. | ||
|
||
AC_DEFUN([gl_DOUBLE_SLASH_ROOT], | ||
[ | ||
AC_REQUIRE([AC_CANONICAL_HOST]) | ||
AC_CACHE_CHECK([whether // is distinct from /], [gl_cv_double_slash_root], | ||
[ if test x"$cross_compiling" = xyes ; then | ||
# When cross-compiling, there is no way to tell whether // is special | ||
# short of a list of hosts. However, the only known hosts to date | ||
# that have a distinct // are Apollo DomainOS (too old to port to), | ||
# Cygwin, and z/OS. If anyone knows of another system for which // has | ||
# special semantics and is distinct from /, please report it to | ||
# <[email protected]>. | ||
case $host in | ||
*-cygwin | i370-ibm-openedition) | ||
gl_cv_double_slash_root=yes ;; | ||
*) | ||
# Be optimistic and assume that / and // are the same when we | ||
# don't know. | ||
gl_cv_double_slash_root='unknown, assuming no' ;; | ||
esac | ||
else | ||
set x `ls -di / // 2>/dev/null` | ||
if test "$[2]" = "$[4]" && wc //dev/null >/dev/null 2>&1; then | ||
gl_cv_double_slash_root=no | ||
else | ||
gl_cv_double_slash_root=yes | ||
fi | ||
fi]) | ||
if test "$gl_cv_double_slash_root" = yes; then | ||
AC_DEFINE([DOUBLE_SLASH_IS_DISTINCT_ROOT], [1], | ||
[Define to 1 if // is a file system root distinct from /.]) | ||
fi | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# nocrash.m4 serial 4 | ||
dnl Copyright (C) 2005, 2009-2016 Free Software Foundation, Inc. | ||
dnl This file is free software; the Free Software Foundation | ||
dnl gives unlimited permission to copy and/or distribute it, | ||
dnl with or without modifications, as long as this notice is preserved. | ||
|
||
dnl Based on libsigsegv, from Bruno Haible and Paolo Bonzini. | ||
|
||
AC_PREREQ([2.13]) | ||
|
||
dnl Expands to some code for use in .c programs that will cause the configure | ||
dnl test to exit instead of crashing. This is useful to avoid triggering | ||
dnl action from a background debugger and to avoid core dumps. | ||
dnl Usage: ... | ||
dnl ]GL_NOCRASH[ | ||
dnl ... | ||
dnl int main() { nocrash_init(); ... } | ||
AC_DEFUN([GL_NOCRASH],[[ | ||
#include <stdlib.h> | ||
#if defined __MACH__ && defined __APPLE__ | ||
/* Avoid a crash on Mac OS X. */ | ||
#include <mach/mach.h> | ||
#include <mach/mach_error.h> | ||
#include <mach/thread_status.h> | ||
#include <mach/exception.h> | ||
#include <mach/task.h> | ||
#include <pthread.h> | ||
/* The exception port on which our thread listens. */ | ||
static mach_port_t our_exception_port; | ||
/* The main function of the thread listening for exceptions of type | ||
EXC_BAD_ACCESS. */ | ||
static void * | ||
mach_exception_thread (void *arg) | ||
{ | ||
/* Buffer for a message to be received. */ | ||
struct { | ||
mach_msg_header_t head; | ||
mach_msg_body_t msgh_body; | ||
char data[1024]; | ||
} msg; | ||
mach_msg_return_t retval; | ||
/* Wait for a message on the exception port. */ | ||
retval = mach_msg (&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof (msg), | ||
our_exception_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); | ||
if (retval != MACH_MSG_SUCCESS) | ||
abort (); | ||
exit (1); | ||
} | ||
static void | ||
nocrash_init (void) | ||
{ | ||
mach_port_t self = mach_task_self (); | ||
/* Allocate a port on which the thread shall listen for exceptions. */ | ||
if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port) | ||
== KERN_SUCCESS) { | ||
/* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html. */ | ||
if (mach_port_insert_right (self, our_exception_port, our_exception_port, | ||
MACH_MSG_TYPE_MAKE_SEND) | ||
== KERN_SUCCESS) { | ||
/* The exceptions we want to catch. Only EXC_BAD_ACCESS is interesting | ||
for us. */ | ||
exception_mask_t mask = EXC_MASK_BAD_ACCESS; | ||
/* Create the thread listening on the exception port. */ | ||
pthread_attr_t attr; | ||
pthread_t thread; | ||
if (pthread_attr_init (&attr) == 0 | ||
&& pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) == 0 | ||
&& pthread_create (&thread, &attr, mach_exception_thread, NULL) == 0) { | ||
pthread_attr_destroy (&attr); | ||
/* Replace the exception port info for these exceptions with our own. | ||
Note that we replace the exception port for the entire task, not only | ||
for a particular thread. This has the effect that when our exception | ||
port gets the message, the thread specific exception port has already | ||
been asked, and we don't need to bother about it. | ||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */ | ||
task_set_exception_ports (self, mask, our_exception_port, | ||
EXCEPTION_DEFAULT, MACHINE_THREAD_STATE); | ||
} | ||
} | ||
} | ||
} | ||
#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
/* Avoid a crash on native Windows. */ | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <windows.h> | ||
#include <winerror.h> | ||
static LONG WINAPI | ||
exception_filter (EXCEPTION_POINTERS *ExceptionInfo) | ||
{ | ||
switch (ExceptionInfo->ExceptionRecord->ExceptionCode) | ||
{ | ||
case EXCEPTION_ACCESS_VIOLATION: | ||
case EXCEPTION_IN_PAGE_ERROR: | ||
case EXCEPTION_STACK_OVERFLOW: | ||
case EXCEPTION_GUARD_PAGE: | ||
case EXCEPTION_PRIV_INSTRUCTION: | ||
case EXCEPTION_ILLEGAL_INSTRUCTION: | ||
case EXCEPTION_DATATYPE_MISALIGNMENT: | ||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: | ||
case EXCEPTION_NONCONTINUABLE_EXCEPTION: | ||
exit (1); | ||
} | ||
return EXCEPTION_CONTINUE_SEARCH; | ||
} | ||
static void | ||
nocrash_init (void) | ||
{ | ||
SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) exception_filter); | ||
} | ||
#else | ||
/* Avoid a crash on POSIX systems. */ | ||
#include <signal.h> | ||
/* A POSIX signal handler. */ | ||
static void | ||
exception_handler (int sig) | ||
{ | ||
exit (1); | ||
} | ||
static void | ||
nocrash_init (void) | ||
{ | ||
#ifdef SIGSEGV | ||
signal (SIGSEGV, exception_handler); | ||
#endif | ||
#ifdef SIGBUS | ||
signal (SIGBUS, exception_handler); | ||
#endif | ||
} | ||
#endif | ||
]]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters