+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.
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)
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)"
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
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"
# 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
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
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
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; }
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
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"
# 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)
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;
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);
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. */
/* 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 ());
}
\f
/* Called when we get a message telling us to change our proc server port. */
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,
}));
_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:
__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. */
return;
}
+ handler = ss->actions[signo].sa_handler;
+
if (handler == SIG_DFL)
/* Figure out the default action for this signal. */
switch (signo)
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 ();
}
}
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 ();
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);
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);
}
/* 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. */
return pending = ss->pending & ~ss->blocked;
}
+ check_pending_signals:
+ untraced = 0;
+
if (signals_pending ())
{
pending:
/* 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;
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,
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 (),
# 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
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
{
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)
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
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)
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;
}
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));
if (last == NULL)
{
retval->next = _nl_loaded_domains;
- _nl_loaded_domains = retval;
- }
+ _nl_loaded_domains = retval;
+ }
else
{
retval->next = last->next;
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
# ifdef HAVE_STRING_H
# include <string.h>
# else
-# define NULL 0
+# define NULL ((void *) 0)
# endif
# endif
#endif
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)
/* 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
{
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;
}
}
- /* 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)
{
{
/* 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;
}
-#include <locale/libintl.h>
+#include <intl/libintl.h>