[PATCH 09/10] debugger.c: correct return type from getppid() (Solaris support)
Cast the return value of getppid() to int from pid_t in debugger.c, since it is being passed to sprintf(%d), which wants an int argument. On Solaris, pid_t is a long for 32-bit programs. --- debugger.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debugger.c b/debugger.c index e8b9378..8ff13d6 100644 --- a/debugger.c +++ b/debugger.c @@ -36,7 +36,7 @@ debugger_is_active (void) if (RUNNING_ON_VALGRIND) return TRUE; -sprintf (buf, /proc/%d/exe, getppid ()); +sprintf (buf, /proc/%d/exe, (int) getppid ()); if (readlink (buf, buf, sizeof (buf)) != -1 strncmp (basename (buf), gdb, 3) == 0) { -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 04/10] configure: check for -Wl,-rpath (Solaris support)
Add a check to configure to see whether -Wl,-rpath can be used without --enable-new-dtags. Solaris needs the former and doesn't know about the latter. --- configure |4 1 file changed, 4 insertions(+) diff --git a/configure b/configure index 28d4110..5c5139f 100755 --- a/configure +++ b/configure @@ -552,6 +552,10 @@ if ${CC} -Wl,--enable-new-dtags -Wl,-rpath,/tmp/ -o minimal minimal.c /dev/null then printf Yes.\n rpath_ldflags=-Wl,--enable-new-dtags -Wl,-rpath,\$(libdir) +elif ${CC} -Wl,-rpath,/tmp/ -o minimal minimal.c /dev/null 21 +then +printf Yes.\n +rpath_ldflags=-Wl,-rpath,\$(libdir) else printf No (nothing to worry about).\n rpath_ldflags= -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 08/10] notmuch-config: header for index() prototype (Solaris support)
Linux, FreeBSD, and Solaris all expect to find the prototype for index() in strings.h. On some operating systems, including string.h is sufficient to get the prototype, but that's not the case on Solaris. This patch just modifies notmuch-config.c to include strings.h to get the prototype. --- notmuch-config.c |1 + 1 file changed, 1 insertion(+) diff --git a/notmuch-config.c b/notmuch-config.c index 3e37a2d..2537a65 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -23,6 +23,7 @@ #include pwd.h #include netdb.h #include assert.h +#include strings.h static const char toplevel_config_comment[] = .notmuch-config - Configuration file for the notmuch mail system\n -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 03/10] gethostbyname: check for libnsl (Solaris support)
Add a check to configure to see whether -lnsl is needed for programs that are using gethostbyname(). This change also adds the file compat/check_ghbn.c, which configure uses to perform its check. --- compat/check_ghbn.c |8 configure | 17 - 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 compat/check_ghbn.c diff --git a/compat/check_ghbn.c b/compat/check_ghbn.c new file mode 100644 index 000..ec5f227 --- /dev/null +++ b/compat/check_ghbn.c @@ -0,0 +1,8 @@ +#include netdb.h + +int main() +{ +(void) gethostbyname(NULL); + +return (0); +} diff --git a/configure b/configure index 047c011..28d4110 100755 --- a/configure +++ b/configure @@ -534,6 +534,17 @@ else fi rm -f compat/check_asctime +printf Checking whether libnsl is needed for gethostbyname... +if ${CC} -o compat/check_ghbn $srcdir/compat/check_ghbn.c /dev/null 21 +then +printf No.\n +libnsl_ldflags= +else +printf Yes.\n +libnsl_ldflags=-lnsl +fi +rm -f compat/check_ghbn + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -723,6 +734,9 @@ GMIME_LDFLAGS = ${gmime_ldflags} TALLOC_CFLAGS = ${talloc_cflags} TALLOC_LDFLAGS = ${talloc_ldflags} +# Flags needed to get gethostbyname() at link time +LIBNSL_LDFLAGS = ${libnsl_ldflags} + # Flags needed to have linker set rpath attribute RPATH_LDFLAGS = ${rpath_ldflags} @@ -757,5 +771,6 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ -DSTD_GETPWUID=\$(STD_GETPWUID) \\ -DSTD_ASCTIME=\$(STD_ASCTIME) -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ +\$(LIBNSL_LDFLAGS) EOF -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 10/10] timegm: add portable implementation (Solaris support)
The timegm(3) function is a non-standard extension to libc which is available in GNU libc and on some BSDs. Although SunOS had this function in its libc, Solaris (unfortunately) removed it. This patch implements a very simple version of timegm() which is good enough for parse-time-string.c. Although notmuch's idiom for portability is to test for native availability and put alternate versions in compat/, that approach led to a compilation problem in this case. libnotmuch.a includes a call to parse_time_string() from parse-time-vrp.o, and parse_time_string() in libparse-time-string.a needs to call timegm(). An attempt to create compat/timegm.c caused the link to fail, because libparse-time-string.a acquired a dependency on the new timegm.o in libnotmuch.a, and the linker only does a single pass on each .a looking for dependencies. This seems to be the case both for the GNU linker and the Solaris linker. A different possible workaround would have been to include libnotmuch.a multiple times on the link line, but that seemed like a brittle way to track this dependency. --- parse-time-string/parse-time-string.c | 37 - 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/parse-time-string/parse-time-string.c b/parse-time-string/parse-time-string.c index 584067d..28901af 100644 --- a/parse-time-string/parse-time-string.c +++ b/parse-time-string/parse-time-string.c @@ -1315,6 +1315,41 @@ fixup_ampm (struct state *state) return 0; } +static int +leapyear (int year) +{ +return ((year % 4) == 0 ((year % 100) != 0 || (year % 400) == 0)); +} + +/* + * This is a simple implementation of timegm() which does what is needed + * by create_output() -- just turns the struct tm into a GMT time_t. + * It does not normalize any of the fields of the struct tm, nor does + * it set tm_wday or tm_yday. + */ +static time_t +local_timegm (struct tm *tm) +{ +intmonthlen[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, +}; +intyear, month, days; + +days = 365 * (tm-tm_year - 70); +for (year = 70; year tm-tm_year; year++) { + if (leapyear(1900 + year)) { + days++; + } +} +for (month = 0; month tm-tm_mon; month++) { + days += monthlen[leapyear(1900 + year)][month]; +} +days += tm-tm_mday - 1; + +return days * 24) + tm-tm_hour) * 60 + tm-tm_min) * 60 + tm-tm_sec); +} + /* Combine absolute and relative fields, and round. */ static int create_output (struct state *state, time_t *t_out, const time_t *ref, @@ -1465,7 +1500,7 @@ create_output (struct state *state, time_t *t_out, const time_t *ref, if (is_field_set (state, TM_TZ)) { /* tm is in specified TZ, convert to UTC for timegm(3). */ tm.tm_min -= get_field (state, TM_TZ); - t = timegm (tm); + t = local_timegm (tm); } else { /* tm is in local time. */ t = mktime (tm); -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 01/10] getpwuid: check for standards compliance (Solaris support)
Add checks to configure to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for getpwuid_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file compat/check_getpwuid.c, which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_getpwuid.c | 10 ++ compat/compat.h |4 configure | 23 +-- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 compat/check_getpwuid.c diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c new file mode 100644 index 000..5da2590 --- /dev/null +++ b/compat/check_getpwuid.c @@ -0,0 +1,10 @@ +#include pwd.h + +int main() +{ +struct passwd passwd, *ignored; + +(void) getpwuid_r (0, passwd, NULL, 0, ignored); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index b2e2736..8374d2f 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -54,6 +54,10 @@ char* strcasestr(const char *haystack, const char *needle); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS +#endif + #ifdef __cplusplus } #endif diff --git a/configure b/configure index ea8a1ad..3c18a45 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf Checking for standard version of getpwuid_r... +if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 +then +printf Yes.\n +std_getpwuid=1 +else +printf No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n +std_getpwuid=0 +fi +rm -f compat/check_getpwuid + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -671,6 +682,11 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the getpwuid_r function is standards-compliant +# (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_GETPWUID = ${std_getpwuid} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -715,10 +731,13 @@ WITH_ZSH = ${WITH_ZSH} # Combined flags for compiling and linking against all of the above CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ - \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) + \$(VALGRIND_CFLAGS) \\ + -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ + -DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ - -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) +-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ +-DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 07/10] gen-version-script: parse Solaris nm output (Solaris support)
The output of nm on Solaris is substantially different from that on Linux, and the current version of gen-version-script is tied to the Linux nm output. This patch separates the parts of nm processing which are dependent on the output format into a couple shell functions, and makes another shell function to use the appropriate version of c++filt to demangle symbols. It also modifies lib/Makefile.local to pass the generated symbol table correctly to the Solaris linker. --- lib/Makefile.local|4 lib/gen-version-script.sh | 50 - 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index 0c6b258..2068e4a 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -30,7 +30,11 @@ LIBRARY_SUFFIX = so LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX) SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR) LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE) +ifeq ($(PLATFORM),SOLARIS) +LIBRARY_LINK_FLAG = -shared -Wl,-M notmuch.sym -Wl,-soname=$(SONAME) -Wl,--no-undefined -lc +else LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) -Wl,--no-undefined +endif ifeq ($(PLATFORM),OPENBSD) LIBRARY_LINK_FLAG += -lc endif diff --git a/lib/gen-version-script.sh b/lib/gen-version-script.sh index 76670d5..d7d96da 100644 --- a/lib/gen-version-script.sh +++ b/lib/gen-version-script.sh @@ -1,3 +1,4 @@ +#!/bin/sh # we go through a bit of work to get the unmangled names of the # typeinfo symbols because of @@ -11,10 +12,44 @@ fi HEADER=$1 shift +if [ `uname -s` == SunOS ] ; then +# +# Using Solaris nm, a defined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [15]|128| 16|FUNC |GLOB |0|1 |notmuch_tags_get +# +# and an undefined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [35]| 0| 0|NOTY |GLOB |0|UNDEF |notmuch_tags_get +# +find_xapian_error() { + nawk -F'\|' '$7 !~ UNDEF $8 ~ Xapian.*Error { print $8 }' +} +find_compat_syms() { + nawk -F'\|' '$7 !~ UNDEF $8 ~ get(line|delim) { print $8 ; }' +} +demangle() { + gc++filt $@ +} +else +find_xapian_error() { + awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $3 ~ Xapian.*Error {print $3}' +} +find_compat_syms() { + awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $2 == T $3 ~ ^get(line|delim)$ {print $3 ;}' +} +demangle() { + c++filt $@ +} +fi + printf '{\nglobal:\n' -nm $* | awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $3 ~ Xapian.*Error {print $3}' | sort | uniq | \ -while read sym; do -demangled=$(c++filt $sym) + +# Find the typeinfo for Xapian::*Errors. +nm $* | find_xapian_error | sort | uniq | while read sym; do +demangled=$(demangle $sym) case $demangled in typeinfo*) printf \t$sym;\n @@ -23,6 +58,11 @@ while read sym; do ;; esac done -nm $* | awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $2 == T $3 ~ ^get(line|delim)$ {print $3 ;}' -sed -n 's/^[[:space:]]*\(notmuch_[a-z_]*\)[[:space:]]*(.*/ \1;/p' $HEADER + +# Find the compat syms that we need to export. +nm $* | find_compat_syms + +# Finally, get the real notmuch symbols. +sed -n 's/^[ ]*\(notmuch_[a-z_]*\)[ ]*(.*/ \1;/p' $HEADER + printf local: *;\n};\n -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 02/10] asctime: check for standards compliance (Solaris support)
Add checks to configure to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for asctime_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file compat/check_asctime.c, which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_asctime.c | 17 + compat/compat.h|3 +++ configure | 22 -- 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 compat/check_asctime.c diff --git a/compat/check_asctime.c b/compat/check_asctime.c new file mode 100644 index 000..a595110 --- /dev/null +++ b/compat/check_asctime.c @@ -0,0 +1,17 @@ +/* + * This compatibility check actually succeeds (on Solaris) if + * _POSIX_PTHREAD_SEMANTICS is not defined. But we need to define that to get + * the right version of getpwuid_r(), so we define it here to ensure that the + * compatibility check ends up doing the same thing as the rest of the code. + */ +#define_POSIX_PTHREAD_SEMANTICS +#include time.h + +int main() +{ +struct tm tm; + +(void) asctime_r (tm, NULL, 0); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index 8374d2f..b750501 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -57,6 +57,9 @@ char* strcasestr(const char *haystack, const char *needle); #if !STD_GETPWUID #define _POSIX_PTHREAD_SEMANTICS #endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS +#endif #ifdef __cplusplus } diff --git a/configure b/configure index 3c18a45..047c011 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/check_getpwuid +printf Checking for standard version of asctime_r... +if ${CC} -o compat/check_asctime $srcdir/compat/check_asctime.c /dev/null 21 +then +printf Yes.\n +std_asctime=1 +else +printf No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n +std_asctime=0 +fi +rm -f compat/check_asctime + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -687,6 +698,11 @@ HAVE_STRCASESTR = ${have_strcasestr} # to enable the standards-compliant version -- needed for Solaris) STD_GETPWUID = ${std_getpwuid} +# Whether the asctime_r function is standards-compliant +# (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_ASCTIME = ${std_asctime} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -733,11 +749,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ - -DSTD_GETPWUID=\$(STD_GETPWUID) + -DSTD_GETPWUID=\$(STD_GETPWUID) \\ + -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ --DSTD_GETPWUID=\$(STD_GETPWUID) +-DSTD_GETPWUID=\$(STD_GETPWUID) \\ +-DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.9.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 06/10] strsep: check for availability (Solaris support)
Solaris does not ship a version of the strsep() function. This change adds a check to configure to see whether notmuch needs to provide its own implementation, and if so, it uses the new version in compat/strsep.c (which was copied from Mutt, and apparently before that from glibc). --- compat/Makefile.local |4 +++ compat/compat.h |4 +++ compat/have_strsep.c | 10 compat/strsep.c | 65 + configure | 17 + 5 files changed, 100 insertions(+) create mode 100644 compat/have_strsep.c create mode 100644 compat/strsep.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 13f16cd..2c4f65f 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1) notmuch_compat_srcs += $(dir)/strcasestr.c endif +ifneq ($(HAVE_STRSEP),1) +notmuch_compat_srcs += $(dir)/strsep.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index b750501..1fd2723 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -46,6 +46,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp); char* strcasestr(const char *haystack, const char *needle); #endif /* !HAVE_STRCASESTR */ +#if !HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* !HAVE_STRSEP */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ diff --git a/compat/have_strsep.c b/compat/have_strsep.c new file mode 100644 index 000..5bd396c --- /dev/null +++ b/compat/have_strsep.c @@ -0,0 +1,10 @@ +#define _GNU_SOURCE +#include string.h + +int main() +{ +char *found; +char **stringp, const char *delim; + +found = strsep(stringp, delim); +} diff --git a/compat/strsep.c b/compat/strsep.c new file mode 100644 index 000..78ab9e7 --- /dev/null +++ b/compat/strsep.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include string.h + +/* Taken from glibc 2.6.1 */ + +char *strsep (char **stringp, const char *delim) +{ + char *begin, *end; + + begin = *stringp; + if (begin == NULL) +return NULL; + + /* A frequent case is when the delimiter string contains only one + character. Here we don't need to call the expensive `strpbrk' + function and instead work using `strchr'. */ + if (delim[0] == '\0' || delim[1] == '\0') +{ + char ch = delim[0]; + + if (ch == '\0') + end = NULL; + else + { + if (*begin == ch) + end = begin; + else if (*begin == '\0') + end = NULL; + else + end = strchr (begin + 1, ch); + } +} + else +/* Find the end of the token. */ +end = strpbrk (begin, delim); + + if (end) +{ + /* Terminate the token and set *STRINGP past NUL character. */ + *end++ = '\0'; + *stringp = end; +} + else +/* No more delimiters; this is the last token. */ +*stringp = NULL; + + return begin; +} diff --git a/configure b/configure index dae837e..e519abc 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf Checking for strsep... +if ${CC} -o compat/have_strsep $srcdir/compat/have_strsep.c /dev/null 21 +then +printf Yes.\n +have_strsep=1 +else +printf No (will use our own instead).\n +have_strsep=0 +fi +rm -f compat/have_strsep + printf Checking for standard version of getpwuid_r... if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 then @@ -723,6 +734,10 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the strsep function is available (if not, then notmuch will +# build its own version) +HAVE_STRSEP = ${have_strsep} + # Whether the getpwuid_r function is standards-compliant # (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS # to enable the standards-compliant version -- needed for Solaris) @@ -782,12 +797,14 @@ CONFIGURE_CFLAGS =
[PATCH 05/10] install: check for non-SysV version (Solaris support)
Solaris ships a program called install in /usr/sbin, which performs a task that's fairly similar to the GNU and BSD install programs but which uses very different command line arguments. In particular, if it is invoked without -c, -f, or -n, it will search the target directory for a file with the same name as the one being installed, and it will only install the file if it finds a matching name. More excitingly, if it doesn't find a match, it will look in /bin, /usr/bin, /etc, /lib, and /usr/lib and try to do the same there. The standard workaround for this is to use GNU install. It is available via the standard Solaris packaging system (in file/gnu-coreutils), and installs itself as /usr/bin/ginstall. This patch adds a check to configure to see if install behaves in a way that's compatible with GNU and BSD install, and if not, it uses a program called ginstall instead. It also modifies configure to set the $(INSTALL) variable, and changes various Makefiles to use it. --- Makefile.local|2 +- completion/Makefile.local |4 ++-- configure | 19 +++ emacs/Makefile.local |6 +++--- lib/Makefile.local|4 ++-- man/Makefile.local|6 +++--- vim/Makefile |6 ++ 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Makefile.local b/Makefile.local index 2b91946..7ccb1cd 100644 --- a/Makefile.local +++ b/Makefile.local @@ -286,7 +286,7 @@ notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME) .PHONY: install install: all install-man mkdir -p $(DESTDIR)$(prefix)/bin/ - install notmuch-shared $(DESTDIR)$(prefix)/bin/notmuch + $(INSTALL) notmuch-shared $(DESTDIR)$(prefix)/bin/notmuch ifeq ($(MAKECMDGOALS), install) @echo @echo Notmuch is now installed to $(DESTDIR)$(prefix) diff --git a/completion/Makefile.local b/completion/Makefile.local index dfc1271..a648a78 100644 --- a/completion/Makefile.local +++ b/completion/Makefile.local @@ -14,9 +14,9 @@ install-$(dir): @echo $@ ifeq ($(WITH_BASH),1) mkdir -p $(DESTDIR)$(bash_completion_dir) - install -m0644 $(bash_script) $(DESTDIR)$(bash_completion_dir)/notmuch + $(INSTALL) -m0644 $(bash_script) $(DESTDIR)$(bash_completion_dir)/notmuch endif ifeq ($(WITH_ZSH),1) mkdir -p $(DESTDIR)$(zsh_completion_dir) - install -m0644 $(zsh_script) $(DESTDIR)$(zsh_completion_dir)/_notmuch + $(INSTALL) -m0644 $(zsh_script) $(DESTDIR)$(zsh_completion_dir)/_notmuch endif diff --git a/configure b/configure index 5c5139f..dae837e 100755 --- a/configure +++ b/configure @@ -591,6 +591,21 @@ for flag in -Wmissing-declarations; do done printf \n\t${WARN_CFLAGS}\n +INSTALL=install +printf Checking for working \install\ program... +mkdir _tmp_ +cd _tmp_ +echo 1 1 +mkdir dest +if install 1 dest /dev/null 21 ; then + printf \install\ works fine.\n +else + INSTALL=ginstall + printf using \ginstall\.\n +fi +cd .. +rm -rf _tmp_ + rm -f minimal minimal.c cat EOF @@ -777,4 +792,8 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ \$(LIBNSL_LDFLAGS) + +# Which install program to use +INSTALL = ${INSTALL} + EOF diff --git a/emacs/Makefile.local b/emacs/Makefile.local index fb82247..ee778cb 100644 --- a/emacs/Makefile.local +++ b/emacs/Makefile.local @@ -36,11 +36,11 @@ endif .PHONY: install-emacs install-emacs: mkdir -p $(DESTDIR)$(emacslispdir) - install -m0644 $(emacs_sources) $(DESTDIR)$(emacslispdir) + $(INSTALL) -m0644 $(emacs_sources) $(DESTDIR)$(emacslispdir) ifeq ($(HAVE_EMACS),1) - install -m0644 $(emacs_bytecode) $(DESTDIR)$(emacslispdir) + $(INSTALL) -m0644 $(emacs_bytecode) $(DESTDIR)$(emacslispdir) endif mkdir -p $(DESTDIR)$(emacsetcdir) - install -m0644 $(emacs_images) $(DESTDIR)$(emacsetcdir) + $(INSTALL) -m0644 $(emacs_images) $(DESTDIR)$(emacsetcdir) CLEAN := $(CLEAN) $(emacs_bytecode) diff --git a/lib/Makefile.local b/lib/Makefile.local index 7785944..0c6b258 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -89,11 +89,11 @@ install: install-$(dir) install-$(dir): $(dir)/$(LIBNAME) mkdir -p $(DESTDIR)$(libdir)/ - install -m0644 $(lib)/$(LIBNAME) $(DESTDIR)$(libdir)/ + $(INSTALL) -m0644 $(lib)/$(LIBNAME) $(DESTDIR)$(libdir)/ ln -sf $(LIBNAME) $(DESTDIR)$(libdir)/$(SONAME) ln -sf $(LIBNAME) $(DESTDIR)$(libdir)/$(LINKER_NAME) mkdir -p $(DESTDIR)$(includedir) - install -m0644 $(srcdir)/$(lib)/notmuch.h $(DESTDIR)$(includedir)/ + $(INSTALL) -m0644 $(srcdir)/$(lib)/notmuch.h $(DESTDIR)$(includedir)/ $(LIBRARY_INSTALL_POST_COMMAND) SRCS := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs) diff --git a/man/Makefile.local
[PATCH 00/10] Solaris support
Hi all, This patch series fixes several issues which are needed to allow notmuch to build on Solaris 11. I've been testing it for a month or so by using Karel Zak's fork of mutt along with a copy of notmuch-0.13.2 that I got to compile. After a friend asked for a copy of my setup, I decided to try to get my patches cleaned up enough to submit, so that he wouldn't need to deal with them if he wanted to hack on it. I don't have access to any machines running a modern version of Linux (much less *BSD), so I haven't been able to check whether these changes have broken any other platforms. I've tried to follow the prevailing idiom of compatibility checks and conditionally-set variables, to minimize the impact on other platforms, but it's possible that I overlooked something. I'm really pleased with my experience using notmuch; using it along with the fork of mutt has given me real control of my email for the first time in many years. So I'm happy to offer these changes up in the hopes that they can be useful to others. I'm not subscribed to the mailing list, so please CC me on any comments. I'll also try to watch the web archives of the list just in case. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 10/10] timegm: add portable implementation (Solaris support)
Hi Jani, I'd prefer to use timegm() where available, and the suggested alternative [1] elsewhere. [1] http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.html I considered this alternative, but decided against it because it's completely MT-unsafe. I don't know whether libnotmuch itself is MT-safe, but a process which called this routine in one thread would temporarily throw off any timezone-related work that any other threads were doing, even if they weren't using libnotmuch. I'll look into the compat build issues when I have a moment. If you do, here's a boiled-down version of the problem that I came up with while investigating it: $ echo 'int main() { extern int foo1(); return foo1(); }' main.c $ echo 'int foo1() { extern int bar(); return bar(); }' foo1.c $ echo 'int bar() { extern int foo2(); return foo2(); }' bar.c $ echo 'int foo2() { return 0; }' foo2.c $ gcc -c main.c foo1.c bar.c foo2.c $ ar rcs libfoo.a foo1.o foo2.o $ ar rcs libbar.a bar.o $ gcc -o main main.o libfoo.a libbar.a [fails] $ gcc -o main main.o libbar.a libfoo.a [fails] Another alternative would be to just include parse-time-string.o in libnotmuch.a directly; I think that would solve the problem. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 10/10] timegm: add portable implementation (Solaris support)
That is a valid point. Yet it doesn't change the fact that I'd prefer to use timegm() where available. Internally, glibc uses the same code to implement both timegm() and mktime(), and I'd hate it if the results were subtly different depending on whether the time zone was specified in the input or not. That's fine with me. That said, I'm not opposed to using your simple timegm() alternative in the compat code if you think it's good enough to get you going on Solaris. I think it is, assuming you don't plan to use tm_wday or tm_yday in your parse-time-string code, and that you don't plan to depend on the side effect of timegm() canonicalizing the passed-in struct tm. As to solving the compat linking problem, I think the patch at the end of this message should fix it. Please try that with the regular notmuch approach to portability. The general idea is to keep parse-time-string as independent as possible from the rest of notmuch (possibly turning it into a dynamic library and a package of its own eventually), but I think including compat.h is an acceptable exception to make. Yeah, this seems to work. I'll update my patch set accordingly. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 08/10] notmuch-config: header for index() prototype (Solaris support)
On Sun, 04 Nov 2012, Blake Jones bla...@foo.net wrote: Linux, FreeBSD, and Solaris all expect to find the prototype for index() in strings.h. On some operating systems, including string.h is sufficient to get the prototype, but that's not the case on Solaris. This patch just modifies notmuch-config.c to include strings.h to get the prototype. We should probably just nuke index() and use strchr() instead. indeed! That was my initial preference, but I didn't know if there was anyone who was committed to the BSD name. Given that two more people think it's a good idea, I'll do that instead. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 05/10] install: check for non-SysV version (Solaris support)
On Mon, 05 Nov 2012, Blake Jones bla...@foo.net wrote: +INSTALL=install +printf Checking for working \install\ program... +mkdir _tmp_ This doesn't feel like a hot idea. Out of curiosity, why not? Note that I'm only referring to creating temp directories like this to check for the install tool compatibility; otherwise I'm fine with the general approach. Sure. But what's wrong with creating a temp directory? The configure script creates plenty of temp files for testing compiler features and library symbol availability. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 10/10] timegm: add portable implementation (Solaris support)
Yet another idea for an alternative. Compile by entering 'sh xtimegm.c' and then run ./xtimegm Simple cases seems to work. Dst change may (or then may not) give one hour difference to the expected. The test coverage could be easily expanded to that ;) Hmm, I also found this: http://lists.gnu.org/archive/html/bug-gnulib/2003-09/msg4.html which does 2 mktime's and one gmtime_r (without allocating tg!)... Pick any of these 3 -- or something different (e.g. less NIH if there is) Of these two, I would probably lean slightly toward the latter, in that it relies more on libc for the time zone handling logic. But in general, this seems to me like a case where an explicit implementation like mine is less prone to failure, because it doesn't need to worry about time zones at all. The other approaches rely on letting libc do all the hard work of time zone manipulation, and then reading the tea leaves to find a way to undo it. I would guess that if some change in the time standards is going to break one of these implementations, it's going to be some new time zone specification, not a change in the number of days in a month. :) For what it's worth, I used the attached program to test my implementation, and it passed. Blake #include time.h static int leapyear(int year) { return ((year % 4) == 0 ((year % 100) != 0 || (year % 400) == 0)); } /* * This is a simple implementation of timegm() which does what is needed * by parse-time-string.c -- just turns the struct tm into a GMT time_t. * It does not normalize any of the fields of the struct tm, nor does * it set tm_wday or tm_yday. */ static time_t timegm(struct tm *tm) { int monthlen[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, }; int year, month, days; days = 365 * (tm-tm_year - 70); for (year = 70; year tm-tm_year; year++) { if (leapyear(1900 + year)) { days++; } } for (month = 0; month tm-tm_mon; month++) { days += monthlen[leapyear(1900 + year)][month]; } days += tm-tm_mday - 1; return days * 24) + tm-tm_hour) * 60 + tm-tm_min) * 60 + tm-tm_sec); } #include stdio.h #include stdlib.h #include unistd.h void tm_test(int niter) { const int monthlen[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, }; int i; struct tm tm, *tmp; time_t t; for (i = 0; i niter; i++) { tm.tm_year = (lrand48() % 67) + 70; tm.tm_mon = lrand48() % 12; do { t = (lrand48() % 31) + 1; } while (t monthlen[leapyear(1900 + tm.tm_year)][tm.tm_mon]); tm.tm_mday = t; tm.tm_hour = lrand48() % 24; tm.tm_min = lrand48() % 60; tm.tm_sec = lrand48() % 60; t = timegm(tm); tmp = gmtime(t); if (tmp-tm_sec != tm.tm_sec || tmp-tm_min != tm.tm_min || tmp-tm_hour != tm.tm_hour || tmp-tm_mday != tm.tm_mday || tmp-tm_mon != tm.tm_mon || tmp-tm_year != tm.tm_year) { printf(%4d-%02d-%02d %02d:%02d:%02d - %4d-%02d-%02d %02d:%02d:%02d\n, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tmp-tm_year + 1900, tmp-tm_mon + 1, tmp-tm_mday, tmp-tm_hour, tmp-tm_min, tmp-tm_sec); } } } void time_test(int niter) { int i; time_t st, et; struct tm *tmp; for (i = 0; i niter; i++) { st = (time_t)lrand48(); tmp = gmtime(st); et = timegm(tmp); if (st != et) { printf(%d - %d (%4d-%02d-%02d %02d:%02d:%02d)\n, st, et, tmp-tm_year + 1900, tmp-tm_mon + 1, tmp-tm_mday, tmp-tm_hour, tmp-tm_min, tmp-tm_sec); } } } int main(void) { const int niter = 1000; srand48(getpid()); tm_test(niter); time_test(niter); return (0); } ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 10/10] timegm: add portable implementation (Solaris support)
The other approaches rely on letting libc do all the hard work of time zone manipulation, and then reading the tea leaves to find a way to undo it. Did you look at the gnu libc version -- I bet it is pretty hairy... I didn't look at either the GNU or the Solaris libc version. But the file that implements the timezone handling (and localtime(), mktime(), etc.) in Solaris' libc is nearly 3000 lines of code, so I suspect there's an awful lot of stuff going on. For what it's worth, I used the attached program to test my implementation, and it passed. Thanks, It's nice to see your simple implementation passes these tests... Just for curiosity: What do you think lacks in your timegm() that it could not be promoted as 'complete timegm() solution'. Well, since there isn't a standard for timegm(), I'm comparing it to what glibc and BSD do. The glibc mktime() man page, for example, mentions that mktime() modifies the fields of the tm structure as follows: - tm_wday and tm_yday are set to values determined from the contents of the other fields - if structure members are outside their valid interval, they will be normalized (so that, for example, 40 October is changed into 9 November) - tm_isdst is set (regardless of its initial value) to a positive value or to 0, respectively, to indicate whether DST is or is not in effect at the specified time. - Calling mktime() also sets the external variable tzname with information about the current timezone. The corresponding timegm() man page for glibc doesn't say whether timegm() does the same thing, but I would assume it does. The FreeBSD timegm() man page says that its version does update the fields of the tm structure, like its mktime() implementation. My implementation of timegm() does none of these things. It treats the passed-in struct tm as constant, and just returns a valid time_t. If you really wanted to make this mktime() be as capable as the ones in the GNU and BSD libc's, you could have it turn around and call gmtime_r() on the generated time_t, and pass the original struct tm to gmtime_r(). Personally, I think this is unnecessary overloading of a function that does this one thing just fine, and in practice Jani's code doesn't seem to need it, so I didn't bother. In any way, including this timegm() function in compat suits me fine. Great. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 00/10] Solaris support
Just now I don't have more time to comment and review more, but in the first 2/3 patches when I tried to compile I got problem NULL not defined. Oh! Yes, I should include stdio.h to pull in the definition of NULL. I'll fix that. Another thing: you have this +# Whether the asctime_r function is standards-compliant +# (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) which is not exactly so.. you added the following lines in compat.h +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS +#endif which is slightly different as -D_POSIX_PTHREAD_SEMANTICS is equivalent to #define _POSIX_PTHREAD_SEMANTICS 1 (you probably knew this and your comments have drifted from actual implementation but just to make sure) I'll make the code and comment line up better. Thanks for your comments. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 00/10] Solaris support
Thanks to Jani Nikula and Tomi Ollila for their comments. Changes since last version: - Add feature test for timegm(); move portable implementation of timegm() into compat/, change libparse-time-string to pull in .o's from compat/. - Include stdio.h in compat/check_*.c, to get definition of NULL. - Explicitly define _POSIX_PTHREAD_SEMANTICS to 1 in compat.h. - Call strchr() rather than index() in notmuch-config.c. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 01/10] getpwuid: check for standards compliance (Solaris support)
Add checks to configure to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for getpwuid_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file compat/check_getpwuid.c, which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_getpwuid.c | 11 +++ compat/compat.h |4 configure | 23 +-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 compat/check_getpwuid.c diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c new file mode 100644 index 000..c435eb8 --- /dev/null +++ b/compat/check_getpwuid.c @@ -0,0 +1,11 @@ +#include stdio.h +#include pwd.h + +int main() +{ +struct passwd passwd, *ignored; + +(void) getpwuid_r (0, passwd, NULL, 0, ignored); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index b2e2736..efea023 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -54,6 +54,10 @@ char* strcasestr(const char *haystack, const char *needle); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #ifdef __cplusplus } #endif diff --git a/configure b/configure index ea8a1ad..bb5031e 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf Checking for standard version of getpwuid_r... +if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 +then +printf Yes.\n +std_getpwuid=1 +else +printf No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n +std_getpwuid=0 +fi +rm -f compat/check_getpwuid + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -671,6 +682,11 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the getpwuid_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_GETPWUID = ${std_getpwuid} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -715,10 +731,13 @@ WITH_ZSH = ${WITH_ZSH} # Combined flags for compiling and linking against all of the above CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ - \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) + \$(VALGRIND_CFLAGS) \\ + -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ + -DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ - -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) +-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ +-DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 02/10] asctime: check for standards compliance (Solaris support)
Add checks to configure to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for asctime_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file compat/check_asctime.c, which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_asctime.c | 18 ++ compat/compat.h|3 +++ configure | 22 -- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 compat/check_asctime.c diff --git a/compat/check_asctime.c b/compat/check_asctime.c new file mode 100644 index 000..c508fbf --- /dev/null +++ b/compat/check_asctime.c @@ -0,0 +1,18 @@ +/* + * This compatibility check actually succeeds (on Solaris) if + * _POSIX_PTHREAD_SEMANTICS is not defined. But we need to #define that to get + * the right version of getpwuid_r(), so we define it here to ensure that the + * compatibility check ends up doing the same thing as the rest of the code. + */ +#define_POSIX_PTHREAD_SEMANTICS 1 +#include time.h +#include stdio.h + +int main() +{ +struct tm tm; + +(void) asctime_r (tm, NULL, 0); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index efea023..e5f833e 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -57,6 +57,9 @@ char* strcasestr(const char *haystack, const char *needle); #if !STD_GETPWUID #define _POSIX_PTHREAD_SEMANTICS 1 #endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif #ifdef __cplusplus } diff --git a/configure b/configure index bb5031e..d153f57 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/check_getpwuid +printf Checking for standard version of asctime_r... +if ${CC} -o compat/check_asctime $srcdir/compat/check_asctime.c /dev/null 21 +then +printf Yes.\n +std_asctime=1 +else +printf No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n +std_asctime=0 +fi +rm -f compat/check_asctime + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -687,6 +698,11 @@ HAVE_STRCASESTR = ${have_strcasestr} # to enable the standards-compliant version -- needed for Solaris) STD_GETPWUID = ${std_getpwuid} +# Whether the asctime_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_ASCTIME = ${std_asctime} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -733,11 +749,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ - -DSTD_GETPWUID=\$(STD_GETPWUID) + -DSTD_GETPWUID=\$(STD_GETPWUID) \\ + -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ --DSTD_GETPWUID=\$(STD_GETPWUID) +-DSTD_GETPWUID=\$(STD_GETPWUID) \\ +-DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 04/10] configure: check for -Wl,-rpath (Solaris support)
Add a check to configure to see whether -Wl,-rpath can be used without --enable-new-dtags. Solaris needs the former and doesn't know about the latter. --- configure |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 9707f11..c9da667 100755 --- a/configure +++ b/configure @@ -552,6 +552,10 @@ if ${CC} -Wl,--enable-new-dtags -Wl,-rpath,/tmp/ -o minimal minimal.c /dev/null then printf Yes.\n rpath_ldflags=-Wl,--enable-new-dtags -Wl,-rpath,\$(libdir) +elif ${CC} -Wl,-rpath,/tmp/ -o minimal minimal.c /dev/null 21 +then +printf Yes.\n +rpath_ldflags=-Wl,-rpath,\$(libdir) else printf No (nothing to worry about).\n rpath_ldflags= -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 06/10] strsep: check for availability (Solaris support)
Solaris does not ship a version of the strsep() function. This change adds a check to configure to see whether notmuch needs to provide its own implementation, and if so, it uses the new version in compat/strsep.c (which was copied from Mutt, and apparently before that from glibc). --- compat/Makefile.local |4 +++ compat/compat.h |4 +++ compat/have_strsep.c | 10 +++ compat/strsep.c | 65 + configure | 17 + 5 files changed, 100 insertions(+), 0 deletions(-) create mode 100644 compat/have_strsep.c create mode 100644 compat/strsep.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 13f16cd..2c4f65f 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1) notmuch_compat_srcs += $(dir)/strcasestr.c endif +ifneq ($(HAVE_STRSEP),1) +notmuch_compat_srcs += $(dir)/strsep.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index e5f833e..0b5e465 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -46,6 +46,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp); char* strcasestr(const char *haystack, const char *needle); #endif /* !HAVE_STRCASESTR */ +#if !HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* !HAVE_STRSEP */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ diff --git a/compat/have_strsep.c b/compat/have_strsep.c new file mode 100644 index 000..5bd396c --- /dev/null +++ b/compat/have_strsep.c @@ -0,0 +1,10 @@ +#define _GNU_SOURCE +#include string.h + +int main() +{ +char *found; +char **stringp, const char *delim; + +found = strsep(stringp, delim); +} diff --git a/compat/strsep.c b/compat/strsep.c new file mode 100644 index 000..78ab9e7 --- /dev/null +++ b/compat/strsep.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include string.h + +/* Taken from glibc 2.6.1 */ + +char *strsep (char **stringp, const char *delim) +{ + char *begin, *end; + + begin = *stringp; + if (begin == NULL) +return NULL; + + /* A frequent case is when the delimiter string contains only one + character. Here we don't need to call the expensive `strpbrk' + function and instead work using `strchr'. */ + if (delim[0] == '\0' || delim[1] == '\0') +{ + char ch = delim[0]; + + if (ch == '\0') + end = NULL; + else + { + if (*begin == ch) + end = begin; + else if (*begin == '\0') + end = NULL; + else + end = strchr (begin + 1, ch); + } +} + else +/* Find the end of the token. */ +end = strpbrk (begin, delim); + + if (end) +{ + /* Terminate the token and set *STRINGP past NUL character. */ + *end++ = '\0'; + *stringp = end; +} + else +/* No more delimiters; this is the last token. */ +*stringp = NULL; + + return begin; +} diff --git a/configure b/configure index d9a101f..ab8357f 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf Checking for strsep... +if ${CC} -o compat/have_strsep $srcdir/compat/have_strsep.c /dev/null 21 +then +printf Yes.\n +have_strsep=1 +else +printf No (will use our own instead).\n +have_strsep=0 +fi +rm -f compat/have_strsep + printf Checking for standard version of getpwuid_r... if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 then @@ -723,6 +734,10 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the strsep function is available (if not, then notmuch will +# build its own version) +HAVE_STRSEP = ${have_strsep} + # Whether the getpwuid_r function is standards-compliant # (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS # to enable the standards-compliant version -- needed for Solaris) @@ -782,12 +797,14 @@ CONFIGURE_CFLAGS =
[PATCH v2 05/10] install: check for non-SysV version (Solaris support)
Solaris ships a program called install in /usr/sbin, which performs a task that's fairly similar to the GNU and BSD install programs but which uses very different command line arguments. In particular, if it is invoked without -c, -f, or -n, it will search the target directory for a file with the same name as the one being installed, and it will only install the file if it finds a matching name. More excitingly, if it doesn't find a match, it will look in /bin, /usr/bin, /etc, /lib, and /usr/lib and try to do the same there. The standard workaround for this is to use GNU install. It is available via the standard Solaris packaging system (in file/gnu-coreutils), and installs itself as /usr/bin/ginstall. This patch adds a check to configure to see if install behaves in a way that's compatible with GNU and BSD install, and if not, it uses a program called ginstall instead. It also modifies configure to set the $(INSTALL) variable, and changes various Makefiles to use it. --- Makefile.local|2 +- completion/Makefile.local |4 ++-- configure | 19 +++ emacs/Makefile.local |6 +++--- lib/Makefile.local|4 ++-- man/Makefile.local|6 +++--- vim/Makefile |6 ++ 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Makefile.local b/Makefile.local index 2b91946..7ccb1cd 100644 --- a/Makefile.local +++ b/Makefile.local @@ -286,7 +286,7 @@ notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME) .PHONY: install install: all install-man mkdir -p $(DESTDIR)$(prefix)/bin/ - install notmuch-shared $(DESTDIR)$(prefix)/bin/notmuch + $(INSTALL) notmuch-shared $(DESTDIR)$(prefix)/bin/notmuch ifeq ($(MAKECMDGOALS), install) @echo @echo Notmuch is now installed to $(DESTDIR)$(prefix) diff --git a/completion/Makefile.local b/completion/Makefile.local index dfc1271..a648a78 100644 --- a/completion/Makefile.local +++ b/completion/Makefile.local @@ -14,9 +14,9 @@ install-$(dir): @echo $@ ifeq ($(WITH_BASH),1) mkdir -p $(DESTDIR)$(bash_completion_dir) - install -m0644 $(bash_script) $(DESTDIR)$(bash_completion_dir)/notmuch + $(INSTALL) -m0644 $(bash_script) $(DESTDIR)$(bash_completion_dir)/notmuch endif ifeq ($(WITH_ZSH),1) mkdir -p $(DESTDIR)$(zsh_completion_dir) - install -m0644 $(zsh_script) $(DESTDIR)$(zsh_completion_dir)/_notmuch + $(INSTALL) -m0644 $(zsh_script) $(DESTDIR)$(zsh_completion_dir)/_notmuch endif diff --git a/configure b/configure index c9da667..d9a101f 100755 --- a/configure +++ b/configure @@ -591,6 +591,21 @@ for flag in -Wmissing-declarations; do done printf \n\t${WARN_CFLAGS}\n +INSTALL=install +printf Checking for working \install\ program... +mkdir _tmp_ +cd _tmp_ +echo 1 1 +mkdir dest +if install 1 dest /dev/null 21 ; then + printf \install\ works fine.\n +else + INSTALL=ginstall + printf using \ginstall\.\n +fi +cd .. +rm -rf _tmp_ + rm -f minimal minimal.c cat EOF @@ -777,4 +792,8 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ \$(LIBNSL_LDFLAGS) + +# Which install program to use +INSTALL = ${INSTALL} + EOF diff --git a/emacs/Makefile.local b/emacs/Makefile.local index fb82247..ee778cb 100644 --- a/emacs/Makefile.local +++ b/emacs/Makefile.local @@ -36,11 +36,11 @@ endif .PHONY: install-emacs install-emacs: mkdir -p $(DESTDIR)$(emacslispdir) - install -m0644 $(emacs_sources) $(DESTDIR)$(emacslispdir) + $(INSTALL) -m0644 $(emacs_sources) $(DESTDIR)$(emacslispdir) ifeq ($(HAVE_EMACS),1) - install -m0644 $(emacs_bytecode) $(DESTDIR)$(emacslispdir) + $(INSTALL) -m0644 $(emacs_bytecode) $(DESTDIR)$(emacslispdir) endif mkdir -p $(DESTDIR)$(emacsetcdir) - install -m0644 $(emacs_images) $(DESTDIR)$(emacsetcdir) + $(INSTALL) -m0644 $(emacs_images) $(DESTDIR)$(emacsetcdir) CLEAN := $(CLEAN) $(emacs_bytecode) diff --git a/lib/Makefile.local b/lib/Makefile.local index 7785944..0c6b258 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -89,11 +89,11 @@ install: install-$(dir) install-$(dir): $(dir)/$(LIBNAME) mkdir -p $(DESTDIR)$(libdir)/ - install -m0644 $(lib)/$(LIBNAME) $(DESTDIR)$(libdir)/ + $(INSTALL) -m0644 $(lib)/$(LIBNAME) $(DESTDIR)$(libdir)/ ln -sf $(LIBNAME) $(DESTDIR)$(libdir)/$(SONAME) ln -sf $(LIBNAME) $(DESTDIR)$(libdir)/$(LINKER_NAME) mkdir -p $(DESTDIR)$(includedir) - install -m0644 $(srcdir)/$(lib)/notmuch.h $(DESTDIR)$(includedir)/ + $(INSTALL) -m0644 $(srcdir)/$(lib)/notmuch.h $(DESTDIR)$(includedir)/ $(LIBRARY_INSTALL_POST_COMMAND) SRCS := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs) diff --git a/man/Makefile.local
[PATCH v2 08/10] notmuch-config: use strchr(), not index() (Solaris support)
notmuch-config.c has the only use of the function named index() in the notmuch source. Several other places use the equivalent function strchr(); this patch just fixes notmuch-config.c to use strchr() instead. (Solaris needs to include strings.h to get the prototype for index(), and notmuch-config.c was failing to include that header, so it wasn't compiling as-is.) --- notmuch-config.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index 3e37a2d..47eb743 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -688,7 +688,7 @@ _item_split (char *item, char **group, char **key) *group = item; -period = index (item, '.'); +period = strchr (item, '.'); if (period == NULL || *(period+1) == '\0') { fprintf (stderr, Invalid configuration name: %s\n -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 07/10] gen-version-script: parse Solaris nm output (Solaris support)
The output of nm on Solaris is substantially different from that on Linux, and the current version of gen-version-script is tied to the Linux nm output. This patch separates the parts of nm processing which are dependent on the output format into a couple shell functions, and makes another shell function to use the appropriate version of c++filt to demangle symbols. It also modifies lib/Makefile.local to pass the generated symbol table correctly to the Solaris linker. --- lib/Makefile.local|4 +++ lib/gen-version-script.sh | 50 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index 0c6b258..2068e4a 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -30,7 +30,11 @@ LIBRARY_SUFFIX = so LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX) SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR) LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE) +ifeq ($(PLATFORM),SOLARIS) +LIBRARY_LINK_FLAG = -shared -Wl,-M notmuch.sym -Wl,-soname=$(SONAME) -Wl,--no-undefined -lc +else LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) -Wl,--no-undefined +endif ifeq ($(PLATFORM),OPENBSD) LIBRARY_LINK_FLAG += -lc endif diff --git a/lib/gen-version-script.sh b/lib/gen-version-script.sh index 76670d5..d7d96da 100644 --- a/lib/gen-version-script.sh +++ b/lib/gen-version-script.sh @@ -1,3 +1,4 @@ +#!/bin/sh # we go through a bit of work to get the unmangled names of the # typeinfo symbols because of @@ -11,10 +12,44 @@ fi HEADER=$1 shift +if [ `uname -s` == SunOS ] ; then +# +# Using Solaris nm, a defined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [15]|128| 16|FUNC |GLOB |0|1 |notmuch_tags_get +# +# and an undefined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [35]| 0| 0|NOTY |GLOB |0|UNDEF |notmuch_tags_get +# +find_xapian_error() { + nawk -F'\|' '$7 !~ UNDEF $8 ~ Xapian.*Error { print $8 }' +} +find_compat_syms() { + nawk -F'\|' '$7 !~ UNDEF $8 ~ get(line|delim) { print $8 ; }' +} +demangle() { + gc++filt $@ +} +else +find_xapian_error() { + awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $3 ~ Xapian.*Error {print $3}' +} +find_compat_syms() { + awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $2 == T $3 ~ ^get(line|delim)$ {print $3 ;}' +} +demangle() { + c++filt $@ +} +fi + printf '{\nglobal:\n' -nm $* | awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $3 ~ Xapian.*Error {print $3}' | sort | uniq | \ -while read sym; do -demangled=$(c++filt $sym) + +# Find the typeinfo for Xapian::*Errors. +nm $* | find_xapian_error | sort | uniq | while read sym; do +demangled=$(demangle $sym) case $demangled in typeinfo*) printf \t$sym;\n @@ -23,6 +58,11 @@ while read sym; do ;; esac done -nm $* | awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $2 == T $3 ~ ^get(line|delim)$ {print $3 ;}' -sed -n 's/^[[:space:]]*\(notmuch_[a-z_]*\)[[:space:]]*(.*/ \1;/p' $HEADER + +# Find the compat syms that we need to export. +nm $* | find_compat_syms + +# Finally, get the real notmuch symbols. +sed -n 's/^[ ]*\(notmuch_[a-z_]*\)[ ]*(.*/ \1;/p' $HEADER + printf local: *;\n};\n -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 09/10] debugger.c: correct return type from getppid() (Solaris support)
Cast the return value of getppid() to int from pid_t in debugger.c, since it is being passed to sprintf(%d), which wants an int argument. On Solaris, pid_t is a long for 32-bit programs. --- debugger.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/debugger.c b/debugger.c index e8b9378..8ff13d6 100644 --- a/debugger.c +++ b/debugger.c @@ -36,7 +36,7 @@ debugger_is_active (void) if (RUNNING_ON_VALGRIND) return TRUE; -sprintf (buf, /proc/%d/exe, getppid ()); +sprintf (buf, /proc/%d/exe, (int) getppid ()); if (readlink (buf, buf, sizeof (buf)) != -1 strncmp (basename (buf), gdb, 3) == 0) { -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 10/10] timegm: add portable implementation (Solaris support)
The timegm(3) function is a non-standard extension to libc which is available in GNU libc and on some BSDs. Although SunOS had this function in its libc, Solaris (unfortunately) removed it. This patch implements a very simple version of timegm() which is good enough for parse-time-string.c. One complication of this fix is that libnotmuch.a includes a call to parse_time_string() from parse-time-vrp.o, and parse_time_string() in libparse-time-string.a is the thing which needs to call timegm(). A straightforward attempt to have the two static libraries reconcile their symbols from one another fails, because the symbols come from different .o's, and the linker only does a single pass on each .a looking for dependencies. To solve this, libparse-time-string includes compat.h, and pulls in .o's from the compat directory, in order to get everything that it needs. --- compat/Makefile.local |4 +++ compat/compat.h | 19 ++-- compat/have_timegm.c |7 ++ compat/timegm.c | 37 + configure | 11 + parse-time-string/Makefile.local |4 ++- parse-time-string/parse-time-string.c |1 + 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 compat/have_timegm.c create mode 100644 compat/timegm.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 2c4f65f..b0d5417 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1) notmuch_compat_srcs += $(dir)/strsep.c endif +ifneq ($(HAVE_TIMEGM),1) +notmuch_compat_srcs += $(dir)/timegm.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index 0b5e465..5a402d5 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -30,6 +30,13 @@ extern C { #endif +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #if !HAVE_GETLINE #include stdio.h #include unistd.h @@ -50,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle); char *strsep(char **stringp, const char *delim); #endif /* !HAVE_STRSEP */ +#if !HAVE_TIMEGM +#include time.h +time_t timegm (struct tm *tm); +#endif /* !HAVE_TIMEGM */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ @@ -58,13 +70,6 @@ char *strsep(char **stringp, const char *delim); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ -#if !STD_GETPWUID -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif -#if !STD_ASCTIME -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif - #ifdef __cplusplus } #endif diff --git a/compat/have_timegm.c b/compat/have_timegm.c new file mode 100644 index 000..b62b793 --- /dev/null +++ b/compat/have_timegm.c @@ -0,0 +1,7 @@ +#include time.h +#include compat.h + +int main() +{ +return (int) timegm((struct tm *)0); +} diff --git a/compat/timegm.c b/compat/timegm.c new file mode 100644 index 000..6d76164 --- /dev/null +++ b/compat/timegm.c @@ -0,0 +1,37 @@ +#include time.h +#include compat.h + +static int +leapyear (int year) +{ +return ((year % 4) == 0 ((year % 100) != 0 || (year % 400) == 0)); +} + +/* + * This is a simple implementation of timegm() which does what is needed + * by create_output() -- just turns the struct tm into a GMT time_t. + * It does not normalize any of the fields of the struct tm, nor does + * it set tm_wday or tm_yday. + */ +time_t +timegm (struct tm *tm) +{ +intmonthlen[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, +}; +intyear, month, days; + +days = 365 * (tm-tm_year - 70); +for (year = 70; year tm-tm_year; year++) { + if (leapyear(1900 + year)) { + days++; + } +} +for (month = 0; month tm-tm_mon; month++) { + days += monthlen[leapyear(1900 + year)][month]; +} +days += tm-tm_mday - 1; + +return days * 24) + tm-tm_hour) * 60 + tm-tm_min) * 60 + tm-tm_sec); +} diff --git a/configure b/configure index ab8357f..f3ec9a2 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/have_strsep +printf Checking for timegm... +if ${CC} -o compat/have_timegm $srcdir/compat/have_timegm.c /dev/null 21 +then +printf Yes.\n +have_timegm=1 +else +printf No (will use our own instead).\n +have_timegm=0 +fi +rm -f compat/have_timegm + printf Checking for standard version of getpwuid_r... if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 then diff --git a/parse-time-string/Makefile.local b/parse-time-string/Makefile.local index 53534f3..c011e0b 100644 --- a/parse-time-string/Makefile.local +++ b/parse-time-string/Makefile.local @@ -1,7 +1,9 @@ dir := parse-time-string
Re: [PATCH v2 05/10] install: check for non-SysV version (Solaris support)
diff --git a/vim/Makefile b/vim/Makefile index f17bebf..7ceba7a 100644 --- a/vim/Makefile +++ b/vim/Makefile @@ -5,8 +5,6 @@ files = plugin/notmuch.vim \ prefix = $(HOME)/.vim destdir = $(prefix)/plugin -INSTALL = install -D -m644 - all: help help: @@ -17,7 +15,7 @@ help: @echo make symlink - create symlinks in ~/.vim (useful for dev elopment) install: - @for x in $(files); do $(INSTALL) $(CURDIR)/$$x $(prefix)/$$x; done + @for x in $(files); do $(INSTALL) -D -m644 $(CURDIR)/$$x $(prefix)/$$x; done -link symlink: INSTALL = ln -fs link symlink: install + @for x in $(files); do ln -fs $(CURDIR)/$$x $(prefix)/$$x; done -- Here you'd need to remove the 'install' dependency as it would first do it and then overwriting the results with dependency. Good catch, thanks; that's what I'll do. I also noticed a couple other things in this file -- I need to include ../Makefile.config to get the definition of $INSTALL, and $destdir isn't used in that Makefile. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 07/10] gen-version-script: parse Solaris nm output (Solaris support)
@@ -11,10 +12,44 @@ fi HEADER=$1 shift +if [ `uname -s` == SunOS ] ; then +# +# Using Solaris nm, a defined symbol looks like this: +# The POSIX / Bourne -comformant equality comparison is '='. Sigh, of course it is. Fixed. e.g. $ ./heirloom-sh/sh -c ' [ a == b ] || echo x' ./heirloom-sh/sh: test: unknown operator == zsh: exit 1 ./heirloom-sh/sh -c ' [ a == b ] || echo x' Interesting that Solaris /bin/sh did not fail there... I was running on Solaris 11.1, which uses ksh93 as its /bin/sh. You're absolutely right that Solaris 10 would fall over, though. Similarly, the following line: demangled=$(demangle $sym) doesn't work on traditional sh. I've replaced $() with ``. Hmm, gen-version-script doesn't have shebang... it is run like: sh $(srcdir)/$(lib)/gen-version-script.sh $ $(libnotmuch_modules) $@ in lib/Makefile.local -- taking sh fron PATH. I updated the first line from the #! invocation to a comment saying # This script is invoked via sh .../gen-version-script.sh. Would a respun version of these patches help toward testing? Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 07/10] gen-version-script: parse Solaris nm output (Solaris support)
Would a respun version of these patches help toward testing? $ grep vim test/* zsh: exit 1 grep vim test/* i.e. no vim tests... Sure -- I was referring to any more general testing you might do. Anyway, thanks for your comments. Barring any more comments I'll probably send out an updated patch set later today. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 00/10] Solaris support
Updated based on comments from Tomi Ollila last week: - Cleaned up the $(INSTALL) changes in vim/Makefile. - Fixed gen-version-script to be compliant with old sh implementation. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 02/10] asctime: check for standards compliance (Solaris support)
Add checks to configure to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for asctime_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file compat/check_asctime.c, which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_asctime.c | 18 ++ compat/compat.h|3 +++ configure | 22 -- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 compat/check_asctime.c diff --git a/compat/check_asctime.c b/compat/check_asctime.c new file mode 100644 index 000..c508fbf --- /dev/null +++ b/compat/check_asctime.c @@ -0,0 +1,18 @@ +/* + * This compatibility check actually succeeds (on Solaris) if + * _POSIX_PTHREAD_SEMANTICS is not defined. But we need to #define that to get + * the right version of getpwuid_r(), so we define it here to ensure that the + * compatibility check ends up doing the same thing as the rest of the code. + */ +#define_POSIX_PTHREAD_SEMANTICS 1 +#include time.h +#include stdio.h + +int main() +{ +struct tm tm; + +(void) asctime_r (tm, NULL, 0); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index efea023..e5f833e 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -57,6 +57,9 @@ char* strcasestr(const char *haystack, const char *needle); #if !STD_GETPWUID #define _POSIX_PTHREAD_SEMANTICS 1 #endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif #ifdef __cplusplus } diff --git a/configure b/configure index bb5031e..d153f57 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/check_getpwuid +printf Checking for standard version of asctime_r... +if ${CC} -o compat/check_asctime $srcdir/compat/check_asctime.c /dev/null 21 +then +printf Yes.\n +std_asctime=1 +else +printf No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n +std_asctime=0 +fi +rm -f compat/check_asctime + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -687,6 +698,11 @@ HAVE_STRCASESTR = ${have_strcasestr} # to enable the standards-compliant version -- needed for Solaris) STD_GETPWUID = ${std_getpwuid} +# Whether the asctime_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_ASCTIME = ${std_asctime} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -733,11 +749,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ - -DSTD_GETPWUID=\$(STD_GETPWUID) + -DSTD_GETPWUID=\$(STD_GETPWUID) \\ + -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ --DSTD_GETPWUID=\$(STD_GETPWUID) +-DSTD_GETPWUID=\$(STD_GETPWUID) \\ +-DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 01/10] getpwuid: check for standards compliance (Solaris support)
Add checks to configure to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for getpwuid_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file compat/check_getpwuid.c, which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_getpwuid.c | 11 +++ compat/compat.h |4 configure | 23 +-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 compat/check_getpwuid.c diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c new file mode 100644 index 000..c435eb8 --- /dev/null +++ b/compat/check_getpwuid.c @@ -0,0 +1,11 @@ +#include stdio.h +#include pwd.h + +int main() +{ +struct passwd passwd, *ignored; + +(void) getpwuid_r (0, passwd, NULL, 0, ignored); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index b2e2736..efea023 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -54,6 +54,10 @@ char* strcasestr(const char *haystack, const char *needle); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #ifdef __cplusplus } #endif diff --git a/configure b/configure index ea8a1ad..bb5031e 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf Checking for standard version of getpwuid_r... +if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 +then +printf Yes.\n +std_getpwuid=1 +else +printf No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n +std_getpwuid=0 +fi +rm -f compat/check_getpwuid + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -671,6 +682,11 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the getpwuid_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_GETPWUID = ${std_getpwuid} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -715,10 +731,13 @@ WITH_ZSH = ${WITH_ZSH} # Combined flags for compiling and linking against all of the above CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ - \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) + \$(VALGRIND_CFLAGS) \\ + -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ + -DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ - -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) +-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ +-DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 04/10] configure: check for -Wl,-rpath (Solaris support)
Add a check to configure to see whether -Wl,-rpath can be used without --enable-new-dtags. Solaris needs the former and doesn't know about the latter. --- configure |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 9707f11..c9da667 100755 --- a/configure +++ b/configure @@ -552,6 +552,10 @@ if ${CC} -Wl,--enable-new-dtags -Wl,-rpath,/tmp/ -o minimal minimal.c /dev/null then printf Yes.\n rpath_ldflags=-Wl,--enable-new-dtags -Wl,-rpath,\$(libdir) +elif ${CC} -Wl,-rpath,/tmp/ -o minimal minimal.c /dev/null 21 +then +printf Yes.\n +rpath_ldflags=-Wl,-rpath,\$(libdir) else printf No (nothing to worry about).\n rpath_ldflags= -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 08/10] notmuch-config: use strchr(), not index() (Solaris support)
notmuch-config.c has the only use of the function named index() in the notmuch source. Several other places use the equivalent function strchr(); this patch just fixes notmuch-config.c to use strchr() instead. (Solaris needs to include strings.h to get the prototype for index(), and notmuch-config.c was failing to include that header, so it wasn't compiling as-is.) --- notmuch-config.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index 3e37a2d..47eb743 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -688,7 +688,7 @@ _item_split (char *item, char **group, char **key) *group = item; -period = index (item, '.'); +period = strchr (item, '.'); if (period == NULL || *(period+1) == '\0') { fprintf (stderr, Invalid configuration name: %s\n -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 03/10] gethostbyname: check for libnsl (Solaris support)
Add a check to configure to see whether -lnsl is needed for programs that are using gethostbyname(). This change also adds the file compat/check_ghbn.c, which configure uses to perform its check. --- compat/check_ghbn.c |9 + configure | 17 - 2 files changed, 25 insertions(+), 1 deletions(-) create mode 100644 compat/check_ghbn.c diff --git a/compat/check_ghbn.c b/compat/check_ghbn.c new file mode 100644 index 000..4858d5c --- /dev/null +++ b/compat/check_ghbn.c @@ -0,0 +1,9 @@ +#include stdio.h +#include netdb.h + +int main() +{ +(void) gethostbyname(NULL); + +return (0); +} diff --git a/configure b/configure index d153f57..9707f11 100755 --- a/configure +++ b/configure @@ -534,6 +534,17 @@ else fi rm -f compat/check_asctime +printf Checking whether libnsl is needed for gethostbyname... +if ${CC} -o compat/check_ghbn $srcdir/compat/check_ghbn.c /dev/null 21 +then +printf No.\n +libnsl_ldflags= +else +printf Yes.\n +libnsl_ldflags=-lnsl +fi +rm -f compat/check_ghbn + printf int main(void){return 0;}\n minimal.c printf Checking for rpath support... @@ -723,6 +734,9 @@ GMIME_LDFLAGS = ${gmime_ldflags} TALLOC_CFLAGS = ${talloc_cflags} TALLOC_LDFLAGS = ${talloc_ldflags} +# Flags needed to get gethostbyname() at link time +LIBNSL_LDFLAGS = ${libnsl_ldflags} + # Flags needed to have linker set rpath attribute RPATH_LDFLAGS = ${rpath_ldflags} @@ -757,5 +771,6 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ -DSTD_GETPWUID=\$(STD_GETPWUID) \\ -DSTD_ASCTIME=\$(STD_ASCTIME) -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ +\$(LIBNSL_LDFLAGS) EOF -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 07/10] gen-version-script: parse Solaris nm output (Solaris support)
The output of nm on Solaris is substantially different from that on Linux, and the current version of gen-version-script is tied to the Linux nm output. This patch separates the parts of nm processing which are dependent on the output format into a couple shell functions, and makes another shell function to use the appropriate version of c++filt to demangle symbols. It also modifies lib/Makefile.local to pass the generated symbol table correctly to the Solaris linker. --- lib/Makefile.local|4 +++ lib/gen-version-script.sh | 50 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index 0c6b258..2068e4a 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -30,7 +30,11 @@ LIBRARY_SUFFIX = so LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX) SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR) LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE) +ifeq ($(PLATFORM),SOLARIS) +LIBRARY_LINK_FLAG = -shared -Wl,-M notmuch.sym -Wl,-soname=$(SONAME) -Wl,--no-undefined -lc +else LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) -Wl,--no-undefined +endif ifeq ($(PLATFORM),OPENBSD) LIBRARY_LINK_FLAG += -lc endif diff --git a/lib/gen-version-script.sh b/lib/gen-version-script.sh index 76670d5..ecf44f0 100644 --- a/lib/gen-version-script.sh +++ b/lib/gen-version-script.sh @@ -1,3 +1,4 @@ +# This script is invoked via sh .../gen-version-script.sh. # we go through a bit of work to get the unmangled names of the # typeinfo symbols because of @@ -11,10 +12,44 @@ fi HEADER=$1 shift +if [ `uname -s` = SunOS ] ; then +# +# Using Solaris nm, a defined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [15]|128| 16|FUNC |GLOB |0|1 |notmuch_tags_get +# +# and an undefined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [35]| 0| 0|NOTY |GLOB |0|UNDEF |notmuch_tags_get +# +find_xapian_error() { + nawk -F'\|' '$7 !~ UNDEF $8 ~ Xapian.*Error { print $8 }' +} +find_compat_syms() { + nawk -F'\|' '$7 !~ UNDEF $8 ~ get(line|delim) { print $8 ; }' +} +demangle() { + gc++filt $@ +} +else +find_xapian_error() { + awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $3 ~ Xapian.*Error {print $3}' +} +find_compat_syms() { + awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $2 == T $3 ~ ^get(line|delim)$ {print $3 ;}' +} +demangle() { + c++filt $@ +} +fi + printf '{\nglobal:\n' -nm $* | awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $3 ~ Xapian.*Error {print $3}' | sort | uniq | \ -while read sym; do -demangled=$(c++filt $sym) + +# Find the typeinfo for Xapian::*Errors. +nm $* | find_xapian_error | sort | uniq | while read sym; do +demangled=`demangle $sym` case $demangled in typeinfo*) printf \t$sym;\n @@ -23,6 +58,11 @@ while read sym; do ;; esac done -nm $* | awk '$1 ~ ^[0-9a-fA-F][0-9a-fA-F]*$ $2 == T $3 ~ ^get(line|delim)$ {print $3 ;}' -sed -n 's/^[[:space:]]*\(notmuch_[a-z_]*\)[[:space:]]*(.*/ \1;/p' $HEADER + +# Find the compat syms that we need to export. +nm $* | find_compat_syms + +# Finally, get the real notmuch symbols. +sed -n 's/^[ ]*\(notmuch_[a-z_]*\)[ ]*(.*/ \1;/p' $HEADER + printf local: *;\n};\n -- 1.7.3.2 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 05/10] install: check for non-SysV version (Solaris support)
Solaris ships a program called install in /usr/sbin, which performs a task that's fairly similar to the GNU and BSD install programs but which uses very different command line arguments. In particular, if it is invoked without -c, -f, or -n, it will search the target directory for a file with the same name as the one being installed, and it will only install the file if it finds a matching name. More excitingly, if it doesn't find a match, it will look in /bin, /usr/bin, /etc, /lib, and /usr/lib and try to do the same there. The standard workaround for this is to use GNU install. It is available via the standard Solaris packaging system (in file/gnu-coreutils), and installs itself as /usr/bin/ginstall. This patch adds a check to configure to see if install behaves in a way that's compatible with GNU and BSD install, and if not, it uses a program called ginstall instead. It also modifies configure to set the $(INSTALL) variable, and changes various Makefiles to use it. --- Makefile.local|2 +- completion/Makefile.local |4 ++-- configure | 19 +++ emacs/Makefile.local |6 +++--- lib/Makefile.local|4 ++-- man/Makefile.local|6 +++--- vim/Makefile | 11 +-- 7 files changed, 35 insertions(+), 17 deletions(-) diff --git a/Makefile.local b/Makefile.local index 2b91946..7ccb1cd 100644 --- a/Makefile.local +++ b/Makefile.local @@ -286,7 +286,7 @@ notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME) .PHONY: install install: all install-man mkdir -p $(DESTDIR)$(prefix)/bin/ - install notmuch-shared $(DESTDIR)$(prefix)/bin/notmuch + $(INSTALL) notmuch-shared $(DESTDIR)$(prefix)/bin/notmuch ifeq ($(MAKECMDGOALS), install) @echo @echo Notmuch is now installed to $(DESTDIR)$(prefix) diff --git a/completion/Makefile.local b/completion/Makefile.local index dfc1271..a648a78 100644 --- a/completion/Makefile.local +++ b/completion/Makefile.local @@ -14,9 +14,9 @@ install-$(dir): @echo $@ ifeq ($(WITH_BASH),1) mkdir -p $(DESTDIR)$(bash_completion_dir) - install -m0644 $(bash_script) $(DESTDIR)$(bash_completion_dir)/notmuch + $(INSTALL) -m0644 $(bash_script) $(DESTDIR)$(bash_completion_dir)/notmuch endif ifeq ($(WITH_ZSH),1) mkdir -p $(DESTDIR)$(zsh_completion_dir) - install -m0644 $(zsh_script) $(DESTDIR)$(zsh_completion_dir)/_notmuch + $(INSTALL) -m0644 $(zsh_script) $(DESTDIR)$(zsh_completion_dir)/_notmuch endif diff --git a/configure b/configure index c9da667..d9a101f 100755 --- a/configure +++ b/configure @@ -591,6 +591,21 @@ for flag in -Wmissing-declarations; do done printf \n\t${WARN_CFLAGS}\n +INSTALL=install +printf Checking for working \install\ program... +mkdir _tmp_ +cd _tmp_ +echo 1 1 +mkdir dest +if install 1 dest /dev/null 21 ; then + printf \install\ works fine.\n +else + INSTALL=ginstall + printf using \ginstall\.\n +fi +cd .. +rm -rf _tmp_ + rm -f minimal minimal.c cat EOF @@ -777,4 +792,8 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ \$(LIBNSL_LDFLAGS) + +# Which install program to use +INSTALL = ${INSTALL} + EOF diff --git a/emacs/Makefile.local b/emacs/Makefile.local index fb82247..ee778cb 100644 --- a/emacs/Makefile.local +++ b/emacs/Makefile.local @@ -36,11 +36,11 @@ endif .PHONY: install-emacs install-emacs: mkdir -p $(DESTDIR)$(emacslispdir) - install -m0644 $(emacs_sources) $(DESTDIR)$(emacslispdir) + $(INSTALL) -m0644 $(emacs_sources) $(DESTDIR)$(emacslispdir) ifeq ($(HAVE_EMACS),1) - install -m0644 $(emacs_bytecode) $(DESTDIR)$(emacslispdir) + $(INSTALL) -m0644 $(emacs_bytecode) $(DESTDIR)$(emacslispdir) endif mkdir -p $(DESTDIR)$(emacsetcdir) - install -m0644 $(emacs_images) $(DESTDIR)$(emacsetcdir) + $(INSTALL) -m0644 $(emacs_images) $(DESTDIR)$(emacsetcdir) CLEAN := $(CLEAN) $(emacs_bytecode) diff --git a/lib/Makefile.local b/lib/Makefile.local index 7785944..0c6b258 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -89,11 +89,11 @@ install: install-$(dir) install-$(dir): $(dir)/$(LIBNAME) mkdir -p $(DESTDIR)$(libdir)/ - install -m0644 $(lib)/$(LIBNAME) $(DESTDIR)$(libdir)/ + $(INSTALL) -m0644 $(lib)/$(LIBNAME) $(DESTDIR)$(libdir)/ ln -sf $(LIBNAME) $(DESTDIR)$(libdir)/$(SONAME) ln -sf $(LIBNAME) $(DESTDIR)$(libdir)/$(LINKER_NAME) mkdir -p $(DESTDIR)$(includedir) - install -m0644 $(srcdir)/$(lib)/notmuch.h $(DESTDIR)$(includedir)/ + $(INSTALL) -m0644 $(srcdir)/$(lib)/notmuch.h $(DESTDIR)$(includedir)/ $(LIBRARY_INSTALL_POST_COMMAND) SRCS := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs) diff --git a/man/Makefile.local
[PATCH v3 10/10] timegm: add portable implementation (Solaris support)
The timegm(3) function is a non-standard extension to libc which is available in GNU libc and on some BSDs. Although SunOS had this function in its libc, Solaris (unfortunately) removed it. This patch implements a very simple version of timegm() which is good enough for parse-time-string.c. One complication of this fix is that libnotmuch.a includes a call to parse_time_string() from parse-time-vrp.o, and parse_time_string() in libparse-time-string.a is the thing which needs to call timegm(). A straightforward attempt to have the two static libraries reconcile their symbols from one another fails, because the symbols come from different .o's, and the linker only does a single pass on each .a looking for dependencies. To solve this, libparse-time-string includes compat.h, and pulls in .o's from the compat directory, in order to get everything that it needs. --- compat/Makefile.local |4 +++ compat/compat.h | 19 ++-- compat/have_timegm.c |7 ++ compat/timegm.c | 37 + configure | 11 + parse-time-string/Makefile.local |4 ++- parse-time-string/parse-time-string.c |1 + 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 compat/have_timegm.c create mode 100644 compat/timegm.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 2c4f65f..b0d5417 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1) notmuch_compat_srcs += $(dir)/strsep.c endif +ifneq ($(HAVE_TIMEGM),1) +notmuch_compat_srcs += $(dir)/timegm.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index 0b5e465..5a402d5 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -30,6 +30,13 @@ extern C { #endif +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #if !HAVE_GETLINE #include stdio.h #include unistd.h @@ -50,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle); char *strsep(char **stringp, const char *delim); #endif /* !HAVE_STRSEP */ +#if !HAVE_TIMEGM +#include time.h +time_t timegm (struct tm *tm); +#endif /* !HAVE_TIMEGM */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ @@ -58,13 +70,6 @@ char *strsep(char **stringp, const char *delim); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ -#if !STD_GETPWUID -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif -#if !STD_ASCTIME -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif - #ifdef __cplusplus } #endif diff --git a/compat/have_timegm.c b/compat/have_timegm.c new file mode 100644 index 000..b62b793 --- /dev/null +++ b/compat/have_timegm.c @@ -0,0 +1,7 @@ +#include time.h +#include compat.h + +int main() +{ +return (int) timegm((struct tm *)0); +} diff --git a/compat/timegm.c b/compat/timegm.c new file mode 100644 index 000..6d76164 --- /dev/null +++ b/compat/timegm.c @@ -0,0 +1,37 @@ +#include time.h +#include compat.h + +static int +leapyear (int year) +{ +return ((year % 4) == 0 ((year % 100) != 0 || (year % 400) == 0)); +} + +/* + * This is a simple implementation of timegm() which does what is needed + * by create_output() -- just turns the struct tm into a GMT time_t. + * It does not normalize any of the fields of the struct tm, nor does + * it set tm_wday or tm_yday. + */ +time_t +timegm (struct tm *tm) +{ +intmonthlen[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, +}; +intyear, month, days; + +days = 365 * (tm-tm_year - 70); +for (year = 70; year tm-tm_year; year++) { + if (leapyear(1900 + year)) { + days++; + } +} +for (month = 0; month tm-tm_mon; month++) { + days += monthlen[leapyear(1900 + year)][month]; +} +days += tm-tm_mday - 1; + +return days * 24) + tm-tm_hour) * 60 + tm-tm_min) * 60 + tm-tm_sec); +} diff --git a/configure b/configure index ab8357f..f3ec9a2 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/have_strsep +printf Checking for timegm... +if ${CC} -o compat/have_timegm $srcdir/compat/have_timegm.c /dev/null 21 +then +printf Yes.\n +have_timegm=1 +else +printf No (will use our own instead).\n +have_timegm=0 +fi +rm -f compat/have_timegm + printf Checking for standard version of getpwuid_r... if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 then diff --git a/parse-time-string/Makefile.local b/parse-time-string/Makefile.local index 53534f3..c011e0b 100644 --- a/parse-time-string/Makefile.local +++ b/parse-time-string/Makefile.local @@ -1,7 +1,9 @@ dir := parse-time-string
[PATCH v3 06/10] strsep: check for availability (Solaris support)
Solaris does not ship a version of the strsep() function. This change adds a check to configure to see whether notmuch needs to provide its own implementation, and if so, it uses the new version in compat/strsep.c (which was copied from Mutt, and apparently before that from glibc). --- compat/Makefile.local |4 +++ compat/compat.h |4 +++ compat/have_strsep.c | 10 +++ compat/strsep.c | 65 + configure | 17 + 5 files changed, 100 insertions(+), 0 deletions(-) create mode 100644 compat/have_strsep.c create mode 100644 compat/strsep.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 13f16cd..2c4f65f 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1) notmuch_compat_srcs += $(dir)/strcasestr.c endif +ifneq ($(HAVE_STRSEP),1) +notmuch_compat_srcs += $(dir)/strsep.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index e5f833e..0b5e465 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -46,6 +46,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp); char* strcasestr(const char *haystack, const char *needle); #endif /* !HAVE_STRCASESTR */ +#if !HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* !HAVE_STRSEP */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ diff --git a/compat/have_strsep.c b/compat/have_strsep.c new file mode 100644 index 000..5bd396c --- /dev/null +++ b/compat/have_strsep.c @@ -0,0 +1,10 @@ +#define _GNU_SOURCE +#include string.h + +int main() +{ +char *found; +char **stringp, const char *delim; + +found = strsep(stringp, delim); +} diff --git a/compat/strsep.c b/compat/strsep.c new file mode 100644 index 000..78ab9e7 --- /dev/null +++ b/compat/strsep.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include string.h + +/* Taken from glibc 2.6.1 */ + +char *strsep (char **stringp, const char *delim) +{ + char *begin, *end; + + begin = *stringp; + if (begin == NULL) +return NULL; + + /* A frequent case is when the delimiter string contains only one + character. Here we don't need to call the expensive `strpbrk' + function and instead work using `strchr'. */ + if (delim[0] == '\0' || delim[1] == '\0') +{ + char ch = delim[0]; + + if (ch == '\0') + end = NULL; + else + { + if (*begin == ch) + end = begin; + else if (*begin == '\0') + end = NULL; + else + end = strchr (begin + 1, ch); + } +} + else +/* Find the end of the token. */ +end = strpbrk (begin, delim); + + if (end) +{ + /* Terminate the token and set *STRINGP past NUL character. */ + *end++ = '\0'; + *stringp = end; +} + else +/* No more delimiters; this is the last token. */ +*stringp = NULL; + + return begin; +} diff --git a/configure b/configure index d9a101f..ab8357f 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf Checking for strsep... +if ${CC} -o compat/have_strsep $srcdir/compat/have_strsep.c /dev/null 21 +then +printf Yes.\n +have_strsep=1 +else +printf No (will use our own instead).\n +have_strsep=0 +fi +rm -f compat/have_strsep + printf Checking for standard version of getpwuid_r... if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 then @@ -723,6 +734,10 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the strsep function is available (if not, then notmuch will +# build its own version) +HAVE_STRSEP = ${have_strsep} + # Whether the getpwuid_r function is standards-compliant # (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS # to enable the standards-compliant version -- needed for Solaris) @@ -782,12 +797,14 @@ CONFIGURE_CFLAGS =
Re: [PATCH v3 00/10] Solaris support
$ gcc compat/have_strsep.c compat/have_strsep.c: In function main: compat/have_strsep.c:7:21: error: expected identifier or ( before const compat/have_strsep.c:9:29: error: delim undeclared (first use in this function) compat/have_strsep.c:9:29: note: each undeclared identifier is reported only once for each function it appears in zsh: exit 1 gcc compat/have_strsep.c --- It is very easy to spot the problem ;) Sigh, yes it is. I started my Solaris port using some patches from someone else who had done previous work on a Solaris port, and obviously I didn't look at the patch very closely. In fact, after fixing have_strsep.c, I saw that I didn't even need it -- Solaris 11 has strsep() in libc. But I'd prefer to clean up this patch and leave the compat version available for those compiling on older versions of Solaris, if that's okay. $ gcc compat/check_asctime.c compat/check_asctime.c: In function main: compat/check_asctime.c:15:5: error: too many arguments to function asctime_r In file included from compat/check_asctime.c:8:0: /usr/include/time.h:266:14: note: declared here zsh: exit 1 gcc compat/check_asctime.c --- the posix-semantics way uses the 2-arg format. The logic of the test setting in this file doesn't open to me. Why not test the same way as in getpwuid_r() case ? Yeah, that's clearly the right thing to do. I was getting odd behavior when I defined _POSIX_PTHREAD_SEMANTICS for getpwuid_r(), and it looks like I fixed it in the wrong direction. Did you happen to notice any other issues besides these two? I'd rather not spam the list with my ten-patch set if there's other silly stuff that needs cleaning up. Thanks again for testing this. Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: crash during saving
I just indexed my mail archive by notmuch and I'm starting to play with mutt-kz. The biggest stopper right now is that mutt cores when set already read mail to new (toggle-new in mutt). Once I try to leave the virtual folder (be it to another folder or because of quitting mutt) it crashes. I haven't had the time yet to investigate deeper, so I'll just post whatever info I have and hope that it will be something obvious for you :) I saw something like that when I was first using mutt-kz as well... it ended up that I had compiled libxapian with one version of gcc (3.4.3 maybe?) and notmuch with 4.5.2, and the C++ runtime libraries were incompatible between the two versions. In my case, any time it tried to throw an exception (e.g. when I removed a tag that was not present) it would die with a similar stack trace. (And, of course, that was on Solaris :) ) Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: crash during saving
Right, so the problem really seems to be in throwing/catching exception. Function _notmuch_message_remove_term is supposed to catch the exception and ignore it. Which does not happen in my case. Yep, that was exactly what I was seeing. On a side note, I wonder, is catching exception faster than going through list of tags to see if given tag exists? Might be interesting to compare. I tried that as a workaround at first (just to get it working, not caring about performance). But I realized that libxapian uses exceptions for a lot of failure modes, and I actually ran into one or two others, so I decided I needed to just get it working. To simplify the problem, you might want to try building a very simple stub version of the whole thing -- i.e. a C program that makes a call to a C-interface liba, which just makes a call into a C++ libb library and tries to catch an exception from it; the libb library would just throw an exception. If that reproduces the problem, that might help you debug your setup. (Again, I eventually settled on using GCC 4.5.2, and didn't have the intestinal fortitude to get Studio working. Especially once I saw problems with C++ exception handling. If you can get it working, more power to you!) Blake ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 4/4] timegm: add portable implementation (Solaris support)
From: Blake Jones bla...@foo.net The timegm(3) function is a non-standard extension to libc which is available in GNU libc and on some BSDs. Although SunOS had this function in its libc, Solaris (unfortunately) removed it. This patch implements a very simple version of timegm() which is good enough for parse-time-string.c. LGTM. Blake Signed-off-by: Vladimir Marek vlma...@volny.cz --- compat/Makefile.local |4 +++ compat/compat.h |5 +++ compat/have_timegm.c |7 compat/timegm.c | 57 + configure | 11 +++ parse-time-string/parse-time-string.c |1 + 6 files changed, 85 insertions(+) create mode 100644 compat/have_timegm.c create mode 100644 compat/timegm.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 2c4f65f..b0d5417 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1) notmuch_compat_srcs += $(dir)/strsep.c endif +ifneq ($(HAVE_TIMEGM),1) +notmuch_compat_srcs += $(dir)/timegm.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index ae762c3..5a402d5 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -57,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle); char *strsep(char **stringp, const char *delim); #endif /* !HAVE_STRSEP */ +#if !HAVE_TIMEGM +#include time.h +time_t timegm (struct tm *tm); +#endif /* !HAVE_TIMEGM */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ diff --git a/compat/have_timegm.c b/compat/have_timegm.c new file mode 100644 index 000..b62b793 --- /dev/null +++ b/compat/have_timegm.c @@ -0,0 +1,7 @@ +#include time.h +#include compat.h + +int main() +{ +return (int) timegm((struct tm *)0); +} diff --git a/compat/timegm.c b/compat/timegm.c new file mode 100644 index 000..213963b --- /dev/null +++ b/compat/timegm.c @@ -0,0 +1,57 @@ +/* timegm.c --- Implementation of replacement timegm function. + Copyright (C) 2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Written by Blake Jones. */ + +#include time.h +#include compat.h + +static int +leapyear (int year) +{ +return ((year % 4) == 0 ((year % 100) != 0 || (year % 400) == 0)); +} + +/* + * This is a simple implementation of timegm() which does what is needed + * by create_output() -- just turns the struct tm into a GMT time_t. + * It does not normalize any of the fields of the struct tm, nor does + * it set tm_wday or tm_yday. + */ +time_t +timegm (struct tm *tm) +{ +int monthlen[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, +}; +int year, month, days; + +days = 365 * (tm-tm_year - 70); +for (year = 70; year tm-tm_year; year++) { + if (leapyear(1900 + year)) { + days++; + } +} +for (month = 0; month tm-tm_mon; month++) { + days += monthlen[leapyear(1900 + year)][month]; +} +days += tm-tm_mday - 1; + +return days * 24) + tm-tm_hour) * 60 + tm-tm_min) * 60 + tm-tm_sec); +} diff --git a/configure b/configure index ac44857..6166917 100755 --- a/configure +++ b/configure @@ -530,6 +530,17 @@ else fi rm -f compat/have_strsep +printf Checking for timegm... +if ${CC} -o compat/have_timegm $srcdir/compat/have_timegm.c /dev/null 21 +then +printf Yes.\n +have_timegm=1 +else +printf No (will use our own instead).\n +have_timegm=0 +fi +rm -f compat/have_timegm + printf Checking for standard version of getpwuid_r... if ${CC} -o compat/check_getpwuid $srcdir/compat/check_getpwuid.c /dev/null 21 then diff --git a/parse-time-string/parse-time-string.c b/parse-time-string/parse-time-string.c index 584067d..ccad422 100644 --- a/parse-time-string/parse-time-string.c +++ b/parse-time-string/parse-time-string.c @@ -32,6 +32,7 @@ #include sys/time.h #include sys/types.h +#include
[PATCH 09/10] debugger.c: correct return type from getppid() (Solaris support)
Cast the return value of getppid() to "int" from "pid_t" in debugger.c, since it is being passed to sprintf("%d"), which wants an "int" argument. On Solaris, "pid_t" is a "long" for 32-bit programs. --- debugger.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debugger.c b/debugger.c index e8b9378..8ff13d6 100644 --- a/debugger.c +++ b/debugger.c @@ -36,7 +36,7 @@ debugger_is_active (void) if (RUNNING_ON_VALGRIND) return TRUE; -sprintf (buf, "/proc/%d/exe", getppid ()); +sprintf (buf, "/proc/%d/exe", (int) getppid ()); if (readlink (buf, buf, sizeof (buf)) != -1 && strncmp (basename (buf), "gdb", 3) == 0) { -- 1.7.9.2
[PATCH 04/10] configure: check for -Wl,-rpath (Solaris support)
Add a check to "configure" to see whether -Wl,-rpath can be used without --enable-new-dtags. Solaris needs the former and doesn't know about the latter. --- configure |4 1 file changed, 4 insertions(+) diff --git a/configure b/configure index 28d4110..5c5139f 100755 --- a/configure +++ b/configure @@ -552,6 +552,10 @@ if ${CC} -Wl,--enable-new-dtags -Wl,-rpath,/tmp/ -o minimal minimal.c >/dev/null then printf "Yes.\n" rpath_ldflags="-Wl,--enable-new-dtags -Wl,-rpath,\$(libdir)" +elif ${CC} -Wl,-rpath,/tmp/ -o minimal minimal.c >/dev/null 2>&1 +then +printf "Yes.\n" +rpath_ldflags="-Wl,-rpath,\$(libdir)" else printf "No (nothing to worry about).\n" rpath_ldflags="" -- 1.7.9.2
[PATCH 08/10] notmuch-config: header for index() prototype (Solaris support)
Linux, FreeBSD, and Solaris all expect to find the prototype for "index()" in . On some operating systems, including is sufficient to get the prototype, but that's not the case on Solaris. This patch just modifies notmuch-config.c to include to get the prototype. --- notmuch-config.c |1 + 1 file changed, 1 insertion(+) diff --git a/notmuch-config.c b/notmuch-config.c index 3e37a2d..2537a65 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -23,6 +23,7 @@ #include #include #include +#include static const char toplevel_config_comment[] = " .notmuch-config - Configuration file for the notmuch mail system\n" -- 1.7.9.2
[PATCH 03/10] gethostbyname: check for libnsl (Solaris support)
Add a check to "configure" to see whether -lnsl is needed for programs that are using gethostbyname(). This change also adds the file "compat/check_ghbn.c", which configure uses to perform its check. --- compat/check_ghbn.c |8 configure | 17 - 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 compat/check_ghbn.c diff --git a/compat/check_ghbn.c b/compat/check_ghbn.c new file mode 100644 index 000..ec5f227 --- /dev/null +++ b/compat/check_ghbn.c @@ -0,0 +1,8 @@ +#include + +int main() +{ +(void) gethostbyname(NULL); + +return (0); +} diff --git a/configure b/configure index 047c011..28d4110 100755 --- a/configure +++ b/configure @@ -534,6 +534,17 @@ else fi rm -f compat/check_asctime +printf "Checking whether libnsl is needed for gethostbyname... " +if ${CC} -o compat/check_ghbn "$srcdir"/compat/check_ghbn.c > /dev/null 2>&1 +then +printf "No.\n" +libnsl_ldflags="" +else +printf "Yes.\n" +libnsl_ldflags="-lnsl" +fi +rm -f compat/check_ghbn + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -723,6 +734,9 @@ GMIME_LDFLAGS = ${gmime_ldflags} TALLOC_CFLAGS = ${talloc_cflags} TALLOC_LDFLAGS = ${talloc_ldflags} +# Flags needed to get gethostbyname() at link time +LIBNSL_LDFLAGS = ${libnsl_ldflags} + # Flags needed to have linker set rpath attribute RPATH_LDFLAGS = ${rpath_ldflags} @@ -757,5 +771,6 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ -DSTD_GETPWUID=\$(STD_GETPWUID) \\ -DSTD_ASCTIME=\$(STD_ASCTIME) -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ +\$(LIBNSL_LDFLAGS) EOF -- 1.7.9.2
[PATCH 10/10] timegm: add portable implementation (Solaris support)
The timegm(3) function is a non-standard extension to libc which is available in GNU libc and on some BSDs. Although SunOS had this function in its libc, Solaris (unfortunately) removed it. This patch implements a very simple version of timegm() which is good enough for parse-time-string.c. Although notmuch's idiom for portability is to test for native availability and put alternate versions in compat/, that approach led to a compilation problem in this case. libnotmuch.a includes a call to parse_time_string() from parse-time-vrp.o, and parse_time_string() in libparse-time-string.a needs to call timegm(). An attempt to create compat/timegm.c caused the link to fail, because libparse-time-string.a acquired a dependency on the new timegm.o in libnotmuch.a, and the linker only does a single pass on each ".a" looking for dependencies. This seems to be the case both for the GNU linker and the Solaris linker. A different possible workaround would have been to include libnotmuch.a multiple times on the link line, but that seemed like a brittle way to track this dependency. --- parse-time-string/parse-time-string.c | 37 - 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/parse-time-string/parse-time-string.c b/parse-time-string/parse-time-string.c index 584067d..28901af 100644 --- a/parse-time-string/parse-time-string.c +++ b/parse-time-string/parse-time-string.c @@ -1315,6 +1315,41 @@ fixup_ampm (struct state *state) return 0; } +static int +leapyear (int year) +{ +return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)); +} + +/* + * This is a simple implementation of timegm() which does what is needed + * by create_output() -- just turns the "struct tm" into a GMT time_t. + * It does not normalize any of the fields of the "struct tm", nor does + * it set tm_wday or tm_yday. + */ +static time_t +local_timegm (struct tm *tm) +{ +intmonthlen[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, +}; +intyear, month, days; + +days = 365 * (tm->tm_year - 70); +for (year = 70; year < tm->tm_year; year++) { + if (leapyear(1900 + year)) { + days++; + } +} +for (month = 0; month < tm->tm_mon; month++) { + days += monthlen[leapyear(1900 + year)][month]; +} +days += tm->tm_mday - 1; + +return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec); +} + /* Combine absolute and relative fields, and round. */ static int create_output (struct state *state, time_t *t_out, const time_t *ref, @@ -1465,7 +1500,7 @@ create_output (struct state *state, time_t *t_out, const time_t *ref, if (is_field_set (state, TM_TZ)) { /* tm is in specified TZ, convert to UTC for timegm(3). */ tm.tm_min -= get_field (state, TM_TZ); - t = timegm (); + t = local_timegm (); } else { /* tm is in local time. */ t = mktime (); -- 1.7.9.2
[PATCH 01/10] getpwuid: check for standards compliance (Solaris support)
Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for getpwuid_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file "compat/check_getpwuid.c", which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_getpwuid.c | 10 ++ compat/compat.h |4 configure | 23 +-- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 compat/check_getpwuid.c diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c new file mode 100644 index 000..5da2590 --- /dev/null +++ b/compat/check_getpwuid.c @@ -0,0 +1,10 @@ +#include + +int main() +{ +struct passwd passwd, *ignored; + +(void) getpwuid_r (0, , NULL, 0, ); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index b2e2736..8374d2f 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -54,6 +54,10 @@ char* strcasestr(const char *haystack, const char *needle); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS +#endif + #ifdef __cplusplus } #endif diff --git a/configure b/configure index ea8a1ad..3c18a45 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf "Checking for standard version of getpwuid_r... " +if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 +then +printf "Yes.\n" +std_getpwuid=1 +else +printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n" +std_getpwuid=0 +fi +rm -f compat/check_getpwuid + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -671,6 +682,11 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the getpwuid_r function is standards-compliant +# (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_GETPWUID = ${std_getpwuid} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -715,10 +731,13 @@ WITH_ZSH = ${WITH_ZSH} # Combined flags for compiling and linking against all of the above CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ - \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) + \$(VALGRIND_CFLAGS) \\ + -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ + -DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ - -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) +-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ +-DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.9.2
[PATCH 07/10] gen-version-script: parse Solaris "nm" output (Solaris support)
The output of "nm" on Solaris is substantially different from that on Linux, and the current version of gen-version-script is tied to the Linux "nm" output. This patch separates the parts of "nm" processing which are dependent on the output format into a couple shell functions, and makes another shell function to use the appropriate version of "c++filt" to demangle symbols. It also modifies lib/Makefile.local to pass the generated symbol table correctly to the Solaris linker. --- lib/Makefile.local|4 lib/gen-version-script.sh | 50 - 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index 0c6b258..2068e4a 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -30,7 +30,11 @@ LIBRARY_SUFFIX = so LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX) SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR) LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE) +ifeq ($(PLATFORM),SOLARIS) +LIBRARY_LINK_FLAG = -shared -Wl,-M notmuch.sym -Wl,-soname=$(SONAME) -Wl,--no-undefined -lc +else LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) -Wl,--no-undefined +endif ifeq ($(PLATFORM),OPENBSD) LIBRARY_LINK_FLAG += -lc endif diff --git a/lib/gen-version-script.sh b/lib/gen-version-script.sh index 76670d5..d7d96da 100644 --- a/lib/gen-version-script.sh +++ b/lib/gen-version-script.sh @@ -1,3 +1,4 @@ +#!/bin/sh # we go through a bit of work to get the unmangled names of the # typeinfo symbols because of @@ -11,10 +12,44 @@ fi HEADER=$1 shift +if [ `uname -s` == SunOS ] ; then +# +# Using Solaris "nm", a defined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [15]|128| 16|FUNC |GLOB |0|1 |notmuch_tags_get +# +# and an undefined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [35]| 0| 0|NOTY |GLOB |0|UNDEF |notmuch_tags_get +# +find_xapian_error() { + nawk -F'\|' '$7 !~ "UNDEF" && $8 ~ "Xapian.*Error" { print $8 }' +} +find_compat_syms() { + nawk -F'\|' '$7 !~ "UNDEF" && $8 ~ "get(line|delim)" { print $8 ";" }' +} +demangle() { + gc++filt "$@" +} +else +find_xapian_error() { + awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $3 ~ "Xapian.*Error" {print $3}' +} +find_compat_syms() { + awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $2 == "T" && $3 ~ "^get(line|delim)$" {print $3 ";"}' +} +demangle() { + c++filt "$@" +} +fi + printf '{\nglobal:\n' -nm $* | awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $3 ~ "Xapian.*Error" {print $3}' | sort | uniq | \ -while read sym; do -demangled=$(c++filt $sym) + +# Find the typeinfo for "Xapian::*Error"s. +nm $* | find_xapian_error | sort | uniq | while read sym; do +demangled=$(demangle $sym) case $demangled in typeinfo*) printf "\t$sym;\n" @@ -23,6 +58,11 @@ while read sym; do ;; esac done -nm $* | awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $2 == "T" && $3 ~ "^get(line|delim)$" {print $3 ";"}' -sed -n 's/^[[:space:]]*\(notmuch_[a-z_]*\)[[:space:]]*(.*/ \1;/p' $HEADER + +# Find the "compat" syms that we need to export. +nm $* | find_compat_syms + +# Finally, get the real notmuch symbols. +sed -n 's/^[ ]*\(notmuch_[a-z_]*\)[ ]*(.*/ \1;/p' $HEADER + printf "local: *;\n};\n" -- 1.7.9.2
[PATCH 02/10] asctime: check for standards compliance (Solaris support)
Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for asctime_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file "compat/check_asctime.c", which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_asctime.c | 17 + compat/compat.h|3 +++ configure | 22 -- 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 compat/check_asctime.c diff --git a/compat/check_asctime.c b/compat/check_asctime.c new file mode 100644 index 000..a595110 --- /dev/null +++ b/compat/check_asctime.c @@ -0,0 +1,17 @@ +/* + * This compatibility check actually succeeds (on Solaris) if + * _POSIX_PTHREAD_SEMANTICS is not defined. But we need to define that to get + * the right version of getpwuid_r(), so we define it here to ensure that the + * compatibility check ends up doing the same thing as the rest of the code. + */ +#define_POSIX_PTHREAD_SEMANTICS +#include + +int main() +{ +struct tm tm; + +(void) asctime_r (, NULL, 0); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index 8374d2f..b750501 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -57,6 +57,9 @@ char* strcasestr(const char *haystack, const char *needle); #if !STD_GETPWUID #define _POSIX_PTHREAD_SEMANTICS #endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS +#endif #ifdef __cplusplus } diff --git a/configure b/configure index 3c18a45..047c011 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/check_getpwuid +printf "Checking for standard version of asctime_r... " +if ${CC} -o compat/check_asctime "$srcdir"/compat/check_asctime.c > /dev/null 2>&1 +then +printf "Yes.\n" +std_asctime=1 +else +printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n" +std_asctime=0 +fi +rm -f compat/check_asctime + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -687,6 +698,11 @@ HAVE_STRCASESTR = ${have_strcasestr} # to enable the standards-compliant version -- needed for Solaris) STD_GETPWUID = ${std_getpwuid} +# Whether the asctime_r function is standards-compliant +# (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_ASCTIME = ${std_asctime} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -733,11 +749,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ - -DSTD_GETPWUID=\$(STD_GETPWUID) + -DSTD_GETPWUID=\$(STD_GETPWUID) \\ + -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ --DSTD_GETPWUID=\$(STD_GETPWUID) +-DSTD_GETPWUID=\$(STD_GETPWUID) \\ +-DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.9.2
[PATCH 06/10] strsep: check for availability (Solaris support)
Solaris does not ship a version of the strsep() function. This change adds a check to "configure" to see whether notmuch needs to provide its own implementation, and if so, it uses the new version in "compat/strsep.c" (which was copied from Mutt, and apparently before that from glibc). --- compat/Makefile.local |4 +++ compat/compat.h |4 +++ compat/have_strsep.c | 10 compat/strsep.c | 65 + configure | 17 + 5 files changed, 100 insertions(+) create mode 100644 compat/have_strsep.c create mode 100644 compat/strsep.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 13f16cd..2c4f65f 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1) notmuch_compat_srcs += $(dir)/strcasestr.c endif +ifneq ($(HAVE_STRSEP),1) +notmuch_compat_srcs += $(dir)/strsep.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index b750501..1fd2723 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -46,6 +46,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp); char* strcasestr(const char *haystack, const char *needle); #endif /* !HAVE_STRCASESTR */ +#if !HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* !HAVE_STRSEP */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ diff --git a/compat/have_strsep.c b/compat/have_strsep.c new file mode 100644 index 000..5bd396c --- /dev/null +++ b/compat/have_strsep.c @@ -0,0 +1,10 @@ +#define _GNU_SOURCE +#include + +int main() +{ +char *found; +char **stringp, const char *delim; + +found = strsep(stringp, delim); +} diff --git a/compat/strsep.c b/compat/strsep.c new file mode 100644 index 000..78ab9e7 --- /dev/null +++ b/compat/strsep.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +/* Taken from glibc 2.6.1 */ + +char *strsep (char **stringp, const char *delim) +{ + char *begin, *end; + + begin = *stringp; + if (begin == NULL) +return NULL; + + /* A frequent case is when the delimiter string contains only one + character. Here we don't need to call the expensive `strpbrk' + function and instead work using `strchr'. */ + if (delim[0] == '\0' || delim[1] == '\0') +{ + char ch = delim[0]; + + if (ch == '\0') + end = NULL; + else + { + if (*begin == ch) + end = begin; + else if (*begin == '\0') + end = NULL; + else + end = strchr (begin + 1, ch); + } +} + else +/* Find the end of the token. */ +end = strpbrk (begin, delim); + + if (end) +{ + /* Terminate the token and set *STRINGP past NUL character. */ + *end++ = '\0'; + *stringp = end; +} + else +/* No more delimiters; this is the last token. */ +*stringp = NULL; + + return begin; +} diff --git a/configure b/configure index dae837e..e519abc 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf "Checking for strsep... " +if ${CC} -o compat/have_strsep "$srcdir"/compat/have_strsep.c > /dev/null 2>&1 +then +printf "Yes.\n" +have_strsep="1" +else +printf "No (will use our own instead).\n" +have_strsep="0" +fi +rm -f compat/have_strsep + printf "Checking for standard version of getpwuid_r... " if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 then @@ -723,6 +734,10 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the strsep function is available (if not, then notmuch will +# build its own version) +HAVE_STRSEP = ${have_strsep} + # Whether the getpwuid_r function is standards-compliant # (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS # to enable the standards-compliant version -- needed for Solaris) @@ -782,12 +797,14 @@ CONFIGURE_CFLAGS =
[PATCH 05/10] install: check for non-SysV version (Solaris support)
Solaris ships a program called "install" in /usr/sbin, which performs a task that's fairly similar to the GNU and BSD "install" programs but which uses very different command line arguments. In particular, if it is invoked without "-c", "-f", or "-n", it will search the target directory for a file with the same name as the one being installed, and it will only install the file if it finds a matching name. More excitingly, if it doesn't find a match, it will look in /bin, /usr/bin, /etc, /lib, and /usr/lib and try to do the same there. The standard workaround for this is to use GNU install. It is available via the standard Solaris packaging system (in "file/gnu-coreutils"), and installs itself as /usr/bin/ginstall. This patch adds a check to "configure" to see if "install" behaves in a way that's compatible with GNU and BSD install, and if not, it uses a program called "ginstall" instead. It also modifies "configure" to set the $(INSTALL) variable, and changes various Makefiles to use it. --- Makefile.local|2 +- completion/Makefile.local |4 ++-- configure | 19 +++ emacs/Makefile.local |6 +++--- lib/Makefile.local|4 ++-- man/Makefile.local|6 +++--- vim/Makefile |6 ++ 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Makefile.local b/Makefile.local index 2b91946..7ccb1cd 100644 --- a/Makefile.local +++ b/Makefile.local @@ -286,7 +286,7 @@ notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME) .PHONY: install install: all install-man mkdir -p "$(DESTDIR)$(prefix)/bin/" - install notmuch-shared "$(DESTDIR)$(prefix)/bin/notmuch" + $(INSTALL) notmuch-shared "$(DESTDIR)$(prefix)/bin/notmuch" ifeq ($(MAKECMDGOALS), install) @echo "" @echo "Notmuch is now installed to $(DESTDIR)$(prefix)" diff --git a/completion/Makefile.local b/completion/Makefile.local index dfc1271..a648a78 100644 --- a/completion/Makefile.local +++ b/completion/Makefile.local @@ -14,9 +14,9 @@ install-$(dir): @echo $@ ifeq ($(WITH_BASH),1) mkdir -p "$(DESTDIR)$(bash_completion_dir)" - install -m0644 $(bash_script) "$(DESTDIR)$(bash_completion_dir)/notmuch" + $(INSTALL) -m0644 $(bash_script) "$(DESTDIR)$(bash_completion_dir)/notmuch" endif ifeq ($(WITH_ZSH),1) mkdir -p "$(DESTDIR)$(zsh_completion_dir)" - install -m0644 $(zsh_script) "$(DESTDIR)$(zsh_completion_dir)/_notmuch" + $(INSTALL) -m0644 $(zsh_script) "$(DESTDIR)$(zsh_completion_dir)/_notmuch" endif diff --git a/configure b/configure index 5c5139f..dae837e 100755 --- a/configure +++ b/configure @@ -591,6 +591,21 @@ for flag in -Wmissing-declarations; do done printf "\n\t${WARN_CFLAGS}\n" +INSTALL="install" +printf "Checking for working \"install\" program... " +mkdir _tmp_ +cd _tmp_ +echo 1 > 1 +mkdir dest +if install 1 dest > /dev/null 2>&1 ; then + printf "\"install\" works fine.\n" +else + INSTALL="ginstall" + printf "using \"ginstall\".\n" +fi +cd .. +rm -rf _tmp_ + rm -f minimal minimal.c cat <
[PATCH 00/10] Solaris support
Hi all, This patch series fixes several issues which are needed to allow notmuch to build on Solaris 11. I've been "testing" it for a month or so by using Karel Zak's fork of mutt along with a copy of notmuch-0.13.2 that I got to compile. After a friend asked for a copy of my setup, I decided to try to get my patches cleaned up enough to submit, so that he wouldn't need to deal with them if he wanted to hack on it. I don't have access to any machines running a modern version of Linux (much less *BSD), so I haven't been able to check whether these changes have broken any other platforms. I've tried to follow the prevailing idiom of compatibility checks and conditionally-set variables, to minimize the impact on other platforms, but it's possible that I overlooked something. I'm really pleased with my experience using notmuch; using it along with the fork of mutt has given me real control of my email for the first time in many years. So I'm happy to offer these changes up in the hopes that they can be useful to others. I'm not subscribed to the mailing list, so please CC me on any comments. I'll also try to watch the web archives of the list just in case. Blake
[PATCH 10/10] timegm: add portable implementation (Solaris support)
Hi Jani, > I'd prefer to use timegm() where available, and the suggested > alternative [1] elsewhere. > > [1] http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.html I considered this alternative, but decided against it because it's completely MT-unsafe. I don't know whether libnotmuch itself is MT-safe, but a process which called this routine in one thread would temporarily throw off any timezone-related work that any other threads were doing, even if they weren't using libnotmuch. > I'll look into the compat build issues when I have a moment. If you do, here's a boiled-down version of the problem that I came up with while investigating it: $ echo 'int main() { extern int foo1(); return foo1(); }' > main.c $ echo 'int foo1() { extern int bar(); return bar(); }' > foo1.c $ echo 'int bar() { extern int foo2(); return foo2(); }' > bar.c $ echo 'int foo2() { return 0; }' > foo2.c $ gcc -c main.c foo1.c bar.c foo2.c $ ar rcs libfoo.a foo1.o foo2.o $ ar rcs libbar.a bar.o $ gcc -o main main.o libfoo.a libbar.a [fails] $ gcc -o main main.o libbar.a libfoo.a [fails] Another alternative would be to just include parse-time-string.o in libnotmuch.a directly; I think that would solve the problem. Blake
[PATCH 10/10] timegm: add portable implementation (Solaris support)
> That is a valid point. Yet it doesn't change the fact that I'd prefer > to use timegm() where available. Internally, glibc uses the same code > to implement both timegm() and mktime(), and I'd hate it if the > results were subtly different depending on whether the time zone was > specified in the input or not. That's fine with me. > That said, I'm not opposed to using your simple timegm() alternative > in the compat code if you think it's good enough to get you going on > Solaris. I think it is, assuming you don't plan to use tm_wday or tm_yday in your parse-time-string code, and that you don't plan to depend on the side effect of timegm() canonicalizing the passed-in "struct tm". > As to solving the compat linking problem, I think the patch at the end > of this message should fix it. Please try that with the regular > notmuch approach to portability. The general idea is to keep > parse-time-string as independent as possible from the rest of notmuch > (possibly turning it into a dynamic library and a package of its own > eventually), but I think including compat.h is an acceptable exception > to make. Yeah, this seems to work. I'll update my patch set accordingly. Blake
[PATCH 08/10] notmuch-config: header for index() prototype (Solaris support)
>> On Sun, 04 Nov 2012, Blake Jones wrote: >>> Linux, FreeBSD, and Solaris all expect to find the prototype for >>> "index()" in . On some operating systems, including >>> is sufficient to get the prototype, but that's not the case >>> on Solaris. This patch just modifies notmuch-config.c to include >>> to get the prototype. >> >> We should probably just nuke index() and use strchr() instead. > > indeed! That was my initial preference, but I didn't know if there was anyone who was committed to the BSD name. Given that two more people think it's a good idea, I'll do that instead. Blake
[PATCH 05/10] install: check for non-SysV version (Solaris support)
> > +INSTALL="install" > > +printf "Checking for working \"install\" program... " > > +mkdir _tmp_ > > This doesn't feel like a hot idea. Out of curiosity, why not? An "install" that behaves as expected is one of the first things that an autoconf-generated "configure" looks for. Now, autoconf-configure implements that check using some assumptions about where things are on different operating systems, but that sort of check runs the risk of becoming stale (see below). > Don't tell me you'd need to create a compatibility script for using > mktemp --tmpdir too... Yes I would, if it were used; not all the world's a GNU. But in the case of mktemp, the widely available "-p" and "-t" options seem to get you most of the way there. The SVR4 "install" in Solaris' /usr/sbin is different enough from the BSD/GNU versions that I wouldn't want to try to emulate it with a wrapper. > Or how about just always using ginstall on Solaris? I'd rather not do that. With the old UCB tools having been EOL'ed [1], /usr/ucb/install (which would have worked) will be going away. There is an open bug in the Sun bug tracking system about moving GNU install to /usr/bin/install, specifically motivated by this change. So while I don't know if/when that bug will be fixed, I would guess [2] that a future release of Solaris may have a BSD/GNU-compatible version of "install" in the default $PATH. Blake [1] http://www.oracle.com/technetwork/systems/end-of-notices/eonsolaris11-392732.html [2] Caveat: I work for Oracle in the Solaris kernel group, but I am not speaking for my employer.
[PATCH 05/10] install: check for non-SysV version (Solaris support)
> On Mon, 05 Nov 2012, Blake Jones wrote: > >> > +INSTALL="install" > >> > +printf "Checking for working \"install\" program... " > >> > +mkdir _tmp_ > >> > >> This doesn't feel like a hot idea. > > > > Out of curiosity, why not? > > Note that I'm only referring to creating temp directories like this to > check for the install tool compatibility; otherwise I'm fine with the > general approach. Sure. But what's wrong with creating a temp directory? The configure script creates plenty of temp files for testing compiler features and library symbol availability. Blake
[PATCH 10/10] timegm: add portable implementation (Solaris support)
> Yet another idea for an alternative. Compile by entering 'sh xtimegm.c' > and then run ./xtimegm > > Simple cases seems to work. Dst change may (or then may not) give one > hour difference to the expected. The test "coverage" could be easily > expanded to that ;) > > Hmm, I also found this: > http://lists.gnu.org/archive/html/bug-gnulib/2003-09/msg4.html > which does 2 mktime's and one gmtime_r (without allocating tg!)... > Pick any of these 3 -- or something different (e.g. less NIH if there is) Of these two, I would probably lean slightly toward the latter, in that it relies more on libc for the time zone handling logic. But in general, this seems to me like a case where an explicit implementation like mine is less prone to failure, because it doesn't need to worry about time zones at all. The other approaches rely on letting libc do all the hard work of time zone manipulation, and then reading the tea leaves to find a way to undo it. I would guess that if some change in the time standards is going to break one of these implementations, it's going to be some new time zone specification, not a change in the number of days in a month. :) For what it's worth, I used the attached program to test my implementation, and it passed. Blake -- next part -- #include static int leapyear(int year) { return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)); } /* * This is a simple implementation of timegm() which does what is needed * by parse-time-string.c -- just turns the "struct tm" into a GMT time_t. * It does not normalize any of the fields of the "struct tm", nor does * it set tm_wday or tm_yday. */ static time_t timegm(struct tm *tm) { int monthlen[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, }; int year, month, days; days = 365 * (tm->tm_year - 70); for (year = 70; year < tm->tm_year; year++) { if (leapyear(1900 + year)) { days++; } } for (month = 0; month < tm->tm_mon; month++) { days += monthlen[leapyear(1900 + year)][month]; } days += tm->tm_mday - 1; return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec); } #include #include #include void tm_test(int niter) { const int monthlen[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, }; int i; struct tm tm, *tmp; time_t t; for (i = 0; i < niter; i++) { tm.tm_year = (lrand48() % 67) + 70; tm.tm_mon = lrand48() % 12; do { t = (lrand48() % 31) + 1; } while (t > monthlen[leapyear(1900 + tm.tm_year)][tm.tm_mon]); tm.tm_mday = t; tm.tm_hour = lrand48() % 24; tm.tm_min = lrand48() % 60; tm.tm_sec = lrand48() % 60; t = timegm(); tmp = gmtime(); if (tmp->tm_sec != tm.tm_sec || tmp->tm_min != tm.tm_min || tmp->tm_hour != tm.tm_hour || tmp->tm_mday != tm.tm_mday || tmp->tm_mon != tm.tm_mon || tmp->tm_year != tm.tm_year) { printf("%4d-%02d-%02d %02d:%02d:%02d -> " "%4d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); } } } void time_test(int niter) { int i; time_t st, et; struct tm *tmp; for (i = 0; i < niter; i++) { st = (time_t)lrand48(); tmp = gmtime(); et = timegm(tmp); if (st != et) { printf("%d -> %d (%4d-%02d-%02d %02d:%02d:%02d)\n", st, et, tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); } } } int main(void) { const int niter = 1000; srand48(getpid()); tm_test(niter); time_test(niter); return (0); }
[PATCH 10/10] timegm: add portable implementation (Solaris support)
>> The other approaches rely on letting libc do all the hard work of >> time zone manipulation, and then reading the tea leaves to find a way >> to undo it. > > Did you look at the gnu libc version -- I bet it is pretty hairy... I didn't look at either the GNU or the Solaris libc version. But the file that implements the timezone handling (and localtime(), mktime(), etc.) in Solaris' libc is nearly 3000 lines of code, so I suspect there's an awful lot of stuff going on. >> For what it's worth, I used the attached program to test my >> implementation, and it passed. > > Thanks, It's nice to see your simple implementation passes these > tests... > > Just for curiosity: What do you think lacks in your timegm() that it > could not be promoted as 'complete timegm() solution'. Well, since there isn't a standard for timegm(), I'm comparing it to what glibc and BSD do. The glibc mktime() man page, for example, mentions that mktime() modifies the fields of the tm structure as follows: - tm_wday and tm_yday are set to values determined from the contents of the other fields - if structure members are outside their valid interval, they will be normalized (so that, for example, 40 October is changed into 9 November) - tm_isdst is set (regardless of its initial value) to a positive value or to 0, respectively, to indicate whether DST is or is not in effect at the specified time. - Calling mktime() also sets the external variable tzname with information about the current timezone. The corresponding timegm() man page for glibc doesn't say whether timegm() does the same thing, but I would assume it does. The FreeBSD timegm() man page says that its version does update the fields of the "tm" structure, like its mktime() implementation. My implementation of timegm() does none of these things. It treats the passed-in "struct tm" as constant, and just returns a valid time_t. If you really wanted to make this mktime() be as capable as the ones in the GNU and BSD libc's, you could have it turn around and call gmtime_r() on the generated time_t, and pass the original "struct tm" to gmtime_r(). Personally, I think this is unnecessary overloading of a function that does this one thing just fine, and in practice Jani's code doesn't seem to need it, so I didn't bother. > In any way, including this timegm() function in compat suits me fine. Great. Blake
[PATCH 00/10] Solaris support
> Just now I don't have more time to comment and review more, but in the > first 2/3 patches when I tried to compile I got problem NULL not > defined. Oh! Yes, I should include to pull in the definition of NULL. I'll fix that. > Another thing: you have this > > +# Whether the asctime_r function is standards-compliant > +# (if not, then notmuch will compile with -D_POSIX_PTHREAD_SEMANTICS > +# to enable the standards-compliant version -- needed for Solaris) > > which is not exactly so.. you added the following lines in compat.h > > +#if !STD_GETPWUID > +#define _POSIX_PTHREAD_SEMANTICS > +#endif > > which is slightly different as -D_POSIX_PTHREAD_SEMANTICS is equivalent to > #define _POSIX_PTHREAD_SEMANTICS 1 > > (you probably knew this and your comments have drifted from actual > implementation but just to make sure) I'll make the code and comment line up better. Thanks for your comments. Blake
[PATCH v2 00/10] Solaris support
Thanks to Jani Nikula and Tomi Ollila for their comments. Changes since last version: - Add feature test for timegm(); move portable implementation of timegm() into compat/, change libparse-time-string to pull in .o's from compat/. - Include in compat/check_*.c, to get definition of NULL. - Explicitly define _POSIX_PTHREAD_SEMANTICS to 1 in compat.h. - Call strchr() rather than index() in notmuch-config.c. Blake
[PATCH v2 01/10] getpwuid: check for standards compliance (Solaris support)
Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for getpwuid_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file "compat/check_getpwuid.c", which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_getpwuid.c | 11 +++ compat/compat.h |4 configure | 23 +-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 compat/check_getpwuid.c diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c new file mode 100644 index 000..c435eb8 --- /dev/null +++ b/compat/check_getpwuid.c @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ +struct passwd passwd, *ignored; + +(void) getpwuid_r (0, , NULL, 0, ); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index b2e2736..efea023 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -54,6 +54,10 @@ char* strcasestr(const char *haystack, const char *needle); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #ifdef __cplusplus } #endif diff --git a/configure b/configure index ea8a1ad..bb5031e 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf "Checking for standard version of getpwuid_r... " +if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 +then +printf "Yes.\n" +std_getpwuid=1 +else +printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n" +std_getpwuid=0 +fi +rm -f compat/check_getpwuid + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -671,6 +682,11 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the getpwuid_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_GETPWUID = ${std_getpwuid} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -715,10 +731,13 @@ WITH_ZSH = ${WITH_ZSH} # Combined flags for compiling and linking against all of the above CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ - \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) + \$(VALGRIND_CFLAGS) \\ + -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ + -DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ - -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) +-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ +-DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2
[PATCH v2 02/10] asctime: check for standards compliance (Solaris support)
Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for asctime_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file "compat/check_asctime.c", which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_asctime.c | 18 ++ compat/compat.h|3 +++ configure | 22 -- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 compat/check_asctime.c diff --git a/compat/check_asctime.c b/compat/check_asctime.c new file mode 100644 index 000..c508fbf --- /dev/null +++ b/compat/check_asctime.c @@ -0,0 +1,18 @@ +/* + * This compatibility check actually succeeds (on Solaris) if + * _POSIX_PTHREAD_SEMANTICS is not defined. But we need to #define that to get + * the right version of getpwuid_r(), so we define it here to ensure that the + * compatibility check ends up doing the same thing as the rest of the code. + */ +#define_POSIX_PTHREAD_SEMANTICS 1 +#include +#include + +int main() +{ +struct tm tm; + +(void) asctime_r (, NULL, 0); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index efea023..e5f833e 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -57,6 +57,9 @@ char* strcasestr(const char *haystack, const char *needle); #if !STD_GETPWUID #define _POSIX_PTHREAD_SEMANTICS 1 #endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif #ifdef __cplusplus } diff --git a/configure b/configure index bb5031e..d153f57 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/check_getpwuid +printf "Checking for standard version of asctime_r... " +if ${CC} -o compat/check_asctime "$srcdir"/compat/check_asctime.c > /dev/null 2>&1 +then +printf "Yes.\n" +std_asctime=1 +else +printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n" +std_asctime=0 +fi +rm -f compat/check_asctime + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -687,6 +698,11 @@ HAVE_STRCASESTR = ${have_strcasestr} # to enable the standards-compliant version -- needed for Solaris) STD_GETPWUID = ${std_getpwuid} +# Whether the asctime_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_ASCTIME = ${std_asctime} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -733,11 +749,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ - -DSTD_GETPWUID=\$(STD_GETPWUID) + -DSTD_GETPWUID=\$(STD_GETPWUID) \\ + -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ --DSTD_GETPWUID=\$(STD_GETPWUID) +-DSTD_GETPWUID=\$(STD_GETPWUID) \\ +-DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2
[PATCH v2 03/10] gethostbyname: check for libnsl (Solaris support)
Add a check to "configure" to see whether -lnsl is needed for programs that are using gethostbyname(). This change also adds the file "compat/check_ghbn.c", which configure uses to perform its check. --- compat/check_ghbn.c |9 + configure | 17 - 2 files changed, 25 insertions(+), 1 deletions(-) create mode 100644 compat/check_ghbn.c diff --git a/compat/check_ghbn.c b/compat/check_ghbn.c new file mode 100644 index 000..4858d5c --- /dev/null +++ b/compat/check_ghbn.c @@ -0,0 +1,9 @@ +#include +#include + +int main() +{ +(void) gethostbyname(NULL); + +return (0); +} diff --git a/configure b/configure index d153f57..9707f11 100755 --- a/configure +++ b/configure @@ -534,6 +534,17 @@ else fi rm -f compat/check_asctime +printf "Checking whether libnsl is needed for gethostbyname... " +if ${CC} -o compat/check_ghbn "$srcdir"/compat/check_ghbn.c > /dev/null 2>&1 +then +printf "No.\n" +libnsl_ldflags="" +else +printf "Yes.\n" +libnsl_ldflags="-lnsl" +fi +rm -f compat/check_ghbn + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -723,6 +734,9 @@ GMIME_LDFLAGS = ${gmime_ldflags} TALLOC_CFLAGS = ${talloc_cflags} TALLOC_LDFLAGS = ${talloc_ldflags} +# Flags needed to get gethostbyname() at link time +LIBNSL_LDFLAGS = ${libnsl_ldflags} + # Flags needed to have linker set rpath attribute RPATH_LDFLAGS = ${rpath_ldflags} @@ -757,5 +771,6 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ -DSTD_GETPWUID=\$(STD_GETPWUID) \\ -DSTD_ASCTIME=\$(STD_ASCTIME) -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ +\$(LIBNSL_LDFLAGS) EOF -- 1.7.3.2
[PATCH v2 04/10] configure: check for -Wl,-rpath (Solaris support)
Add a check to "configure" to see whether -Wl,-rpath can be used without --enable-new-dtags. Solaris needs the former and doesn't know about the latter. --- configure |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 9707f11..c9da667 100755 --- a/configure +++ b/configure @@ -552,6 +552,10 @@ if ${CC} -Wl,--enable-new-dtags -Wl,-rpath,/tmp/ -o minimal minimal.c >/dev/null then printf "Yes.\n" rpath_ldflags="-Wl,--enable-new-dtags -Wl,-rpath,\$(libdir)" +elif ${CC} -Wl,-rpath,/tmp/ -o minimal minimal.c >/dev/null 2>&1 +then +printf "Yes.\n" +rpath_ldflags="-Wl,-rpath,\$(libdir)" else printf "No (nothing to worry about).\n" rpath_ldflags="" -- 1.7.3.2
[PATCH v2 06/10] strsep: check for availability (Solaris support)
Solaris does not ship a version of the strsep() function. This change adds a check to "configure" to see whether notmuch needs to provide its own implementation, and if so, it uses the new version in "compat/strsep.c" (which was copied from Mutt, and apparently before that from glibc). --- compat/Makefile.local |4 +++ compat/compat.h |4 +++ compat/have_strsep.c | 10 +++ compat/strsep.c | 65 + configure | 17 + 5 files changed, 100 insertions(+), 0 deletions(-) create mode 100644 compat/have_strsep.c create mode 100644 compat/strsep.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 13f16cd..2c4f65f 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1) notmuch_compat_srcs += $(dir)/strcasestr.c endif +ifneq ($(HAVE_STRSEP),1) +notmuch_compat_srcs += $(dir)/strsep.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index e5f833e..0b5e465 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -46,6 +46,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp); char* strcasestr(const char *haystack, const char *needle); #endif /* !HAVE_STRCASESTR */ +#if !HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* !HAVE_STRSEP */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ diff --git a/compat/have_strsep.c b/compat/have_strsep.c new file mode 100644 index 000..5bd396c --- /dev/null +++ b/compat/have_strsep.c @@ -0,0 +1,10 @@ +#define _GNU_SOURCE +#include + +int main() +{ +char *found; +char **stringp, const char *delim; + +found = strsep(stringp, delim); +} diff --git a/compat/strsep.c b/compat/strsep.c new file mode 100644 index 000..78ab9e7 --- /dev/null +++ b/compat/strsep.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +/* Taken from glibc 2.6.1 */ + +char *strsep (char **stringp, const char *delim) +{ + char *begin, *end; + + begin = *stringp; + if (begin == NULL) +return NULL; + + /* A frequent case is when the delimiter string contains only one + character. Here we don't need to call the expensive `strpbrk' + function and instead work using `strchr'. */ + if (delim[0] == '\0' || delim[1] == '\0') +{ + char ch = delim[0]; + + if (ch == '\0') + end = NULL; + else + { + if (*begin == ch) + end = begin; + else if (*begin == '\0') + end = NULL; + else + end = strchr (begin + 1, ch); + } +} + else +/* Find the end of the token. */ +end = strpbrk (begin, delim); + + if (end) +{ + /* Terminate the token and set *STRINGP past NUL character. */ + *end++ = '\0'; + *stringp = end; +} + else +/* No more delimiters; this is the last token. */ +*stringp = NULL; + + return begin; +} diff --git a/configure b/configure index d9a101f..ab8357f 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf "Checking for strsep... " +if ${CC} -o compat/have_strsep "$srcdir"/compat/have_strsep.c > /dev/null 2>&1 +then +printf "Yes.\n" +have_strsep="1" +else +printf "No (will use our own instead).\n" +have_strsep="0" +fi +rm -f compat/have_strsep + printf "Checking for standard version of getpwuid_r... " if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 then @@ -723,6 +734,10 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the strsep function is available (if not, then notmuch will +# build its own version) +HAVE_STRSEP = ${have_strsep} + # Whether the getpwuid_r function is standards-compliant # (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS # to enable the standards-compliant version -- needed for Solaris) @@ -782,12 +797,14 @@ CONFIGURE_CFLAGS =
[PATCH v2 05/10] install: check for non-SysV version (Solaris support)
Solaris ships a program called "install" in /usr/sbin, which performs a task that's fairly similar to the GNU and BSD "install" programs but which uses very different command line arguments. In particular, if it is invoked without "-c", "-f", or "-n", it will search the target directory for a file with the same name as the one being installed, and it will only install the file if it finds a matching name. More excitingly, if it doesn't find a match, it will look in /bin, /usr/bin, /etc, /lib, and /usr/lib and try to do the same there. The standard workaround for this is to use GNU install. It is available via the standard Solaris packaging system (in "file/gnu-coreutils"), and installs itself as /usr/bin/ginstall. This patch adds a check to "configure" to see if "install" behaves in a way that's compatible with GNU and BSD install, and if not, it uses a program called "ginstall" instead. It also modifies "configure" to set the $(INSTALL) variable, and changes various Makefiles to use it. --- Makefile.local|2 +- completion/Makefile.local |4 ++-- configure | 19 +++ emacs/Makefile.local |6 +++--- lib/Makefile.local|4 ++-- man/Makefile.local|6 +++--- vim/Makefile |6 ++ 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Makefile.local b/Makefile.local index 2b91946..7ccb1cd 100644 --- a/Makefile.local +++ b/Makefile.local @@ -286,7 +286,7 @@ notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME) .PHONY: install install: all install-man mkdir -p "$(DESTDIR)$(prefix)/bin/" - install notmuch-shared "$(DESTDIR)$(prefix)/bin/notmuch" + $(INSTALL) notmuch-shared "$(DESTDIR)$(prefix)/bin/notmuch" ifeq ($(MAKECMDGOALS), install) @echo "" @echo "Notmuch is now installed to $(DESTDIR)$(prefix)" diff --git a/completion/Makefile.local b/completion/Makefile.local index dfc1271..a648a78 100644 --- a/completion/Makefile.local +++ b/completion/Makefile.local @@ -14,9 +14,9 @@ install-$(dir): @echo $@ ifeq ($(WITH_BASH),1) mkdir -p "$(DESTDIR)$(bash_completion_dir)" - install -m0644 $(bash_script) "$(DESTDIR)$(bash_completion_dir)/notmuch" + $(INSTALL) -m0644 $(bash_script) "$(DESTDIR)$(bash_completion_dir)/notmuch" endif ifeq ($(WITH_ZSH),1) mkdir -p "$(DESTDIR)$(zsh_completion_dir)" - install -m0644 $(zsh_script) "$(DESTDIR)$(zsh_completion_dir)/_notmuch" + $(INSTALL) -m0644 $(zsh_script) "$(DESTDIR)$(zsh_completion_dir)/_notmuch" endif diff --git a/configure b/configure index c9da667..d9a101f 100755 --- a/configure +++ b/configure @@ -591,6 +591,21 @@ for flag in -Wmissing-declarations; do done printf "\n\t${WARN_CFLAGS}\n" +INSTALL="install" +printf "Checking for working \"install\" program... " +mkdir _tmp_ +cd _tmp_ +echo 1 > 1 +mkdir dest +if install 1 dest > /dev/null 2>&1 ; then + printf "\"install\" works fine.\n" +else + INSTALL="ginstall" + printf "using \"ginstall\".\n" +fi +cd .. +rm -rf _tmp_ + rm -f minimal minimal.c cat <
[PATCH v2 08/10] notmuch-config: use strchr(), not index() (Solaris support)
notmuch-config.c has the only use of the function named "index()" in the notmuch source. Several other places use the equivalent function "strchr()"; this patch just fixes notmuch-config.c to use strchr() instead. (Solaris needs to include to get the prototype for index(), and notmuch-config.c was failing to include that header, so it wasn't compiling as-is.) --- notmuch-config.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index 3e37a2d..47eb743 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -688,7 +688,7 @@ _item_split (char *item, char **group, char **key) *group = item; -period = index (item, '.'); +period = strchr (item, '.'); if (period == NULL || *(period+1) == '\0') { fprintf (stderr, "Invalid configuration name: %s\n" -- 1.7.3.2
[PATCH v2 07/10] gen-version-script: parse Solaris "nm" output (Solaris support)
The output of "nm" on Solaris is substantially different from that on Linux, and the current version of gen-version-script is tied to the Linux "nm" output. This patch separates the parts of "nm" processing which are dependent on the output format into a couple shell functions, and makes another shell function to use the appropriate version of "c++filt" to demangle symbols. It also modifies lib/Makefile.local to pass the generated symbol table correctly to the Solaris linker. --- lib/Makefile.local|4 +++ lib/gen-version-script.sh | 50 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index 0c6b258..2068e4a 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -30,7 +30,11 @@ LIBRARY_SUFFIX = so LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX) SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR) LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE) +ifeq ($(PLATFORM),SOLARIS) +LIBRARY_LINK_FLAG = -shared -Wl,-M notmuch.sym -Wl,-soname=$(SONAME) -Wl,--no-undefined -lc +else LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) -Wl,--no-undefined +endif ifeq ($(PLATFORM),OPENBSD) LIBRARY_LINK_FLAG += -lc endif diff --git a/lib/gen-version-script.sh b/lib/gen-version-script.sh index 76670d5..d7d96da 100644 --- a/lib/gen-version-script.sh +++ b/lib/gen-version-script.sh @@ -1,3 +1,4 @@ +#!/bin/sh # we go through a bit of work to get the unmangled names of the # typeinfo symbols because of @@ -11,10 +12,44 @@ fi HEADER=$1 shift +if [ `uname -s` == SunOS ] ; then +# +# Using Solaris "nm", a defined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [15]|128| 16|FUNC |GLOB |0|1 |notmuch_tags_get +# +# and an undefined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [35]| 0| 0|NOTY |GLOB |0|UNDEF |notmuch_tags_get +# +find_xapian_error() { + nawk -F'\|' '$7 !~ "UNDEF" && $8 ~ "Xapian.*Error" { print $8 }' +} +find_compat_syms() { + nawk -F'\|' '$7 !~ "UNDEF" && $8 ~ "get(line|delim)" { print $8 ";" }' +} +demangle() { + gc++filt "$@" +} +else +find_xapian_error() { + awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $3 ~ "Xapian.*Error" {print $3}' +} +find_compat_syms() { + awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $2 == "T" && $3 ~ "^get(line|delim)$" {print $3 ";"}' +} +demangle() { + c++filt "$@" +} +fi + printf '{\nglobal:\n' -nm $* | awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $3 ~ "Xapian.*Error" {print $3}' | sort | uniq | \ -while read sym; do -demangled=$(c++filt $sym) + +# Find the typeinfo for "Xapian::*Error"s. +nm $* | find_xapian_error | sort | uniq | while read sym; do +demangled=$(demangle $sym) case $demangled in typeinfo*) printf "\t$sym;\n" @@ -23,6 +58,11 @@ while read sym; do ;; esac done -nm $* | awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $2 == "T" && $3 ~ "^get(line|delim)$" {print $3 ";"}' -sed -n 's/^[[:space:]]*\(notmuch_[a-z_]*\)[[:space:]]*(.*/ \1;/p' $HEADER + +# Find the "compat" syms that we need to export. +nm $* | find_compat_syms + +# Finally, get the real notmuch symbols. +sed -n 's/^[ ]*\(notmuch_[a-z_]*\)[ ]*(.*/ \1;/p' $HEADER + printf "local: *;\n};\n" -- 1.7.3.2
[PATCH v2 09/10] debugger.c: correct return type from getppid() (Solaris support)
Cast the return value of getppid() to "int" from "pid_t" in debugger.c, since it is being passed to sprintf("%d"), which wants an "int" argument. On Solaris, "pid_t" is a "long" for 32-bit programs. --- debugger.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/debugger.c b/debugger.c index e8b9378..8ff13d6 100644 --- a/debugger.c +++ b/debugger.c @@ -36,7 +36,7 @@ debugger_is_active (void) if (RUNNING_ON_VALGRIND) return TRUE; -sprintf (buf, "/proc/%d/exe", getppid ()); +sprintf (buf, "/proc/%d/exe", (int) getppid ()); if (readlink (buf, buf, sizeof (buf)) != -1 && strncmp (basename (buf), "gdb", 3) == 0) { -- 1.7.3.2
[PATCH v2 10/10] timegm: add portable implementation (Solaris support)
The timegm(3) function is a non-standard extension to libc which is available in GNU libc and on some BSDs. Although SunOS had this function in its libc, Solaris (unfortunately) removed it. This patch implements a very simple version of timegm() which is good enough for parse-time-string.c. One complication of this fix is that libnotmuch.a includes a call to parse_time_string() from parse-time-vrp.o, and parse_time_string() in libparse-time-string.a is the thing which needs to call timegm(). A straightforward attempt to have the two static libraries reconcile their symbols from one another fails, because the symbols come from different .o's, and the linker only does a single pass on each ".a" looking for dependencies. To solve this, libparse-time-string includes "compat.h", and pulls in .o's from the compat directory, in order to get everything that it needs. --- compat/Makefile.local |4 +++ compat/compat.h | 19 ++-- compat/have_timegm.c |7 ++ compat/timegm.c | 37 + configure | 11 + parse-time-string/Makefile.local |4 ++- parse-time-string/parse-time-string.c |1 + 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 compat/have_timegm.c create mode 100644 compat/timegm.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 2c4f65f..b0d5417 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1) notmuch_compat_srcs += $(dir)/strsep.c endif +ifneq ($(HAVE_TIMEGM),1) +notmuch_compat_srcs += $(dir)/timegm.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index 0b5e465..5a402d5 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -30,6 +30,13 @@ extern "C" { #endif +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #if !HAVE_GETLINE #include #include @@ -50,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle); char *strsep(char **stringp, const char *delim); #endif /* !HAVE_STRSEP */ +#if !HAVE_TIMEGM +#include +time_t timegm (struct tm *tm); +#endif /* !HAVE_TIMEGM */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ @@ -58,13 +70,6 @@ char *strsep(char **stringp, const char *delim); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ -#if !STD_GETPWUID -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif -#if !STD_ASCTIME -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif - #ifdef __cplusplus } #endif diff --git a/compat/have_timegm.c b/compat/have_timegm.c new file mode 100644 index 000..b62b793 --- /dev/null +++ b/compat/have_timegm.c @@ -0,0 +1,7 @@ +#include +#include "compat.h" + +int main() +{ +return (int) timegm((struct tm *)0); +} diff --git a/compat/timegm.c b/compat/timegm.c new file mode 100644 index 000..6d76164 --- /dev/null +++ b/compat/timegm.c @@ -0,0 +1,37 @@ +#include +#include "compat.h" + +static int +leapyear (int year) +{ +return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)); +} + +/* + * This is a simple implementation of timegm() which does what is needed + * by create_output() -- just turns the "struct tm" into a GMT time_t. + * It does not normalize any of the fields of the "struct tm", nor does + * it set tm_wday or tm_yday. + */ +time_t +timegm (struct tm *tm) +{ +intmonthlen[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, +}; +intyear, month, days; + +days = 365 * (tm->tm_year - 70); +for (year = 70; year < tm->tm_year; year++) { + if (leapyear(1900 + year)) { + days++; + } +} +for (month = 0; month < tm->tm_mon; month++) { + days += monthlen[leapyear(1900 + year)][month]; +} +days += tm->tm_mday - 1; + +return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec); +} diff --git a/configure b/configure index ab8357f..f3ec9a2 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/have_strsep +printf "Checking for timegm... " +if ${CC} -o compat/have_timegm "$srcdir"/compat/have_timegm.c > /dev/null 2>&1 +then +printf "Yes.\n" +have_timegm="1" +else +printf "No (will use our own instead).\n" +have_timegm="0" +fi +rm -f compat/have_timegm + printf "Checking for standard version of getpwuid_r... " if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 then diff --git a/parse-time-string/Makefile.local b/parse-time-string/Makefile.local index 53534f3..c011e0b 100644 --- a/parse-time-string/Makefile.local +++ b/parse-time-string/Makefile.local @@ -1,7 +1,9 @@ dir :=
[PATCH v2 05/10] install: check for non-SysV version (Solaris support)
> > diff --git a/vim/Makefile b/vim/Makefile > > index f17bebf..7ceba7a 100644 > > --- a/vim/Makefile > > +++ b/vim/Makefile > > @@ -5,8 +5,6 @@ files = plugin/notmuch.vim \ > > prefix = $(HOME)/.vim > > destdir = $(prefix)/plugin > > > > -INSTALL = install -D -m644 > > - > > all: help > > > > help: > > @@ -17,7 +15,7 @@ help: > > @echo "make symlink - create symlinks in ~/.vim (useful for dev > elopment)" > > > > install: > > - @for x in $(files); do $(INSTALL) $(CURDIR)/$$x $(prefix)/$$x; done > > + @for x in $(files); do $(INSTALL) -D -m644 $(CURDIR)/$$x $(prefix)/$$x; > done > > > > -link symlink: INSTALL = ln -fs > > link symlink: install > > + @for x in $(files); do ln -fs $(CURDIR)/$$x $(prefix)/$$x; done > > -- > > Here you'd need to remove the 'install' dependency as it would first > do it and then overwriting the results with dependency. Good catch, thanks; that's what I'll do. I also noticed a couple other things in this file -- I need to "include ../Makefile.config" to get the definition of $INSTALL, and $destdir isn't used in that Makefile. Blake
[PATCH v2 07/10] gen-version-script: parse Solaris "nm" output (Solaris support)
>> @@ -11,10 +12,44 @@ fi >> HEADER=$1 >> shift >> >> +if [ `uname -s` == SunOS ] ; then >> +# >> +# Using Solaris "nm", a defined symbol looks like this: >> +# > > The POSIX / Bourne -comformant equality comparison is '='. Sigh, of course it is. Fixed. > e.g. > > $ ./heirloom-sh/sh -c ' [ a == b ] || echo x' > ./heirloom-sh/sh: test: unknown operator == > zsh: exit 1 ./heirloom-sh/sh -c ' [ a == b ] || echo x' > > Interesting that Solaris /bin/sh did not fail there... I was running on Solaris 11.1, which uses ksh93 as its /bin/sh. You're absolutely right that Solaris 10 would fall over, though. Similarly, the following line: demangled=$(demangle $sym) doesn't work on traditional sh. I've replaced $() with ``. > Hmm, gen-version-script doesn't have shebang... it is run like: > > sh $(srcdir)/$(lib)/gen-version-script.sh $< $(libnotmuch_modules) > $@ > > in lib/Makefile.local -- taking sh fron PATH. I updated the first line from the #! invocation to a comment saying # This script is invoked via "sh .../gen-version-script.sh". Would a respun version of these patches help toward testing? Blake
[PATCH v2 07/10] gen-version-script: parse Solaris "nm" output (Solaris support)
>> Would a respun version of these patches help toward testing? > > $ grep vim test/* > zsh: exit 1 grep vim test/* > > i.e. no vim tests... Sure -- I was referring to any more general testing you might do. Anyway, thanks for your comments. Barring any more comments I'll probably send out an updated patch set later today. Blake
[PATCH v3 00/10] Solaris support
Updated based on comments from Tomi Ollila last week: - Cleaned up the $(INSTALL) changes in vim/Makefile. - Fixed gen-version-script to be compliant with old "sh" implementation.
[PATCH v3 02/10] asctime: check for standards compliance (Solaris support)
Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for asctime_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file "compat/check_asctime.c", which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_asctime.c | 18 ++ compat/compat.h|3 +++ configure | 22 -- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 compat/check_asctime.c diff --git a/compat/check_asctime.c b/compat/check_asctime.c new file mode 100644 index 000..c508fbf --- /dev/null +++ b/compat/check_asctime.c @@ -0,0 +1,18 @@ +/* + * This compatibility check actually succeeds (on Solaris) if + * _POSIX_PTHREAD_SEMANTICS is not defined. But we need to #define that to get + * the right version of getpwuid_r(), so we define it here to ensure that the + * compatibility check ends up doing the same thing as the rest of the code. + */ +#define_POSIX_PTHREAD_SEMANTICS 1 +#include +#include + +int main() +{ +struct tm tm; + +(void) asctime_r (, NULL, 0); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index efea023..e5f833e 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -57,6 +57,9 @@ char* strcasestr(const char *haystack, const char *needle); #if !STD_GETPWUID #define _POSIX_PTHREAD_SEMANTICS 1 #endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif #ifdef __cplusplus } diff --git a/configure b/configure index bb5031e..d153f57 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/check_getpwuid +printf "Checking for standard version of asctime_r... " +if ${CC} -o compat/check_asctime "$srcdir"/compat/check_asctime.c > /dev/null 2>&1 +then +printf "Yes.\n" +std_asctime=1 +else +printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n" +std_asctime=0 +fi +rm -f compat/check_asctime + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -687,6 +698,11 @@ HAVE_STRCASESTR = ${have_strcasestr} # to enable the standards-compliant version -- needed for Solaris) STD_GETPWUID = ${std_getpwuid} +# Whether the asctime_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_ASCTIME = ${std_asctime} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -733,11 +749,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ - -DSTD_GETPWUID=\$(STD_GETPWUID) + -DSTD_GETPWUID=\$(STD_GETPWUID) \\ + -DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ --DSTD_GETPWUID=\$(STD_GETPWUID) +-DSTD_GETPWUID=\$(STD_GETPWUID) \\ +-DSTD_ASCTIME=\$(STD_ASCTIME) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2
[PATCH v3 01/10] getpwuid: check for standards compliance (Solaris support)
Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs to be defined to get the right number of arguments in the prototypes for getpwuid_r(). Solaris' default implementation conforms to POSIX.1c Draft 6, rather than the final POSIX.1c spec. The standards-compliant version can be used by defining _POSIX_PTHREAD_SEMANTICS. This change also adds the file "compat/check_getpwuid.c", which configure uses to perform its check, and modifies compat/compat.h to define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed. --- compat/check_getpwuid.c | 11 +++ compat/compat.h |4 configure | 23 +-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 compat/check_getpwuid.c diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c new file mode 100644 index 000..c435eb8 --- /dev/null +++ b/compat/check_getpwuid.c @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ +struct passwd passwd, *ignored; + +(void) getpwuid_r (0, , NULL, 0, ); + +return (0); +} diff --git a/compat/compat.h b/compat/compat.h index b2e2736..efea023 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -54,6 +54,10 @@ char* strcasestr(const char *haystack, const char *needle); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #ifdef __cplusplus } #endif diff --git a/configure b/configure index ea8a1ad..bb5031e 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf "Checking for standard version of getpwuid_r... " +if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 +then +printf "Yes.\n" +std_getpwuid=1 +else +printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n" +std_getpwuid=0 +fi +rm -f compat/check_getpwuid + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -671,6 +682,11 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the getpwuid_r function is standards-compliant +# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS +# to enable the standards-compliant version -- needed for Solaris) +STD_GETPWUID = ${std_getpwuid} + # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD PLATFORM = ${platform} @@ -715,10 +731,13 @@ WITH_ZSH = ${WITH_ZSH} # Combined flags for compiling and linking against all of the above CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ - \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) + \$(VALGRIND_CFLAGS) \\ + -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ + -DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ - -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) +-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ +-DSTD_GETPWUID=\$(STD_GETPWUID) CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) EOF -- 1.7.3.2
[PATCH v3 04/10] configure: check for -Wl,-rpath (Solaris support)
Add a check to "configure" to see whether -Wl,-rpath can be used without --enable-new-dtags. Solaris needs the former and doesn't know about the latter. --- configure |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 9707f11..c9da667 100755 --- a/configure +++ b/configure @@ -552,6 +552,10 @@ if ${CC} -Wl,--enable-new-dtags -Wl,-rpath,/tmp/ -o minimal minimal.c >/dev/null then printf "Yes.\n" rpath_ldflags="-Wl,--enable-new-dtags -Wl,-rpath,\$(libdir)" +elif ${CC} -Wl,-rpath,/tmp/ -o minimal minimal.c >/dev/null 2>&1 +then +printf "Yes.\n" +rpath_ldflags="-Wl,-rpath,\$(libdir)" else printf "No (nothing to worry about).\n" rpath_ldflags="" -- 1.7.3.2
[PATCH v3 08/10] notmuch-config: use strchr(), not index() (Solaris support)
notmuch-config.c has the only use of the function named "index()" in the notmuch source. Several other places use the equivalent function "strchr()"; this patch just fixes notmuch-config.c to use strchr() instead. (Solaris needs to include to get the prototype for index(), and notmuch-config.c was failing to include that header, so it wasn't compiling as-is.) --- notmuch-config.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index 3e37a2d..47eb743 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -688,7 +688,7 @@ _item_split (char *item, char **group, char **key) *group = item; -period = index (item, '.'); +period = strchr (item, '.'); if (period == NULL || *(period+1) == '\0') { fprintf (stderr, "Invalid configuration name: %s\n" -- 1.7.3.2
[PATCH v3 10/10] timegm: add portable implementation (Solaris support)
The timegm(3) function is a non-standard extension to libc which is available in GNU libc and on some BSDs. Although SunOS had this function in its libc, Solaris (unfortunately) removed it. This patch implements a very simple version of timegm() which is good enough for parse-time-string.c. One complication of this fix is that libnotmuch.a includes a call to parse_time_string() from parse-time-vrp.o, and parse_time_string() in libparse-time-string.a is the thing which needs to call timegm(). A straightforward attempt to have the two static libraries reconcile their symbols from one another fails, because the symbols come from different .o's, and the linker only does a single pass on each ".a" looking for dependencies. To solve this, libparse-time-string includes "compat.h", and pulls in .o's from the compat directory, in order to get everything that it needs. --- compat/Makefile.local |4 +++ compat/compat.h | 19 ++-- compat/have_timegm.c |7 ++ compat/timegm.c | 37 + configure | 11 + parse-time-string/Makefile.local |4 ++- parse-time-string/parse-time-string.c |1 + 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 compat/have_timegm.c create mode 100644 compat/timegm.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 2c4f65f..b0d5417 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1) notmuch_compat_srcs += $(dir)/strsep.c endif +ifneq ($(HAVE_TIMEGM),1) +notmuch_compat_srcs += $(dir)/timegm.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index 0b5e465..5a402d5 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -30,6 +30,13 @@ extern "C" { #endif +#if !STD_GETPWUID +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif +#if !STD_ASCTIME +#define _POSIX_PTHREAD_SEMANTICS 1 +#endif + #if !HAVE_GETLINE #include #include @@ -50,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle); char *strsep(char **stringp, const char *delim); #endif /* !HAVE_STRSEP */ +#if !HAVE_TIMEGM +#include +time_t timegm (struct tm *tm); +#endif /* !HAVE_TIMEGM */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ @@ -58,13 +70,6 @@ char *strsep(char **stringp, const char *delim); #define IGNORE_RESULT(x) x #endif /* __GNUC__ */ -#if !STD_GETPWUID -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif -#if !STD_ASCTIME -#define _POSIX_PTHREAD_SEMANTICS 1 -#endif - #ifdef __cplusplus } #endif diff --git a/compat/have_timegm.c b/compat/have_timegm.c new file mode 100644 index 000..b62b793 --- /dev/null +++ b/compat/have_timegm.c @@ -0,0 +1,7 @@ +#include +#include "compat.h" + +int main() +{ +return (int) timegm((struct tm *)0); +} diff --git a/compat/timegm.c b/compat/timegm.c new file mode 100644 index 000..6d76164 --- /dev/null +++ b/compat/timegm.c @@ -0,0 +1,37 @@ +#include +#include "compat.h" + +static int +leapyear (int year) +{ +return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)); +} + +/* + * This is a simple implementation of timegm() which does what is needed + * by create_output() -- just turns the "struct tm" into a GMT time_t. + * It does not normalize any of the fields of the "struct tm", nor does + * it set tm_wday or tm_yday. + */ +time_t +timegm (struct tm *tm) +{ +intmonthlen[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, +}; +intyear, month, days; + +days = 365 * (tm->tm_year - 70); +for (year = 70; year < tm->tm_year; year++) { + if (leapyear(1900 + year)) { + days++; + } +} +for (month = 0; month < tm->tm_mon; month++) { + days += monthlen[leapyear(1900 + year)][month]; +} +days += tm->tm_mday - 1; + +return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec); +} diff --git a/configure b/configure index ab8357f..f3ec9a2 100755 --- a/configure +++ b/configure @@ -523,6 +523,17 @@ else fi rm -f compat/have_strsep +printf "Checking for timegm... " +if ${CC} -o compat/have_timegm "$srcdir"/compat/have_timegm.c > /dev/null 2>&1 +then +printf "Yes.\n" +have_timegm="1" +else +printf "No (will use our own instead).\n" +have_timegm="0" +fi +rm -f compat/have_timegm + printf "Checking for standard version of getpwuid_r... " if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 then diff --git a/parse-time-string/Makefile.local b/parse-time-string/Makefile.local index 53534f3..c011e0b 100644 --- a/parse-time-string/Makefile.local +++ b/parse-time-string/Makefile.local @@ -1,7 +1,9 @@ dir :=
[PATCH v3 03/10] gethostbyname: check for libnsl (Solaris support)
Add a check to "configure" to see whether -lnsl is needed for programs that are using gethostbyname(). This change also adds the file "compat/check_ghbn.c", which configure uses to perform its check. --- compat/check_ghbn.c |9 + configure | 17 - 2 files changed, 25 insertions(+), 1 deletions(-) create mode 100644 compat/check_ghbn.c diff --git a/compat/check_ghbn.c b/compat/check_ghbn.c new file mode 100644 index 000..4858d5c --- /dev/null +++ b/compat/check_ghbn.c @@ -0,0 +1,9 @@ +#include +#include + +int main() +{ +(void) gethostbyname(NULL); + +return (0); +} diff --git a/configure b/configure index d153f57..9707f11 100755 --- a/configure +++ b/configure @@ -534,6 +534,17 @@ else fi rm -f compat/check_asctime +printf "Checking whether libnsl is needed for gethostbyname... " +if ${CC} -o compat/check_ghbn "$srcdir"/compat/check_ghbn.c > /dev/null 2>&1 +then +printf "No.\n" +libnsl_ldflags="" +else +printf "Yes.\n" +libnsl_ldflags="-lnsl" +fi +rm -f compat/check_ghbn + printf "int main(void){return 0;}\n" > minimal.c printf "Checking for rpath support... " @@ -723,6 +734,9 @@ GMIME_LDFLAGS = ${gmime_ldflags} TALLOC_CFLAGS = ${talloc_cflags} TALLOC_LDFLAGS = ${talloc_ldflags} +# Flags needed to get gethostbyname() at link time +LIBNSL_LDFLAGS = ${libnsl_ldflags} + # Flags needed to have linker set rpath attribute RPATH_LDFLAGS = ${rpath_ldflags} @@ -757,5 +771,6 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ -DSTD_GETPWUID=\$(STD_GETPWUID) \\ -DSTD_ASCTIME=\$(STD_ASCTIME) -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) \\ +\$(LIBNSL_LDFLAGS) EOF -- 1.7.3.2
[PATCH v3 07/10] gen-version-script: parse Solaris "nm" output (Solaris support)
The output of "nm" on Solaris is substantially different from that on Linux, and the current version of gen-version-script is tied to the Linux "nm" output. This patch separates the parts of "nm" processing which are dependent on the output format into a couple shell functions, and makes another shell function to use the appropriate version of "c++filt" to demangle symbols. It also modifies lib/Makefile.local to pass the generated symbol table correctly to the Solaris linker. --- lib/Makefile.local|4 +++ lib/gen-version-script.sh | 50 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index 0c6b258..2068e4a 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -30,7 +30,11 @@ LIBRARY_SUFFIX = so LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX) SONAME = $(LINKER_NAME).$(LIBNOTMUCH_VERSION_MAJOR) LIBNAME = $(SONAME).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE) +ifeq ($(PLATFORM),SOLARIS) +LIBRARY_LINK_FLAG = -shared -Wl,-M notmuch.sym -Wl,-soname=$(SONAME) -Wl,--no-undefined -lc +else LIBRARY_LINK_FLAG = -shared -Wl,--version-script=notmuch.sym,-soname=$(SONAME) -Wl,--no-undefined +endif ifeq ($(PLATFORM),OPENBSD) LIBRARY_LINK_FLAG += -lc endif diff --git a/lib/gen-version-script.sh b/lib/gen-version-script.sh index 76670d5..ecf44f0 100644 --- a/lib/gen-version-script.sh +++ b/lib/gen-version-script.sh @@ -1,3 +1,4 @@ +# This script is invoked via "sh .../gen-version-script.sh". # we go through a bit of work to get the unmangled names of the # typeinfo symbols because of @@ -11,10 +12,44 @@ fi HEADER=$1 shift +if [ `uname -s` = SunOS ] ; then +# +# Using Solaris "nm", a defined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [15]|128| 16|FUNC |GLOB |0|1 |notmuch_tags_get +# +# and an undefined symbol looks like this: +# +# [Index]ValueSize Type Bind Other Shndx Name +# [35]| 0| 0|NOTY |GLOB |0|UNDEF |notmuch_tags_get +# +find_xapian_error() { + nawk -F'\|' '$7 !~ "UNDEF" && $8 ~ "Xapian.*Error" { print $8 }' +} +find_compat_syms() { + nawk -F'\|' '$7 !~ "UNDEF" && $8 ~ "get(line|delim)" { print $8 ";" }' +} +demangle() { + gc++filt "$@" +} +else +find_xapian_error() { + awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $3 ~ "Xapian.*Error" {print $3}' +} +find_compat_syms() { + awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $2 == "T" && $3 ~ "^get(line|delim)$" {print $3 ";"}' +} +demangle() { + c++filt "$@" +} +fi + printf '{\nglobal:\n' -nm $* | awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $3 ~ "Xapian.*Error" {print $3}' | sort | uniq | \ -while read sym; do -demangled=$(c++filt $sym) + +# Find the typeinfo for "Xapian::*Error"s. +nm $* | find_xapian_error | sort | uniq | while read sym; do +demangled=`demangle $sym` case $demangled in typeinfo*) printf "\t$sym;\n" @@ -23,6 +58,11 @@ while read sym; do ;; esac done -nm $* | awk '$1 ~ "^[0-9a-fA-F][0-9a-fA-F]*$" && $2 == "T" && $3 ~ "^get(line|delim)$" {print $3 ";"}' -sed -n 's/^[[:space:]]*\(notmuch_[a-z_]*\)[[:space:]]*(.*/ \1;/p' $HEADER + +# Find the "compat" syms that we need to export. +nm $* | find_compat_syms + +# Finally, get the real notmuch symbols. +sed -n 's/^[ ]*\(notmuch_[a-z_]*\)[ ]*(.*/ \1;/p' $HEADER + printf "local: *;\n};\n" -- 1.7.3.2
[PATCH v3 05/10] install: check for non-SysV version (Solaris support)
Solaris ships a program called "install" in /usr/sbin, which performs a task that's fairly similar to the GNU and BSD "install" programs but which uses very different command line arguments. In particular, if it is invoked without "-c", "-f", or "-n", it will search the target directory for a file with the same name as the one being installed, and it will only install the file if it finds a matching name. More excitingly, if it doesn't find a match, it will look in /bin, /usr/bin, /etc, /lib, and /usr/lib and try to do the same there. The standard workaround for this is to use GNU install. It is available via the standard Solaris packaging system (in "file/gnu-coreutils"), and installs itself as /usr/bin/ginstall. This patch adds a check to "configure" to see if "install" behaves in a way that's compatible with GNU and BSD install, and if not, it uses a program called "ginstall" instead. It also modifies "configure" to set the $(INSTALL) variable, and changes various Makefiles to use it. --- Makefile.local|2 +- completion/Makefile.local |4 ++-- configure | 19 +++ emacs/Makefile.local |6 +++--- lib/Makefile.local|4 ++-- man/Makefile.local|6 +++--- vim/Makefile | 11 +-- 7 files changed, 35 insertions(+), 17 deletions(-) diff --git a/Makefile.local b/Makefile.local index 2b91946..7ccb1cd 100644 --- a/Makefile.local +++ b/Makefile.local @@ -286,7 +286,7 @@ notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME) .PHONY: install install: all install-man mkdir -p "$(DESTDIR)$(prefix)/bin/" - install notmuch-shared "$(DESTDIR)$(prefix)/bin/notmuch" + $(INSTALL) notmuch-shared "$(DESTDIR)$(prefix)/bin/notmuch" ifeq ($(MAKECMDGOALS), install) @echo "" @echo "Notmuch is now installed to $(DESTDIR)$(prefix)" diff --git a/completion/Makefile.local b/completion/Makefile.local index dfc1271..a648a78 100644 --- a/completion/Makefile.local +++ b/completion/Makefile.local @@ -14,9 +14,9 @@ install-$(dir): @echo $@ ifeq ($(WITH_BASH),1) mkdir -p "$(DESTDIR)$(bash_completion_dir)" - install -m0644 $(bash_script) "$(DESTDIR)$(bash_completion_dir)/notmuch" + $(INSTALL) -m0644 $(bash_script) "$(DESTDIR)$(bash_completion_dir)/notmuch" endif ifeq ($(WITH_ZSH),1) mkdir -p "$(DESTDIR)$(zsh_completion_dir)" - install -m0644 $(zsh_script) "$(DESTDIR)$(zsh_completion_dir)/_notmuch" + $(INSTALL) -m0644 $(zsh_script) "$(DESTDIR)$(zsh_completion_dir)/_notmuch" endif diff --git a/configure b/configure index c9da667..d9a101f 100755 --- a/configure +++ b/configure @@ -591,6 +591,21 @@ for flag in -Wmissing-declarations; do done printf "\n\t${WARN_CFLAGS}\n" +INSTALL="install" +printf "Checking for working \"install\" program... " +mkdir _tmp_ +cd _tmp_ +echo 1 > 1 +mkdir dest +if install 1 dest > /dev/null 2>&1 ; then + printf "\"install\" works fine.\n" +else + INSTALL="ginstall" + printf "using \"ginstall\".\n" +fi +cd .. +rm -rf _tmp_ + rm -f minimal minimal.c cat <
[PATCH v3 09/10] debugger.c: correct return type from getppid() (Solaris support)
Cast the return value of getppid() to "int" from "pid_t" in debugger.c, since it is being passed to sprintf("%d"), which wants an "int" argument. On Solaris, "pid_t" is a "long" for 32-bit programs. --- debugger.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/debugger.c b/debugger.c index e8b9378..8ff13d6 100644 --- a/debugger.c +++ b/debugger.c @@ -36,7 +36,7 @@ debugger_is_active (void) if (RUNNING_ON_VALGRIND) return TRUE; -sprintf (buf, "/proc/%d/exe", getppid ()); +sprintf (buf, "/proc/%d/exe", (int) getppid ()); if (readlink (buf, buf, sizeof (buf)) != -1 && strncmp (basename (buf), "gdb", 3) == 0) { -- 1.7.3.2
[PATCH v3 06/10] strsep: check for availability (Solaris support)
Solaris does not ship a version of the strsep() function. This change adds a check to "configure" to see whether notmuch needs to provide its own implementation, and if so, it uses the new version in "compat/strsep.c" (which was copied from Mutt, and apparently before that from glibc). --- compat/Makefile.local |4 +++ compat/compat.h |4 +++ compat/have_strsep.c | 10 +++ compat/strsep.c | 65 + configure | 17 + 5 files changed, 100 insertions(+), 0 deletions(-) create mode 100644 compat/have_strsep.c create mode 100644 compat/strsep.c diff --git a/compat/Makefile.local b/compat/Makefile.local index 13f16cd..2c4f65f 100644 --- a/compat/Makefile.local +++ b/compat/Makefile.local @@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1) notmuch_compat_srcs += $(dir)/strcasestr.c endif +ifneq ($(HAVE_STRSEP),1) +notmuch_compat_srcs += $(dir)/strsep.c +endif + SRCS := $(SRCS) $(notmuch_compat_srcs) diff --git a/compat/compat.h b/compat/compat.h index e5f833e..0b5e465 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -46,6 +46,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp); char* strcasestr(const char *haystack, const char *needle); #endif /* !HAVE_STRCASESTR */ +#if !HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* !HAVE_STRSEP */ + /* Silence gcc warnings about unused results. These warnings exist * for a reason; any use of this needs to be justified. */ #ifdef __GNUC__ diff --git a/compat/have_strsep.c b/compat/have_strsep.c new file mode 100644 index 000..5bd396c --- /dev/null +++ b/compat/have_strsep.c @@ -0,0 +1,10 @@ +#define _GNU_SOURCE +#include + +int main() +{ +char *found; +char **stringp, const char *delim; + +found = strsep(stringp, delim); +} diff --git a/compat/strsep.c b/compat/strsep.c new file mode 100644 index 000..78ab9e7 --- /dev/null +++ b/compat/strsep.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +/* Taken from glibc 2.6.1 */ + +char *strsep (char **stringp, const char *delim) +{ + char *begin, *end; + + begin = *stringp; + if (begin == NULL) +return NULL; + + /* A frequent case is when the delimiter string contains only one + character. Here we don't need to call the expensive `strpbrk' + function and instead work using `strchr'. */ + if (delim[0] == '\0' || delim[1] == '\0') +{ + char ch = delim[0]; + + if (ch == '\0') + end = NULL; + else + { + if (*begin == ch) + end = begin; + else if (*begin == '\0') + end = NULL; + else + end = strchr (begin + 1, ch); + } +} + else +/* Find the end of the token. */ +end = strpbrk (begin, delim); + + if (end) +{ + /* Terminate the token and set *STRINGP past NUL character. */ + *end++ = '\0'; + *stringp = end; +} + else +/* No more delimiters; this is the last token. */ +*stringp = NULL; + + return begin; +} diff --git a/configure b/configure index d9a101f..ab8357f 100755 --- a/configure +++ b/configure @@ -512,6 +512,17 @@ else fi rm -f compat/have_strcasestr +printf "Checking for strsep... " +if ${CC} -o compat/have_strsep "$srcdir"/compat/have_strsep.c > /dev/null 2>&1 +then +printf "Yes.\n" +have_strsep="1" +else +printf "No (will use our own instead).\n" +have_strsep="0" +fi +rm -f compat/have_strsep + printf "Checking for standard version of getpwuid_r... " if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 then @@ -723,6 +734,10 @@ HAVE_GETLINE = ${have_getline} # build its own version) HAVE_STRCASESTR = ${have_strcasestr} +# Whether the strsep function is available (if not, then notmuch will +# build its own version) +HAVE_STRSEP = ${have_strsep} + # Whether the getpwuid_r function is standards-compliant # (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS # to enable the standards-compliant version -- needed for Solaris) @@ -782,12 +797,14 @@ CONFIGURE_CFLAGS =
[PATCH v3 00/10] Solaris support
> $ gcc compat/have_strsep.c > compat/have_strsep.c: In function "main": > compat/have_strsep.c:7:21: error: expected identifier or "(" before "const" > compat/have_strsep.c:9:29: error: "delim" undeclared (first use in this > function) > compat/have_strsep.c:9:29: note: each undeclared identifier is reported only > once for each function it appears in > zsh: exit 1 gcc compat/have_strsep.c > > --- It is very easy to spot the problem ;) Sigh, yes it is. I started my Solaris port using some patches from someone else who had done previous work on a Solaris port, and obviously I didn't look at the patch very closely. In fact, after fixing have_strsep.c, I saw that I didn't even need it -- Solaris 11 has strsep() in libc. But I'd prefer to clean up this patch and leave the compat version available for those compiling on older versions of Solaris, if that's okay. > $ gcc compat/check_asctime.c > compat/check_asctime.c: In function "main": > compat/check_asctime.c:15:5: error: too many arguments to function "asctime_r" > In file included from compat/check_asctime.c:8:0: > /usr/include/time.h:266:14: note: declared here > zsh: exit 1 gcc compat/check_asctime.c > > --- the posix-semantics way uses the 2-arg format. > > The logic of the test setting in this file doesn't open to > me. Why not test the same way as in getpwuid_r() case ? Yeah, that's clearly the right thing to do. I was getting odd behavior when I defined _POSIX_PTHREAD_SEMANTICS for getpwuid_r(), and it looks like I fixed it in the wrong direction. Did you happen to notice any other issues besides these two? I'd rather not spam the list with my ten-patch set if there's other silly stuff that needs cleaning up. Thanks again for testing this. Blake
crash during saving
> I just indexed my mail archive by notmuch and I'm starting to play > with mutt-kz. The biggest stopper right now is that mutt cores when > set already read mail to new (toggle-new in mutt). Once I try to leave > the virtual folder (be it to another folder or because of quitting > mutt) it crashes. > > I haven't had the time yet to investigate deeper, so I'll just post > whatever info I have and hope that it will be something obvious for > you :) I saw something like that when I was first using mutt-kz as well... it ended up that I had compiled libxapian with one version of gcc (3.4.3 maybe?) and notmuch with 4.5.2, and the C++ runtime libraries were incompatible between the two versions. In my case, any time it tried to throw an exception (e.g. when I removed a tag that was not present) it would die with a similar stack trace. (And, of course, that was on Solaris :) ) Blake
crash during saving
> Right, so the problem really seems to be in throwing/catching > exception. Function "_notmuch_message_remove_term" is supposed to > catch the exception and ignore it. Which does not happen in my case. Yep, that was exactly what I was seeing. > On a side note, I wonder, is catching exception faster than going > through list of tags to see if given tag exists? Might be interesting > to compare. I tried that as a workaround at first (just to get it working, not caring about performance). But I realized that libxapian uses exceptions for a lot of failure modes, and I actually ran into one or two others, so I decided I needed to just get it working. To simplify the problem, you might want to try building a very simple stub version of the whole thing -- i.e. a C program that makes a call to a C-interface "liba", which just makes a call into a C++ "libb" library and tries to catch an exception from it; the "libb" library would just throw an exception. If that reproduces the problem, that might help you debug your setup. (Again, I eventually settled on using GCC 4.5.2, and didn't have the intestinal fortitude to get Studio working. Especially once I saw problems with C++ exception handling. If you can get it working, more power to you!) Blake
[PATCH 4/4] timegm: add portable implementation (Solaris support)
> From: Blake Jones > > The timegm(3) function is a non-standard extension to libc which is > available in GNU libc and on some BSDs. Although SunOS had this > function in its libc, Solaris (unfortunately) removed it. This patch > implements a very simple version of timegm() which is good enough for > parse-time-string.c. LGTM. Blake > Signed-off-by: Vladimir Marek > --- > compat/Makefile.local |4 +++ > compat/compat.h |5 +++ > compat/have_timegm.c |7 > compat/timegm.c | 57 > + > configure | 11 +++ > parse-time-string/parse-time-string.c |1 + > 6 files changed, 85 insertions(+) > create mode 100644 compat/have_timegm.c > create mode 100644 compat/timegm.c > > diff --git a/compat/Makefile.local b/compat/Makefile.local > index 2c4f65f..b0d5417 100644 > --- a/compat/Makefile.local > +++ b/compat/Makefile.local > @@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1) > notmuch_compat_srcs += $(dir)/strsep.c > endif > > +ifneq ($(HAVE_TIMEGM),1) > +notmuch_compat_srcs += $(dir)/timegm.c > +endif > + > SRCS := $(SRCS) $(notmuch_compat_srcs) > diff --git a/compat/compat.h b/compat/compat.h > index ae762c3..5a402d5 100644 > --- a/compat/compat.h > +++ b/compat/compat.h > @@ -57,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle); > char *strsep(char **stringp, const char *delim); > #endif /* !HAVE_STRSEP */ > > +#if !HAVE_TIMEGM > +#include > +time_t timegm (struct tm *tm); > +#endif /* !HAVE_TIMEGM */ > + > /* Silence gcc warnings about unused results. These warnings exist > * for a reason; any use of this needs to be justified. */ > #ifdef __GNUC__ > diff --git a/compat/have_timegm.c b/compat/have_timegm.c > new file mode 100644 > index 000..b62b793 > --- /dev/null > +++ b/compat/have_timegm.c > @@ -0,0 +1,7 @@ > +#include > +#include "compat.h" > + > +int main() > +{ > +return (int) timegm((struct tm *)0); > +} > diff --git a/compat/timegm.c b/compat/timegm.c > new file mode 100644 > index 000..213963b > --- /dev/null > +++ b/compat/timegm.c > @@ -0,0 +1,57 @@ > +/* timegm.c --- Implementation of replacement timegm function. > + Copyright (C) 2012 Free Software Foundation, Inc. > + > + This program is free software; you can redistribute it and/or > + modify it under the terms of the GNU General Public License as > + published by the Free Software Foundation; either version 3, or (at > + your option) any later version. > + > + This program is distributed in the hope that it will be useful, but > + WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > + 02110-1301, USA. */ > + > +/* Written by Blake Jones. */ > + > +#include > +#include "compat.h" > + > +static int > +leapyear (int year) > +{ > +return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)); > +} > + > +/* > + * This is a simple implementation of timegm() which does what is needed > + * by create_output() -- just turns the "struct tm" into a GMT time_t. > + * It does not normalize any of the fields of the "struct tm", nor does > + * it set tm_wday or tm_yday. > + */ > +time_t > +timegm (struct tm *tm) > +{ > +int monthlen[2][12] = { > + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, > + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, > +}; > +int year, month, days; > + > +days = 365 * (tm->tm_year - 70); > +for (year = 70; year < tm->tm_year; year++) { > + if (leapyear(1900 + year)) { > + days++; > + } > +} > +for (month = 0; month < tm->tm_mon; month++) { > + days += monthlen[leapyear(1900 + year)][month]; > +} > +days += tm->tm_mday - 1; > + > +return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + > tm->tm_sec); > +} > diff --git a/configure b/configure > index ac44857..6166917 100755 > --- a/configure > +++ b/configure > @@ -530,6 +530,17 @@ else > fi > rm -f compat/have_strsep > > +printf "Checking for timegm... " > +if ${CC} -o compat/have_timegm "$srcdir"/compat/have_tim
[PATCH 4/4] timegm: add portable implementation (Solaris support)
> The copyright header gives FSF "owner"ship to the file -- which would > be fine by the project -- but does assigning copyright to the FSF work > like this... ... I started to look around and found (among other > pages) this: > > http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=doc/Copyright/conditions.text;h=6e19adf0233900c9169 > e10fe7e0aa8d1feb73996;hb=HEAD > > Maybe for liability reasons FSF needs more than just stating the > copyright at the beginning of file... I don't know -- but if this is > the case maybe the easiest thing is to remove (amend) the Copyright > line out of the file. I don't really care what sort of copyright it has. Vladimir is the one with the up-to-date tree at this point, so he would be best positioned to update the text with whatever works best for the rest of notmuch. > In getline.c, and getdelim.c the code is taken from glibc. What I've > understood this timegm.c is new art ? To the best of my recollection, yes, I implemented this version of timegm() from scratch, based on my understanding of what it needed to do. Blake