diff options
-rw-r--r-- | ChangeLog | 37 | ||||
-rw-r--r-- | NEWS | 9 | ||||
-rwxr-xr-x | autogen.sh | 38 | ||||
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | ltmain.sh | 8 | ||||
-rw-r--r-- | src/Makefile.am | 78 | ||||
-rw-r--r-- | src/gpg-error-config.in | 9 | ||||
-rw-r--r-- | src/gpg-error.c | 10 | ||||
-rw-r--r-- | src/gpg-error.def | 11 | ||||
-rw-r--r-- | src/gpg-error.def.in | 20 | ||||
-rw-r--r-- | src/gpg-error.h.in | 12 | ||||
-rw-r--r-- | src/gpg-extra/errno.h | 60 | ||||
-rw-r--r-- | src/init.c | 256 | ||||
-rw-r--r-- | src/mkheader.awk | 35 | ||||
-rw-r--r-- | src/w32-gettext.c | 10 | ||||
-rw-r--r-- | src/w32-gettext.h | 6 | ||||
-rw-r--r-- | src/w32ce-add.h | 7 | ||||
-rw-r--r-- | tests/Makefile.am | 9 | ||||
-rw-r--r-- | tests/t-syserror.c | 2 |
19 files changed, 521 insertions, 108 deletions
@@ -1,3 +1,40 @@ +2010-01-18 Werner Koch <[email protected]> + + * ltmain.sh (wrappers_required): Don't set for mingw32ce. + + * tests/Makefile.am (extra_includes): New. + * tests/t-syserror.c (main): Use gpg_err_set_errno. + + * src/w32ce-add.h: New. + * src/Makefile.am (EXTRA_DIST): Add it + (extra-h.in): New rule + (gpg-error.h): Pass extra-h.in to mkheader. + * src/mkheader.awk (extra_body): New. + + * src/gpg-error.c (get_err_from_number): Use gpg_err_set_errno. + + * src/mkw32errmap.c: New + * src/gpg-error.def: Rename to .. + * src/gpg-error.def.in: .. this. + (_gpg_errno_location): New. + * src/init.c (struct tls_space_s, tls_index): New. + (get_tls, _gpg_errno_location, DllMain): New. + (read_w32_registry_string) [W32CE]: Don't expand envvars. + (_gpg_w32ce_strerror): New. + * src/Makefile.am (extra_headers, extra_cppflags): New. + (include_HEADERS): Add extra_headers. Prefix with nobase_. + (libgpg_error_la_CPPFLAGS, gpg_error_CPPFLAGS) + (mkerrcodes.h): Add extra_cppflags. + (RCCOMPILE): Replace libgpg_error_la_CPPFLAGS by direct inclusion + of -DLOCALEDIR. + * configure.ac (HAVE_W32CE_SYSTEM): New AM_CONDITIONAL and + AC_DEFINE. + (GPG_ERROR_CONFIG_ISUBDIRAFTER): New. + * src/gpg-error-config.in <--libs>: Replace fixed -lgpg-error + by subst variable. + (isubdirafter): New. + <--cflags>: Take subst variable in account. Add idirafter stuff. + 2009-10-26 Marcus Brinkmann <[email protected]> * src/gpg-error.h.in (GPG_ERR_SOURCE_DIM): Reduce to 128. @@ -1,12 +1,15 @@ Noteworthy changes in version 1.8 ---------------------------------------------- + * Preliminary support for WindowsCE. + * Interface changes relative to the 1.7 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - GPG_ERR_NOT_ENABLED NEW - GPG_ERR_SOURCE_G13 NEW + GPG_ERR_NOT_ENABLED NEW. + GPG_ERR_SOURCE_G13 NEW. GPG_ERR_NO_ENGINE NEW. - + gpg_err_set_errno NEW. + Noteworthy changes in version 1.7 (2008-11-26) ---------------------------------------------- @@ -35,9 +35,26 @@ if test "$1" = "--force"; then shift fi +# Convenience option to use certain configure options for some hosts. +myhost="" +myhostsub="" +case "$1" in + --build-w32) + myhost="w32" + ;; + --build-w32ce) + myhost="w32" + myhostsub="ce" + ;; + *) + ;; +esac + + + # ***** W32 build script ******* # Used to cross-compile for Windows. -if test "$1" = "--build-w32"; then +if [ "$myhost" = "w32" ]; then tmp=`dirname $0` tsdir=`cd "$tmp"; pwd` shift @@ -47,12 +64,21 @@ if test "$1" = "--build-w32"; then fi build=`$tsdir/config.guess` - [ -z "$w32root" ] && w32root="$HOME/w32root" + case $myhostsub in + ce) + [ -z "$w32root" ] && w32root="$HOME/w32ce_root" + toolprefixes="arm-mingw32ce" + ;; + *) + [ -z "$w32root" ] && w32root="$HOME/w32root" + toolprefixes="i586-mingw32msvc i386-mingw32msvc" + ;; + esac echo "Using $w32root as standard install directory" >&2 # Locate the cross compiler crossbindir= - for host in i586-mingw32msvc i386-mingw32msvc; do + for host in $toolprefixes; do if ${host}-gcc --version >/dev/null 2>&1 ; then crossbindir=/usr/${host}/bin conf_CC="CC=${host}-gcc" @@ -61,8 +87,10 @@ if test "$1" = "--build-w32"; then done if [ -z "$crossbindir" ]; then echo "Cross compiler kit not installed" >&2 - echo "Under Debian GNU/Linux, you may install it using" >&2 - echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + if [ -z "$sub" ]; then + echo "Under Debian GNU/Linux, you may install it using" >&2 + echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + fi echo "Stop." >&2 exit 1 fi diff --git a/configure.ac b/configure.ac index 0f66c7d..4ede88f 100644 --- a/configure.ac +++ b/configure.ac @@ -87,6 +87,10 @@ AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler]) # Set some internal variables depending on the platform for later use. have_w32_system=no case "${host}" in + *-mingw32ce*) + have_w32_system=yes + have_w32ce_system=yes + ;; *-mingw32*) have_w32_system=yes ;; @@ -129,16 +133,21 @@ AC_C_CONST # Substitution used for gpg-error-config GPG_ERROR_CONFIG_LIBS="-lgpg-error" GPG_ERROR_CONFIG_CFLAGS="" +GPG_ERROR_CONFIG_ISUBDIRAFTER="" AC_SUBST(GPG_ERROR_CONFIG_LIBS) AC_SUBST(GPG_ERROR_CONFIG_CFLAGS) +AC_SUBST(GPG_ERROR_CONFIG_ISUBDIRAFTER) AC_CONFIG_FILES([src/gpg-error-config], [chmod +x src/gpg-error-config]) # Special defines for certain platforms if test "$have_w32_system" = yes; then AC_DEFINE(HAVE_W32_SYSTEM,1,[Defined if we run on a W32 API based system]) + if test "$have_w32ce_system" = yes; then + AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE]) + GPG_ERROR_CONFIG_ISUBDIRAFTER="gpg-extra" + fi BUILD_TIMESTAMP=`date --iso-8601=minutes` - AC_SUBST(BUILD_TIMESTAMP) changequote(,)dnl BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` changequote([,])dnl @@ -152,6 +161,7 @@ fi AC_SUBST(BUILD_TIMESTAMP) AC_SUBST(BUILD_FILEVERSION) AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) +AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes) AC_ARG_ENABLE(languages, @@ -7680,15 +7680,15 @@ EOF wrappers_required=yes case $host in + *cegcc | *mingw32ce* ) + # Disable wrappers for cegcc, we are cross compiling anyway. + wrappers_required=no + ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; - *cegcc) - # Disable wrappers for cegcc, we are cross compiling anyway. - wrappers_required=no - ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no diff --git a/src/Makefile.am b/src/Makefile.am index 6444c2c..8e2a319 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,10 +21,19 @@ # because they are needed to build the po directory, and they don't # depend on the configuration anyway. + +if HAVE_W32CE_SYSTEM +extra_headers = gpg-extra/errno.h +extra_cppflags = -idirafter gpg-extra +else +extra_headers = +extra_cppflags = +endif + localedir = $(datadir)/locale bin_PROGRAMS = gpg-error lib_LTLIBRARIES = libgpg-error.la -include_HEADERS = gpg-error.h +nobase_include_HEADERS = gpg-error.h $(extra_headers) bin_SCRIPTS = gpg-error-config m4datadir = $(datadir)/aclocal m4data_DATA = gpg-error.m4 @@ -33,25 +42,26 @@ m4data_DATA = gpg-error.m4 EXTRA_DIST = mkstrtable.awk err-sources.h.in err-codes.h.in \ mkerrnos.awk errnos.in README \ mkerrcodes.awk mkerrcodes1.awk mkerrcodes2.awk mkerrcodes.c \ - mkheader.awk gpg-error.h.in \ + mkheader.awk gpg-error.h.in mkw32errmap.c w32ce-add.h \ err-sources.h err-codes.h gpg-error-config.in gpg-error.m4 \ - gpg-error.def versioninfo.rc.in + gpg-error.def.in versioninfo.rc.in BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \ - err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h + err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h \ + gpg-error.def gpg-extra/errno.h extra-h.in -tmp_files = _mkerrcodes.h +tmp_files = _mkerrcodes.h _gpg-error.def.h mkw32errmap.tab.h CLEANFILES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \ - gpg-error.h mkerrcodes mkerrcodes.h \ - err-sources-sym.h err-codes-sym.h errnos-sym.h $(tmp_files) - + gpg-error.h mkerrcodes mkerrcodes.h gpg-error.def mkw32errmap.tab.h \ + err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-extra/errno.h \ + extra-h.in $(tmp_files) if HAVE_W32_SYSTEM arch_sources = w32-gettext.h w32-gettext.c RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(libgpg_error_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) + -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS) $(CPPFLAGS) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) SUFFIXES = .rc .lo @@ -63,7 +73,7 @@ gpg_error_res = versioninfo.lo no_undefined = -no-undefined export_symbols = -export-symbols $(srcdir)/gpg-error.def -install-def-file: +install-def-file: gpg-error.def $(INSTALL) gpg-error.def $(DESTDIR)$(libdir)/gpg-error.def uninstall-def-file: @@ -92,11 +102,14 @@ libgpg_error_la_LDFLAGS = -version-info \ libgpg_error_la_SOURCES = gpg-error.h gettext.h $(arch_sources) \ init.c strsource.c strerror.c code-to-errno.c code-from-errno.c -libgpg_error_la_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" +# Note that RCCOMPILE needs the same defines as ..._la_CPPFLAGS but +# without the extra_cppflags because they may include am -idirafter +# which is not supported by the RC compiler. +libgpg_error_la_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags) libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) gpg_error_SOURCES = strsource-sym.c strerror-sym.c gpg-error.c $(arch_sources) -gpg_error_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" +gpg_error_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags) gpg_error_LDADD = ./libgpg-error.la @LTLIBINTL@ err-sources.h: Makefile mkstrtable.awk err-sources.h.in @@ -119,16 +132,41 @@ code-to-errno.h: Makefile mkerrnos.awk errnos.in $(AWK) -f $(srcdir)/mkerrnos.awk $(srcdir)/errnos.in >$@ # It is correct to use $(CPP). We want the host's idea of the error codes. -mkerrcodes.h: Makefile mkerrcodes.awk +mkerrcodes.h: Makefile mkerrcodes.awk $(extra_headers) $(AWK) -f $(srcdir)/mkerrcodes1.awk $(srcdir)/errnos.in >_$@ - $(CPP) _$@ | grep GPG_ERR_ | $(AWK) -f $(srcdir)/mkerrcodes.awk >$@ + $(CPP) $(extra_cppflags) _$@ | grep GPG_ERR_ | \ + $(AWK) -f $(srcdir)/mkerrcodes.awk >$@ -rm _$@ +if HAVE_W32CE_SYSTEM +# It is correct to use $(CPP). We want the host's idea of the error codes. +mkw32errmap.tab.h: Makefile mkw32errmap.c + $(CPP) -DRESOLVE_MACROS $(srcdir)/mkw32errmap.c | \ + grep '{&mkw32errmap_marker' >$@ +gpg-extra/errno.h: mkw32errmap + ./mkw32errmap > $@ +endif + +# We use CC proper for preprocessing thus we have to convince it that +# the data is really to be preprocessed. +gpg-error.def: Makefile gpg-error.def.in + cat $(srcdir)/gpg-error.def.in >[email protected] + $(CPP) $(DEFAULT_INCLUDES) $(INCLUDES) $(extra_cppflags) [email protected] | \ + grep -v '^#' >$@ + -rm [email protected] + # It is correct to use $(CC_FOR_BUILD) here. We want to run the # program at build time. mkerrcodes: mkerrcodes.c mkerrcodes.h Makefile $(CC_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkerrcodes.c +if HAVE_W32CE_SYSTEM +# It is correct to use $(CC_FOR_BUILD) here. We want to run the +# program at build time. +mkw32errmap: mkw32errmap.c mkw32errmap.tab.h Makefile + $(CC_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkw32errmap.c +endif + code-from-errno.h: mkerrcodes Makefile ./mkerrcodes | $(AWK) -f $(srcdir)/mkerrcodes2.awk >$@ @@ -137,10 +175,18 @@ errnos-sym.h: Makefile mkstrtable.awk errnos.in -v prefix=GPG_ERR_ -v namespace=errnos_ \ $(srcdir)/errnos.in >$@ -gpg-error.h: Makefile mkheader.awk \ - err-sources.h.in err-codes.h.in errnos.in gpg-error.h.in +extra-h.in: Makefile w32ce-add.h + -rm extra-h.in +if HAVE_W32CE_SYSTEM + cat $(srcdir)/w32ce-add.h >extra-h.in +endif + echo EOF >>extra-h.in + +gpg-error.h: Makefile mkheader.awk err-sources.h.in err-codes.h.in \ + errnos.in extra-h.in gpg-error.h.in $(AWK) -f $(srcdir)/mkheader.awk \ $(srcdir)/err-sources.h.in \ $(srcdir)/err-codes.h.in \ $(srcdir)/errnos.in \ + extra-h.in \ $(srcdir)/gpg-error.h.in > $@ diff --git a/src/gpg-error-config.in b/src/gpg-error-config.in index 76c41ca..4be0343 100644 --- a/src/gpg-error-config.in +++ b/src/gpg-error-config.in @@ -14,6 +14,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ +isubdirafter="@GPG_ERROR_CONFIG_ISUBDIRAFTER@" output="" @@ -60,12 +61,18 @@ while test $# -gt 0; do if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then output="$output -I$includedir" fi + # Note: -idirafter is a gcc extension. It is only used on + # systems where gcc is the only compiler we support. + for i in $isubdirafter; do + output="$output -idirafter ${includedir}/${i}" + done + output="$output @GPG_ERROR_CONFIG_CFLAGS@" ;; --libs) if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then output="$output -L$libdir" fi - output="$output -lgpg-error" + output="$output @GPG_ERROR_CONFIG_LIBS@" ;; *) usage 1 1>&2 diff --git a/src/gpg-error.c b/src/gpg-error.c index c2fadb8..eefd672 100644 --- a/src/gpg-error.c +++ b/src/gpg-error.c @@ -71,7 +71,11 @@ i18n_init (void) setlocale (LC_TIME, ""); setlocale (LC_MESSAGES, ""); # else - setlocale (LC_ALL, "" ); +# ifdef HAVE_W32_SYSTEM +# warning setlocal is missing +# else + setlocale (LC_ALL, "" ); +# endif # endif locale_dir = get_locale_dir (); @@ -158,6 +162,7 @@ read_w32_registry_string( const char *root, const char *dir, const char *name ) goto leave; } result[nbytes] = 0; /* make sure it is really a string */ +#ifndef HAVE_W32CE_SYSTEM if (type == REG_EXPAND_SZ && strchr (result, '%')) { char *tmp; @@ -196,6 +201,7 @@ read_w32_registry_string( const char *root, const char *dir, const char *name ) free (tmp); } } +#endif /*HAVE_W32CE_SYSTEM*/ leave: RegCloseKey( key_handle ); @@ -255,7 +261,7 @@ get_err_from_number (char *str, gpg_error_t *err) unsigned long nr; char *tail; - errno = 0; + gpg_err_set_errno (0); nr = strtoul (str, &tail, 0); if (errno) return 0; diff --git a/src/gpg-error.def b/src/gpg-error.def deleted file mode 100644 index d595b79..0000000 --- a/src/gpg-error.def +++ /dev/null @@ -1,11 +0,0 @@ - -EXPORTS - gpg_strerror @1 - gpg_strerror_r @2 - gpg_strsource @3 - gpg_err_code_from_errno @4 - gpg_err_code_to_errno @5 - gpg_err_init @6 - gpg_err_code_from_syserror @7 - - diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in new file mode 100644 index 0000000..dcf22ac --- /dev/null +++ b/src/gpg-error.def.in @@ -0,0 +1,20 @@ +/* gpg-error.def.in - Exported symbols + * Needs to be processed by CPP. + */ + +#include <config.h> + +EXPORTS + gpg_strerror @1 + gpg_strerror_r @2 + gpg_strsource @3 + gpg_err_code_from_errno @4 + gpg_err_code_to_errno @5 + gpg_err_init @6 + gpg_err_code_from_syserror @7 +#ifdef HAVE_W32CE_SYSTEM + _gpg_w32ce_strerror @8 + _gpg_w32ce_get_errno @9 +#endif + gpg_err_set_errno @10 + diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index f86201c..7068add 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1,5 +1,5 @@ /* gpg-error.h - Public interface to libgpg-error. - Copyright (C) 2003, 2004 g10 Code GmbH + Copyright (C) 2003, 2004, 2010 g10 Code GmbH This file is part of libgpg-error. @@ -14,9 +14,9 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with libgpg-error; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + #ifndef GPG_ERROR_H #define GPG_ERROR_H 1 @@ -231,7 +231,11 @@ int gpg_err_code_to_errno (gpg_err_code_t code); gpg_err_code_t gpg_err_code_from_syserror (void); +/* Set the ERRNO variable. This function is the preferred way to set + ERRNO due to peculiarities on WindowsCE. */ +void gpg_err_set_errno (int err); +@include extra-h.in /* Self-documenting convenience functions. */ diff --git a/src/gpg-extra/errno.h b/src/gpg-extra/errno.h new file mode 100644 index 0000000..7670fda --- /dev/null +++ b/src/gpg-extra/errno.h @@ -0,0 +1,60 @@ +/* errno.h - WindowsCE errno.h substitute + Copyright (C) 2010 g10 Code GmbH + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + +++ Do not edit! File has been generated by mkw32errmap.c +++ + + This file is intended to be used with ming32ce-gcc to implement an + errno substitute under WindowsCE. It must be included via gcc's + -idirafter option. The gpg-error-config script emits the + appropriate option snippet. The actual implementation of the errno + related functions are part of libgpg-error. A separate header file + is required because errno.h is often included before gpg-error.h. + */ + +#ifndef _GPG_ERROR_EXTRA_ERRNO_H +#define _GPG_ERROR_EXTRA_ERRNO_H + +/* Due to peculiarities in W32 we can't implement ERRNO as an + writable lvalue. This also allows us to easily find places + where ERRNO is being written to. See also gpg_err_set_errno. */ +int _gpg_w32ce_get_errno (void); +#define errno (_gpg_w32ce_get_errno ()) + +#define ENOENT 2 +#define EMFILE 4 +#define EACCES 5 +#define EBADF 6 +#define ENOMEM 8 +#define EXDEV 17 +#define ENFILE 18 +#define EROFS 19 +#define ENOLCK 36 +#define ENOSYS 50 +#define EEXIST 80 +#define EPERM 82 +#define EINVAL 87 +#define EINTR 104 +#define EPIPE 109 +#define ENOSPC 112 +#define ENOTEMPTY 145 +#define EBUSY 170 +#define ENAMETOOLONG 206 +#define EAGAIN 234 +#define ENOTDIR 267 +#define ERANGE 534 +#define ENXIO 1006 +#define EFAULT 1067 +#define EIO 1117 +#define EDEADLOCK 1131 +#define ENODEV 1200 + +#endif /*_GPG_ERROR_EXTRA_ERRNO_H*/ @@ -35,13 +35,25 @@ /* Locale directory support. */ #if HAVE_W32_SYSTEM -/* The implementation follows below. */ +/* The TLS space definition. */ +struct tls_space_s +{ + /* 119 bytes for an error message should be enough. With this size + we can assume that the allocation does not take up more than 128 + bytes per thread. */ + char strerror_buffer[120]; +}; +static int tls_index; /* Index for the TLS functions. */ + static char *get_locale_dir (void); static void drop_locale_dir (char *locale_dir); -#else + +#else /*!HAVE_W32_SYSTEM*/ + #define get_locale_dir() LOCALEDIR #define drop_locale_dir(dir) -#endif + +#endif /*!HAVE_W32_SYSTEM*/ /* Initialize the library. This function should be run early. */ @@ -121,62 +133,72 @@ read_w32_registry_string( const char *root, const char *dir, const char *name ) } nbytes = 1; - if( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) { - if (root) - goto leave; - /* Try to fallback to HKLM also vor a missing value. */ - RegCloseKey (key_handle); - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) - return NULL; /* Nope. */ - if (RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes)) - goto leave; - } - result = malloc( (n1=nbytes+1) ); + if( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) + { + if (root) + goto leave; + /* Try to fallback to HKLM also vor a missing value. */ + RegCloseKey (key_handle); + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) + return NULL; /* Nope. */ + if (RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes)) + goto leave; + } + result = malloc ( (n1=nbytes+1) ); if( !result ) goto leave; - if( RegQueryValueEx( key_handle, name, 0, &type, result, &n1 ) ) { - free(result); result = NULL; - goto leave; - } + if( RegQueryValueEx( key_handle, name, 0, &type, result, &n1 ) ) + { + free(result); result = NULL; + goto leave; + } result[nbytes] = 0; /* make sure it is really a string */ - if (type == REG_EXPAND_SZ && strchr (result, '%')) { - char *tmp; - n1 += 1000; - tmp = malloc (n1+1); - if (!tmp) - goto leave; - nbytes = ExpandEnvironmentStrings (result, tmp, n1); - if (nbytes && nbytes > n1) { - free (tmp); - n1 = nbytes; - tmp = malloc (n1 + 1); +#ifndef HAVE_W32CE_SYSTEM /* W32CE has no environment variables. */ + if (type == REG_EXPAND_SZ && strchr (result, '%')) + { + char *tmp; + + n1 += 1000; + tmp = malloc (n1+1); if (!tmp) - goto leave; + goto leave; nbytes = ExpandEnvironmentStrings (result, tmp, n1); - if (nbytes && nbytes > n1) { - free (tmp); /* oops - truncated, better don't expand at all */ - goto leave; - } - tmp[nbytes] = 0; - free (result); - result = tmp; + if (nbytes && nbytes > n1) + { + free (tmp); + n1 = nbytes; + tmp = malloc (n1 + 1); + if (!tmp) + goto leave; + nbytes = ExpandEnvironmentStrings (result, tmp, n1); + if (nbytes && nbytes > n1) + { + free (tmp); /* oops - truncated, better don't expand at all */ + goto leave; + } + tmp[nbytes] = 0; + free (result); + result = tmp; + } + else if (nbytes) /* okay, reduce the length */ + { + tmp[nbytes] = 0; + free (result); + result = malloc (strlen (tmp)+1); + if (!result) + result = tmp; + else { + strcpy (result, tmp); + free (tmp); + } + } + else /* error - don't expand */ + { + free (tmp); + } } - else if (nbytes) { /* okay, reduce the length */ - tmp[nbytes] = 0; - free (result); - result = malloc (strlen (tmp)+1); - if (!result) - result = tmp; - else { - strcpy (result, tmp); - free (tmp); - } - } - else { /* error - don't expand */ - free (tmp); - } - } +#endif /*HAVE_W32CE_SYSTEM*/ leave: RegCloseKey( key_handle ); @@ -223,4 +245,132 @@ drop_locale_dir (char *locale_dir) free (locale_dir); } -#endif /* HAVE_W32_SYSTEM */ + +/* Return the tls object. This function is guaranteed to return a + valid non-NULL object. */ +#ifdef HAVE_W32CE_SYSTEM +static struct tls_space_s * +get_tls (void) +{ + struct tls_space_s *tls; + + tls = TlsGetValue (tls_index); + if (!tls) + { + /* Called by a thread which existed before this DLL was loaded. + Allocate the space. */ + tls = LocalAlloc (LPTR, sizeof *tls); + if (!tls) + { + /* No way to continue - commit suicide. */ + abort (); + } + TlsSetValue (tls_index, tls); + } + + return tls; +} +#endif /*HAVE_W32CE_SYSTEM*/ + +/* Return the value of the ERRNO variable. This needs to be a + function so that we can have a per-thread ERRNO. This is used only + on WindowsCE because that OS misses an errno. */ +#ifdef HAVE_W32CE_SYSTEM +int +_gpg_w32ce_get_errno (void) +{ + int err; + + err = GetLastError (); + /* FIXME: Should we fold some W32 error codes into the same errno + value? */ + return err; +} +#endif /*HAVE_W32CE_SYSTEM*/ + + +/* Replacement strerror function for WindowsCE. */ +#ifdef HAVE_W32CE_SYSTEM +char * +_gpg_w32ce_strerror (int err) +{ + struct tls_space_s *tls = get_tls (); + + if (err == -1) + err = _gpg_w32ce_get_errno (); + if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + tls->strerror_buffer, sizeof tls->strerror_buffer -1, + NULL)) + snprintf (tls->strerror_buffer, sizeof tls->strerror_buffer -1, + "[w32err=%d]", err); + return tls->strerror_buffer; +} +#endif /*HAVE_W32CE_SYSTEM*/ + + +void +gpg_err_set_errno (int err) +{ +#ifdef HAVE_W32CE_SYSTEM + SetLastError (err); +#else /*!HAVE_W32CE_SYSTEM*/ + errno = err; +#endif /*!HAVE_W32CE_SYSTEM*/ +} + + +/* Entry point called by the DLL loader. This is only used by + WindowsCE for now; we might eventually use TLS to implement a + thread safe strerror. */ +#ifdef HAVE_W32CE_SYSTEM +int WINAPI +DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) +{ + struct tls_space_s *tls; + (void)reserved; + + switch (reason) + { + case DLL_PROCESS_ATTACH: + tls_index = TlsAlloc (); + if (tls_index == TLS_OUT_OF_INDEXES) + return FALSE; + /* falltru. */ + case DLL_THREAD_ATTACH: + tls = LocalAlloc (LPTR, sizeof *tls); + if (!tls) + return FALSE; + TlsSetValue (tls_index, tls); + break; + + case DLL_THREAD_DETACH: + tls = TlsGetValue (tls_index); + if (tls) + LocalFree (tls); + break; + + case DLL_PROCESS_DETACH: + tls = TlsGetValue (tls_index); + if (tls) + LocalFree (tls); + TlsFree (tls_index); + break; + + default: + break; + } + + return TRUE; +} +#endif /*HAVE_W32CE_SYSTEM*/ + +#else /*!HAVE_W32_SYSTEM*/ + +void +gpg_err_set_errno (int err) +{ + errno = err; +} + +#endif /*!HAVE_W32_SYSTEM*/ diff --git a/src/mkheader.awk b/src/mkheader.awk index 67de05d..0d09a8c 100644 --- a/src/mkheader.awk +++ b/src/mkheader.awk @@ -58,6 +58,8 @@ BEGIN { codes_nr = 0; # errnos_nr holds the number of system errors. errnos_nr = 0; +# extra_nr holds the number of extra lines to be included. + extra_nr = 0 # These variables walk us through our input. sources_header = 1; @@ -66,6 +68,7 @@ BEGIN { codes_body = 0; between_codes_and_errnos = 0; errnos_body = 0; + extra_body = 0; gpg_error_h = 0; print "/* Output of mkheader.awk. DO NOT EDIT. */"; @@ -148,9 +151,9 @@ errnos_body { if ($1 !~ /^[0-9]/) { -# Note that this assumes that gpg-error.h.in doesn't start with a digit. +# Note that this assumes that extra_body.in doesn't start with a digit. errnos_body = 0; - gpg_error_h = 1; + extra_body = 1; } else { @@ -160,6 +163,23 @@ errnos_body { } } +extra_body { + if (/^##/) + next + + if (/^EOF/) + { + extra_body = 0; + gpg_error_h = 1; + next; + } + else + { + extra_line[extra_nr] = $0; + extra_nr++; + } +} + gpg_error_h { if ($0 ~ /^@include err-sources/) { @@ -180,9 +200,16 @@ gpg_error_h { else if ($0 ~ /^@include errnos/) { for (i = 0; i < errnos_nr; i++) + { + print " " errnos_sym[i] " = " errnos_idx[i] ","; +# print "#define " errnos_sym[i] " (" errnos_idx[i] ")"; + } + } + else if ($0 ~ /^@include extra-h.in/) + { + for (i = 0; i < extra_nr; i++) { - print " " errnos_sym[i] " = " errnos_idx[i] ","; -# print "#define " errnos_sym[i] " (" errnos_idx[i] ")"; + print extra_line[i]; } } else diff --git a/src/w32-gettext.c b/src/w32-gettext.c index 03ef24d..1b6eb3d 100644 --- a/src/w32-gettext.c +++ b/src/w32-gettext.c @@ -68,7 +68,9 @@ #endif #include <stdlib.h> -#include <locale.h> +#ifndef HAVE_W32CE_SYSTEM +# include <locale.h> +#endif #ifdef HAVE_W32_SYSTEM # include <windows.h> @@ -776,6 +778,7 @@ _nl_locale_name (int category, const char *categoryname) /* Let the user override the system settings through environment variables, as on POSIX systems. */ +#ifndef HAVE_W32CE_SYSTEM retval = getenv ("LC_ALL"); if (retval != NULL && retval[0] != '\0') return retval; @@ -785,9 +788,14 @@ _nl_locale_name (int category, const char *categoryname) retval = getenv ("LANG"); if (retval != NULL && retval[0] != '\0') return retval; +#endif /*!HAVE_W32CE_SYSTEM*/ /* Use native Win32 API locale ID. */ +#ifdef HAVE_W32CE_SYSTEM + lcid = GetSystemDefaultLCID (); +#else lcid = GetThreadLocale (); +#endif /* Strip off the sorting rules, keep only the language part. */ langid = LANGIDFROMLCID (lcid); diff --git a/src/w32-gettext.h b/src/w32-gettext.h index ee11f2a..ce69ffe 100644 --- a/src/w32-gettext.h +++ b/src/w32-gettext.h @@ -20,7 +20,11 @@ #if ENABLE_NLS -#include <locale.h> +#ifdef HAVE_W32CE_SYSTEM +# define LC_ALL 0 +#else +# include <locale.h> +#endif #if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun)) # define LC_MESSAGES 1729 #endif diff --git a/src/w32ce-add.h b/src/w32ce-add.h new file mode 100644 index 0000000..83b7538 --- /dev/null +++ b/src/w32ce-add.h @@ -0,0 +1,7 @@ +## w32ce-add.h - Snippet to be be included into gpg-error.h. +## (Comments are indicated by a double hash mark) + +/* Substitute for strerror - this one is thread safe. */ +char *_gpg_w32ce_strerror (int err); +#define strerror(a) _gpg_w32ce_strerror (a) + diff --git a/tests/Makefile.am b/tests/Makefile.am index 488f86f..be63260 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -19,9 +19,16 @@ ## Process this file with automake to produce Makefile.in +if HAVE_W32CE_SYSTEM +extra_includes = -idirafter $(top_builddir)/src/gpg-extra +else +extra_includes = +endif + + TESTS = t-strerror t-syserror -INCLUDES = -I$(top_builddir)/src +INCLUDES = -I$(top_builddir)/src $(extra_includes) LDADD = ../src/libgpg-error.la diff --git a/tests/t-syserror.c b/tests/t-syserror.c index b6973c3..25de86f 100644 --- a/tests/t-syserror.c +++ b/tests/t-syserror.c @@ -64,7 +64,7 @@ main (int argc, char *argv[]) return 1; } - errno = 0; + gpg_err_set_errno (0); ec = gpg_err_code_from_syserror (); if (ec != GPG_ERR_MISSING_ERRNO) |