about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-11-10 20:38:31 +0000
committerRoland McGrath <roland@gnu.org>1995-11-10 20:38:31 +0000
commit75914335da0fd12367af3072dce4f7083829f09e (patch)
tree0dd7aefd0b944042d3993533ac601e5626f7c02d
parentd7435cd836d451ddfaedd800616ab79d007c9305 (diff)
downloadglibc-75914335da0fd12367af3072dce4f7083829f09e.tar.gz
glibc-75914335da0fd12367af3072dce4f7083829f09e.tar.xz
glibc-75914335da0fd12367af3072dce4f7083829f09e.zip
Fri Nov 10 14:15:21 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
	* hurd/hurdsig.c (_hurd_internal_post_signal): For SIGNO == 0,
	skip straight to pending check.  When UNTRACED, resume process
	from suspension first.

	* intl/Makefile (headers): New variable, libintl.h.
	[gettext-srcdir]: New rules to copy source from $(gettext-srcdir)/intl.
	* configure.in: Check for --with-gettext arg.

Fri Nov 10 13:51:30 1995  Richard Stallman  <rms@gnu.ai.mit.edu>

	* malloc/malloc.c (get_contiguous_space): New function.
	(morecore): Rewrite allocating new malloc info table.
	(_malloc_internal): Use get_contiguous_space.

Fri Nov 10 13:03:40 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* hurd/hurdexec.c (_hurd_exec): If exec'ing self, pass
	_hurd_msgport to be destroyed.

	* Makerules (installed-libcs): Filter out %_pic.a.

	* hurd/hurdinit.c (_hurd_proc_init): When traced, use msg_sig_post
	to our msgport to take SIGTRAP, instead of _hurd_raise_signal.

	* hurd/Makefile (user-interfaces): Add hurd/process_request.
-rw-r--r--ChangeLog28
-rw-r--r--Makerules1
-rwxr-xr-xconfigure27
-rw-r--r--configure.in15
-rw-r--r--hurd/Makefile3
-rw-r--r--hurd/hurdexec.c6
-rw-r--r--hurd/hurdinit.c2
-rw-r--r--hurd/hurdsig.c112
-rw-r--r--intl/Makefile15
-rw-r--r--intl/dcgettext.c15
-rw-r--r--intl/finddomain.c221
-rw-r--r--intl/gettext.c2
-rw-r--r--intl/libintl.h (renamed from locale/libintl.h)0
-rw-r--r--intl/loadmsgcat.c7
-rw-r--r--intl/localealias.c10
-rw-r--r--libintl.h2
16 files changed, 296 insertions, 170 deletions
diff --git a/ChangeLog b/ChangeLog
index 207092eb97..c55cda94f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+Fri Nov 10 14:15:21 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* hurd/hurdsig.c (_hurd_internal_post_signal): For SIGNO == 0,
+	skip straight to pending check.  When UNTRACED, resume process
+	from suspension first.
+
+	* intl/Makefile (headers): New variable, libintl.h.
+	[gettext-srcdir]: New rules to copy source from $(gettext-srcdir)/intl.
+	* configure.in: Check for --with-gettext arg.
+
+Fri Nov 10 13:51:30 1995  Richard Stallman  <rms@gnu.ai.mit.edu>
+
+	* malloc/malloc.c (get_contiguous_space): New function.
+	(morecore): Rewrite allocating new malloc info table.
+	(_malloc_internal): Use get_contiguous_space.
+
+Fri Nov 10 13:03:40 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* hurd/hurdexec.c (_hurd_exec): If exec'ing self, pass
+	_hurd_msgport to be destroyed.
+
+	* Makerules (installed-libcs): Filter out %_pic.a.
+
+	* hurd/hurdinit.c (_hurd_proc_init): When traced, use msg_sig_post
+	to our msgport to take SIGTRAP, instead of _hurd_raise_signal.
+
+	* hurd/Makefile (user-interfaces): Add hurd/process_request.
+
 Wed Nov  8 16:31:25 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
 	* termios/Makefile (headers): Add sys/ttychars.h.
diff --git a/Makerules b/Makerules
index 1ae1384ffa..1f678d588e 100644
--- a/Makerules
+++ b/Makerules
@@ -457,6 +457,7 @@ ifdef objects
 installed-libcs := $(foreach o,$(object-suffixes),\
 			     $(libdir)/$(patsubst %,$(libtype$o),\
 						  $(libprefix)$(libc-name)))
+installed-libcs := $(filter-out %_pic.a,$(installed-libcs))
 install: $(installed-libcs)
 $(installed-libcs): $(libdir)/lib$(libprefix)%: lib
 	$(make-target-directory)
diff --git a/configure b/configure
index 0476b00499..26935c74c0 100755
--- a/configure
+++ b/configure
@@ -15,6 +15,8 @@ ac_default_prefix=/usr/local
 ac_help="$ac_help
   --with-gmp=DIRECTORY	  find GMP source code in DIRECTORY (not needed)"
 ac_help="$ac_help
+  --with-gettext=DIR	  find GNU gettext source code in DIR (not needed)"
+ac_help="$ac_help
   --with-fp		  if using floating-point hardware"
 ac_help="$ac_help
   --with-gnu-binutils	  if using GNU binutils (as and ld)"
@@ -558,6 +560,21 @@ esac
 
 fi
 
+# Check for a --with-gettext argument and set gettext-srcdir in config.make.
+# Check whether --with-gettext or --without-gettext was given.
+if test "${with_gettext+set}" = set; then
+  withval="$with_gettext"
+  case "$with_gettext" in
+yes)
+  { echo "configure: error: --with-gettext requires an argument; use --with-gettext=DIR" 1>&2; exit 1; } ;;
+''|no) ;;
+*)
+  config_vars="$config_vars
+gettext-srcdir = $withval" ;;
+esac
+
+fi
+
 
 # Check whether --with-fp or --without-fp was given.
 if test "${with_fp+set}" = set; then
@@ -768,7 +785,7 @@ ostry=$os
 while o=`echo $tail | sed 's/\.[^.]*$//'`; test $o != $tail; do
   ostry="$ostry /$o"
   tail=$o
-done  
+done
 o=`echo $tail | sed 's/[0-9]*$//'`
 if test $o != $tail; then
   ostry="$ostry /$o"
@@ -1133,7 +1150,7 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1137 "configure"
+#line 1154 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1147,7 +1164,7 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1151 "configure"
+#line 1168 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1201,7 +1218,7 @@ if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&4
 else
   cat > conftest.$ac_ext <<EOF
-#line 1205 "configure"
+#line 1222 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1324,7 +1341,7 @@ if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&4
 else
   cat > conftest.$ac_ext <<EOF
-#line 1328 "configure"
+#line 1345 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
diff --git a/configure.in b/configure.in
index ead6813ba0..6b2624e254 100644
--- a/configure.in
+++ b/configure.in
@@ -18,6 +18,19 @@ yes) AC_MSG_ERROR(--with-gmp requires an argument; use --with-gmp=DIRECTORY) ;;
 gmp-srcdir = $withval" ;;
 esac
 ])
+# Check for a --with-gettext argument and set gettext-srcdir in config.make.
+AC_ARG_WITH(gettext, dnl
+  --with-gettext=DIR	  find GNU gettext source code in DIR (not needed),
+	    [dnl
+case "$with_gettext" in
+yes)
+  AC_MSG_ERROR(--with-gettext requires an argument; use --with-gettext=DIR) ;;
+''|no) ;;
+*)
+  config_vars="$config_vars
+gettext-srcdir = $withval" ;;
+esac
+])
 
 dnl Arguments to specify presence of other packages/features.
 AC_ARG_WITH(fp, dnl
@@ -133,7 +146,7 @@ ostry=$os
 while o=`echo $tail | sed 's/\.[^.]*$//'`; test $o != $tail; do
   ostry="$ostry /$o"
   tail=$o
-done  
+done
 o=`echo $tail | sed 's/[0-9]*$//'`
 if test $o != $tail; then
   ostry="$ostry /$o"
diff --git a/hurd/Makefile b/hurd/Makefile
index 8d1f19464b..69f9e96031 100644
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -33,7 +33,8 @@ distribute := hurdstartup.h hurdfault.h intr-rpc.defs STATUS
 # The RPC interfaces go in a separate library.
 interface-library := libhurduser
 user-interfaces		:= $(addprefix hurd/,\
-				       auth process startup \
+				       auth startup \
+				       process process_request \
 				       msg msg_reply msg_request \
 				       exec exec_startup crash interrupt \
 				       fs fsys io term socket ifsock)
diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c
index 0ac18e42da..149e95ccec 100644
--- a/hurd/hurdexec.c
+++ b/hurd/hurdexec.c
@@ -30,7 +30,7 @@ Cambridge, MA 02139, USA.  */
    If TASK == mach_task_self (), some ports are dealloc'd by the exec server.
    ARGV and ENVP are terminated by NULL pointers.  */
 error_t
-_hurd_exec (task_t task, file_t file, 
+_hurd_exec (task_t task, file_t file,
 	    char *const argv[], char *const envp[])
 {
   error_t err;
@@ -129,7 +129,7 @@ _hurd_exec (task_t task, file_t file,
      in the exec, or the signal will never be delivered.  Setting the
      critical section flag avoids anything we call trying to acquire the
      sigstate lock.  */
-  
+
   ss->critical_section = 1;
   __spin_unlock (&ss->lock);
 
@@ -224,7 +224,7 @@ _hurd_exec (task_t task, file_t file,
 		       ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
 		       ints, INIT_INT_MAX,
 		       please_dealloc, pdp - please_dealloc,
-		       NULL, 0);
+		       &_hurd_msgport, task == __mach_task_self () ? 1 : 0);
   }
 
   /* Release references to the standard ports.  */
diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c
index 409d2d19a0..bed78b8321 100644
--- a/hurd/hurdinit.c
+++ b/hurd/hurdinit.c
@@ -151,7 +151,7 @@ _hurd_proc_init (char **argv)
     /* This process is "traced", meaning it should stop on signals or exec.
        We are all set up now to handle signals.  Stop ourselves, to inform
        our parent (presumably a debugger) that the exec has completed.  */
-    _hurd_raise_signal (NULL, SIGTRAP, 0, 0);
+    __msg_sig_post (_hurd_msgport, SIGTRAP, __mach_task_self ());
 }
 
 /* Called when we get a message telling us to change our proc server port.  */
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 7affb906d5..68be2e9bd0 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -265,11 +265,14 @@ interrupted_reply_port_location (struct machine_thread_all_state *thread_state,
    incoming signal, returns the reply port to be received on.  Otherwise
    returns MACH_PORT_NULL.
 
+   SIGNO is used to find the applicable SA_RESTART bit.  If SIGNO is zero,
+   the RPC fails with EINTR instead of restarting (thread_cancel).
+
    *STATE_CHANGE is set nonzero if STATE->basic was modified and should
    be applied back to the thread if it might ever run again, else zero.  */
 
 mach_port_t
-_hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread, 
+_hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
 		     struct machine_thread_all_state *state, int *state_change,
 		     mach_port_t *reply_port,
 		     mach_msg_type_name_t reply_port_type,
@@ -480,6 +483,52 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 		 }));
       _hurd_stopped = 1;
     }
+  /* Resume the process after a suspension.  */
+  void resume (void)
+    {
+      /* Resume the process from being stopped.  */
+      thread_t *threads;
+      mach_msg_type_number_t nthreads, i;
+      error_t err;
+
+      if (! _hurd_stopped)
+	return;
+
+      /* Tell the proc server we are continuing.  */
+      __USEPORT (PROC, __proc_mark_cont (port));
+      /* Fetch ports to all our threads and resume them.  */
+      err = __task_threads (__mach_task_self (), &threads, &nthreads);
+      assert_perror (err);
+      for (i = 0; i < nthreads; ++i)
+	{
+	  if (threads[i] != _hurd_msgport_thread &&
+	      (act != handle || threads[i] != ss->thread))
+	    {
+	      err = __thread_resume (threads[i]);
+	      assert_perror (err);
+	    }
+	  err = __mach_port_deallocate (__mach_task_self (),
+					threads[i]);
+	  assert_perror (err);
+	}
+      __vm_deallocate (__mach_task_self (),
+		       (vm_address_t) threads,
+		       nthreads * sizeof *threads);
+      _hurd_stopped = 0;
+      /* The thread that will run the handler is already suspended.  */
+      ss_suspended = 1;
+    }
+
+  if (signo == 0)
+    {
+      if (untraced)
+	/* This is PTRACE_CONTINUE.  */
+	resume ();
+
+      /* This call is just to check for pending signals.  */
+      __spin_lock (&ss->lock);
+      goto check_pending_signals;
+    }
 
  post_signal:
 
@@ -514,8 +563,6 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 
       __spin_lock (&ss->lock);
 
-      handler = ss->actions[signo].sa_handler;
-
       if (!untraced && (_hurd_exec_flags & EXEC_TRACED))
 	{
 	  /* We are being traced.  Stop to tell the debugger of the signal.  */
@@ -530,6 +577,8 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	  return;
 	}
 
+      handler = ss->actions[signo].sa_handler;
+
       if (handler == SIG_DFL)
 	/* Figure out the default action for this signal.  */
 	switch (signo)
@@ -604,35 +653,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	    ss->pending &= ~STOPSIGS;
 
 	  if (_hurd_stopped && act != stop && (untraced || signo == SIGCONT))
-	    {
-	      /* Resume the process from being stopped.  */
-	      thread_t *threads;
-	      mach_msg_type_number_t nthreads, i;
-	      error_t err;
-	      /* Tell the proc server we are continuing.  */
-	      __USEPORT (PROC, __proc_mark_cont (port));
-	      /* Fetch ports to all our threads and resume them.  */
-	      err = __task_threads (__mach_task_self (), &threads, &nthreads);
-	      assert_perror (err);
-	      for (i = 0; i < nthreads; ++i)
-		{
-		  if (threads[i] != _hurd_msgport_thread &&
-		      (act != handle || threads[i] != ss->thread))
-		    {
-		      err = __thread_resume (threads[i]);
-		      assert_perror (err);
-		    }
-		  err = __mach_port_deallocate (__mach_task_self (),
-						threads[i]);
-		  assert_perror (err);
-		}
-	      __vm_deallocate (__mach_task_self (),
-			       (vm_address_t) threads,
-			       nthreads * sizeof *threads);
-	      _hurd_stopped = 0;
-	      /* The thread that will run the handler is already suspended.  */
-	      ss_suspended = 1;
-	    }
+	    resume ();
 	}
     }
 
@@ -648,10 +669,8 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
       act = term;
     }
 
-  /* Handle receipt of a blocked signal, or any signal while stopped.
-     It matters that we test ACT first here, because we must never pass
-     SIGNO==0 to __sigismember.  */
-  if ((act != ignore && __sigismember (&ss->blocked, signo)) ||
+  /* Handle receipt of a blocked signal, or any signal while stopped.  */
+  if (__sigismember (&ss->blocked, signo) ||
       (signo != SIGKILL && _hurd_stopped))
     {
       mark_pending ();
@@ -754,7 +773,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 		ss->context = &ocontext;
 	      }
 	    _hurdsig_end_catch_fault ();
-	    
+
 	    if (! machine_get_basic_state (ss->thread, &thread_state))
 	      goto sigbomb;
 	    loc = interrupted_reply_port_location (&thread_state, 1);
@@ -772,7 +791,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	else
 	  {
 	    wait_for_reply
-	      = (_hurdsig_abort_rpcs (ss, signo, 1, 
+	      = (_hurdsig_abort_rpcs (ss, signo, 1,
 				      &thread_state, &state_changed,
 				      &reply_port, reply_port_type, untraced)
 		 != MACH_PORT_NULL);
@@ -851,12 +870,8 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
     }
 
   /* The signal has either been ignored or is now being handled.  We can
-     consider it delivered and reply to the killer.  The exception is
-     signal 0, which can be sent by a user thread to make us check for
-     pending signals.  In that case we want to deliver the pending signals
-     before replying.  */
-  if (signo != 0)
-    reply ();
+     consider it delivered and reply to the killer.  */
+  reply ();
 
   /* We get here unless the signal was fatal.  We still hold SS->lock.
      Check for pending signals, and loop to post them.  */
@@ -874,6 +889,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	return pending = ss->pending & ~ss->blocked;
       }
 
+  check_pending_signals:
+    untraced = 0;
+
     if (signals_pending ())
       {
       pending:
@@ -974,7 +992,7 @@ signal_allowed (int signo, mach_port_t refport)
 	/* A continue signal can be sent by anyone in the session.  */
 	mach_port_t sessport;
 	if (! __USEPORT (PROC, __proc_getsidport (port, &sessport)))
-	  { 
+	  {
 	    __mach_port_deallocate (__mach_task_self (), sessport);
 	    if (refport == sessport)
 	      goto win;
@@ -1099,7 +1117,7 @@ _hurdsig_init (void)
 				  MACH_PORT_RIGHT_RECEIVE,
 				  &_hurd_msgport))
     __libc_fatal ("hurd: Can't create message port receive right\n");
-  
+
   /* Make a send right to the signal port.  */
   if (err = __mach_port_insert_right (__mach_task_self (),
 				      _hurd_msgport,
@@ -1135,7 +1153,7 @@ _hurdsig_init (void)
 
   if (err = __thread_resume (_hurd_msgport_thread))
     __libc_fatal ("hurd: Can't resume signal thread\n");
-    
+
 #if 0				/* Don't confuse poor gdb.  */
   /* Receive exceptions on the signal port.  */
   __task_set_special_port (__mach_task_self (),
diff --git a/intl/Makefile b/intl/Makefile
index f7ef998fca..6e588fc88a 100644
--- a/intl/Makefile
+++ b/intl/Makefile
@@ -19,6 +19,7 @@
 # Cambridge, MA 02139, USA.
 
 subdir = intl
+headers = libintl.h
 routines = bindtextdom dcgettext dgettext gettext	\
 	   finddomain loadmsgcat localealias textdomain
 distribute = gettext.h gettextP.h hash-string.h
@@ -27,3 +28,17 @@ include ../Rules
 
 CPPFLAGS += -D'GNULOCALEDIR="$(localedir)"' \
 	    -D'LOCALE_ALIAS_PATH="$(localedir):$(nlsdir)"'
+
+ifdef gettext-srcdir
+
+%:: $(gettext-srcdir)/intl/%.glibc; $(copysrc)
+%:: $(gettext-srcdir)/intl/%; $(copysrc)
+
+define copysrc
+cp -f $< $@.new
+chmod a-w $@.new
+mv -f $@.new $@
+test ! -d CVS || cvs commit -m'Updated from $<' $@
+endef
+
+endif
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
index 91025be89b..09e0443494 100644
--- a/intl/dcgettext.c
+++ b/intl/dcgettext.c
@@ -317,14 +317,13 @@ DCGETTEXT (domainname, msgid, category)
 	    {
 	      int cnt;
 
-	      for (cnt = 6; cnt >= 0 && retval == NULL; --cnt)
-		if (domain->successor[cnt] != NULL)
-		  {
-		    retval = find_msg (domain->successor[cnt], msgid);
-
- 		    if (domain->successor[cnt]->data == NULL)
-		      domain->successor[cnt] = NULL;
-		  }
+	      for (cnt = 0; domain->successor[cnt] != NULL; --cnt)
+		{
+		  retval = find_msg (domain->successor[cnt], msgid);
+
+		  if (retval != NULL)
+		    break;
+		}
 	    }
 
 	  if (retval != NULL)
diff --git a/intl/finddomain.c b/intl/finddomain.c
index 19cf2d7581..007a87e075 100644
--- a/intl/finddomain.c
+++ b/intl/finddomain.c
@@ -95,6 +95,11 @@ static struct loaded_domain *make_entry_rec __P ((const char *dirname,
 						  const char *domainname,
 						  int do_allocate));
 
+/* Substitution for systems lacking this function in their C library.  */
+#if !_LIBC && !HAVE_STPCPY
+static char *stpcpy __P ((char *dest, const char *src));
+#endif
+
 
 /* Return a data structure describing the message catalog described by
    the DOMAINNAME and CATEGORY parameters with respect to the currently
@@ -155,9 +160,9 @@ _nl_find_domain (dirname, locale, domainname)
       if (retval->data != NULL)
 	return retval;
 
-      for (cnt = 6; cnt >= 0; --cnt)
+      for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
 	{
-	  if (retval->successor[cnt] == 0)
+	  if (retval->successor[cnt]->decided == 0)
 	    _nl_load_domain (retval->successor[cnt]);
 
 	  if (retval->successor[cnt]->data != NULL)
@@ -279,13 +284,13 @@ _nl_find_domain (dirname, locale, domainname)
      separator character in the file name, not for XPG syntax.  */
   if (syntax == xpg)
     {
-      if (territory[0] == '\0')
+      if (territory != NULL && territory[0] == '\0')
 	mask &= ~TERRITORY;
 
-      if (codeset[0] == '\0')
+      if (codeset != NULL && codeset[0] == '\0')
 	mask &= ~XPG_CODESET;
 
-      if (modifier[0] == '\0')
+      if (modifier != NULL && modifier[0] == '\0')
 	mask &= ~XPG_MODIFIER;
     }
 
@@ -340,107 +345,110 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier,
      const char *domain;
      int do_allocate;
 {
-  struct loaded_domain *retval, *last;
-  char *filename, *cp;
+  char *filename = NULL;
+  struct loaded_domain *last = NULL;
+  struct loaded_domain *retval;
+  char *cp;
   size_t entries;
   int cnt;
 
-  /* Allocate room for the full file name.  */
-  filename = (char *) malloc (strlen (dirname) + 1
-			      + strlen (language)
-			      + ((mask & TERRITORY) != 0
-				 ? strlen (territory) : 0)
-			      + ((mask & XPG_CODESET) != 0
-				 ? strlen (codeset) : 0)
-			      + ((mask & XPG_MODIFIER) != 0 ?
-				 strlen (modifier) : 0)
-			      + ((mask & CEN_SPECIAL) != 0
-				 ? strlen (special) : 0)
-			      + ((mask & CEN_SPONSOR) != 0
-				 ? strlen (sponsor) : 0)
-			      + ((mask & CEN_REVISION) != 0
-				 ? strlen (revision) : 0) + 1
-			      + strlen (domain) + 1);
-
-  if (filename == NULL)
-    return NULL;
 
-  retval = NULL;
-  last = NULL;
+  /* Process the current entry described by the MASK only when it is
+     valid.  Because the mask can have in the first call bits from
+     both syntaces set this is necessary to prevent constructing
+     illegal local names.  */
+  /* FIXME: Rewrite because test is necessary only in first round.  */
+  if ((mask & CEN_SPECIFIC) == 0 || (mask & XPG_SPECIFIC) == 0)
+    {
+      /* Allocate room for the full file name.  */
+      filename = (char *) malloc (strlen (dirname) + 1
+				  + strlen (language)
+				  + ((mask & TERRITORY) != 0
+				     ? strlen (territory) : 0)
+				  + ((mask & XPG_CODESET) != 0
+				     ? strlen (codeset) : 0)
+				  + ((mask & XPG_MODIFIER) != 0 ?
+				     strlen (modifier) : 0)
+				  + ((mask & CEN_SPECIAL) != 0
+				     ? strlen (special) : 0)
+				  + ((mask & CEN_SPONSOR) != 0
+				     ? strlen (sponsor) : 0)
+				  + ((mask & CEN_REVISION) != 0
+				     ? strlen (revision) : 0) + 1
+				  + strlen (domain) + 1);
+
+      if (filename == NULL)
+	return NULL;
 
-  /* We don't want libintl.a to depend on any other library.  So we
-     avoid the non-standard function stpcpy.  In GNU C Library this
-     function is available, though.  Also allow the symbol HAVE_STPCPY
-     to be defined.  */
-#if !defined _LIBC && !defined HAVE_STPCPY
-# define stpcpy(p, s)							    \
-  (strcpy (p, s), strchr (p, '\0'))
-#endif
+      retval = NULL;
+      last = NULL;
 
-  /* Construct file name.  */
-  cp = stpcpy (filename, dirname);
-  *cp++ = '/';
-  cp = stpcpy (cp, language);
+      /* Construct file name.  */
+      cp = stpcpy (filename, dirname);
+      *cp++ = '/';
+      cp = stpcpy (cp, language);
 
-  if ((mask & TERRITORY) != 0)
-    {
-      *cp++ = '_';
-      cp = stpcpy (cp, territory);
-    }
-  if ((mask & XPG_CODESET) != 0)
-    {
-      *cp++ = '.';
+      if ((mask & TERRITORY) != 0)
+	{
+	  *cp++ = '_';
+	  cp = stpcpy (cp, territory);
+	}
+      if ((mask & XPG_CODESET) != 0)
+	{
+	  *cp++ = '.';
       cp = stpcpy (cp, codeset);
-    }
-  if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
-    {
-      /* This component can be part of both syntaces but has different
-	 leading characters.  For CEN we use `+', else `@'.  */
-      *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
-      cp = stpcpy (cp, modifier);
-    }
-  if ((mask & CEN_SPECIAL) != 0)
-    {
-      *cp++ = '+';
-      cp = stpcpy (cp, special);
-    }
-  if ((mask & CEN_SPONSOR) != 0)
-    {
-      *cp++ = ',';
-      cp = stpcpy (cp, sponsor);
-    }
-  if ((mask & CEN_REVISION) != 0)
-    {
-      *cp++ = '_';
-      cp = stpcpy (cp, revision);
-    }
-
-  *cp++ = '/';
-  stpcpy (cp, domain);
-
-  /* Look in list of already loaded domains whether it is already
-     available.  */
-  last = NULL;
-  for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
-    {
-      int compare = strcmp (retval->filename, filename);
-      if (compare == 0)
-	/* We found it!  */
-	break;
-      if (compare < 0)
+	}
+      if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
 	{
-	  /* It's not in the list.  */
-	  retval = NULL;
-	  break;
+	  /* This component can be part of both syntaces but has different
+	     leading characters.  For CEN we use `+', else `@'.  */
+	  *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
+	  cp = stpcpy (cp, modifier);
+	}
+      if ((mask & CEN_SPECIAL) != 0)
+	{
+	  *cp++ = '+';
+	  cp = stpcpy (cp, special);
+	}
+      if ((mask & CEN_SPONSOR) != 0)
+	{
+	  *cp++ = ',';
+	  cp = stpcpy (cp, sponsor);
+	}
+      if ((mask & CEN_REVISION) != 0)
+	{
+	  *cp++ = '_';
+	  cp = stpcpy (cp, revision);
 	}
 
-      last = retval;
-    }
-
-  if (retval != NULL || do_allocate == 0)
-    {
-      free (filename);
-      return retval;
+      *cp++ = '/';
+      stpcpy (cp, domain);
+
+      /* Look in list of already loaded domains whether it is already
+	 available.  */
+      last = NULL;
+      for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
+	if (retval->filename != NULL)
+	  {
+	    int compare = strcmp (retval->filename, filename);
+	    if (compare == 0)
+	      /* We found it!  */
+	      break;
+	    if (compare < 0)
+	      {
+		/* It's not in the list.  */
+		retval = NULL;
+		break;
+	      }
+
+	    last = retval;
+	  }
+
+      if (retval != NULL || do_allocate == 0)
+	{
+	  free (filename);
+	  return retval;
+	}
     }
 
   retval = (struct loaded_domain *) malloc (sizeof (*retval));
@@ -453,8 +461,8 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier,
   if (last == NULL)
     {
       retval->next = _nl_loaded_domains;
-     _nl_loaded_domains = retval;
-     }
+      _nl_loaded_domains = retval;
+    }
   else
     {
       retval->next = last->next;
@@ -474,3 +482,22 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier,
 
   return retval;
 }
+
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library.  So we
+   avoid the non-standard function stpcpy.  In GNU C Library this
+   function is available, though.  Also allow the symbol HAVE_STPCPY
+   to be defined.  */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+     char *dest;
+     const char *src;
+{
+  while ((*dest++ = *src++) != '\0')
+    /* Do nothing. */ ;
+  return dest - 1;
+}
+#endif
diff --git a/intl/gettext.c b/intl/gettext.c
index 204d85ecd4..7bed6369b4 100644
--- a/intl/gettext.c
+++ b/intl/gettext.c
@@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #  ifdef HAVE_STRING_H
 #   include <string.h>
 #  else
-#   define NULL 0
+#   define NULL ((void *) 0)
 #  endif
 # endif
 #endif
diff --git a/locale/libintl.h b/intl/libintl.h
index f9a150d3df..f9a150d3df 100644
--- a/locale/libintl.h
+++ b/intl/libintl.h
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index b05c630724..d98f365bf9 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -75,6 +75,13 @@ _nl_load_domain (domain)
   domain->decided = 1;
   domain->data = NULL;
 
+  /* If the record does not represent a valid locale the FILENAME
+     might be NULL.  This can happen when according to the given
+     specification the locale file name is different for XPG and CEN
+     syntax.  */
+  if (domain->filename == NULL)
+    return;
+
   /* Try to open the addressed file.  */
   fd = open (domain->filename, O_RDONLY);
   if (fd == -1)
diff --git a/intl/localealias.c b/intl/localealias.c
index fc3bc1238b..47f2cbffa8 100644
--- a/intl/localealias.c
+++ b/intl/localealias.c
@@ -1,5 +1,5 @@
 /* localealias.c -- handle aliases for locale names
-   Copyright (C) 1995 Software Foundation, Inc.
+   Copyright (C) 1995 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
@@ -125,7 +125,7 @@ _nl_expand_alias (name)
 	{
 	  const char *start;
 
-	  while (locale_alias_path[0] != '\0' && locale_alias_path[0] == ':')
+	  while (locale_alias_path[0] == ':')
 	    ++locale_alias_path;
 	  start = locale_alias_path;
 
@@ -239,7 +239,7 @@ read_alias_file (fname, fname_len)
 	    }
 	}
 
-      /* Possibily not the whole line fits into the buffer.  Ignore
+      /* Possibily not the whole line fitted into the buffer.  Ignore
 	 the rest of the line.  */
       while (strchr (cp, '\n') == NULL)
 	{
@@ -305,8 +305,8 @@ alias_compare (map1, map2)
     {
       /* I know this seems to be odd but the tolower() function in
 	 some systems libc cannot handle nonalpha characters.  */
-      c1 = isalpha (*p1) ? tolower (*p1) : *p1;
-      c2 = isalpha (*p2) ? tolower (*p2) : *p2;
+      c1 = isupper (*p1) ? tolower (*p1) : *p1;
+      c2 = isupper (*p2) ? tolower (*p2) : *p2;
       if (c1 == '\0')
 	break;
     }
diff --git a/libintl.h b/libintl.h
index 38a33d232b..be1062ca03 100644
--- a/libintl.h
+++ b/libintl.h
@@ -1 +1 @@
-#include <locale/libintl.h>
+#include <intl/libintl.h>