summaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/atexit.c57
-rw-r--r--stdlib/exit.c23
-rw-r--r--stdlib/exit.h12
-rw-r--r--stdlib/random.c30
-rw-r--r--stdlib/stdlib.h28
5 files changed, 99 insertions, 51 deletions
diff --git a/stdlib/atexit.c b/stdlib/atexit.c
index a2ab453576..675de668cc 100644
--- a/stdlib/atexit.c
+++ b/stdlib/atexit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996 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
@@ -16,16 +16,16 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
-#include <ansidecl.h>
+#include <libc-lock.h>
#include <stdlib.h>
#include "exit.h"
/* Register FUNC to be executed by `exit'. */
int
-DEFUN(atexit, (func), void EXFUN((*func), (NOARGS)))
+atexit (void (*func) (void))
{
- struct exit_function *new = __new_exitfn();
+ struct exit_function *new = __new_exitfn ();
if (new == NULL)
return -1;
@@ -36,30 +36,55 @@ DEFUN(atexit, (func), void EXFUN((*func), (NOARGS)))
}
+/* We change global data, so we need locking. */
+__libc_lock_define_initialized (static, lock)
+
+
static struct exit_function_list fnlist = { NULL, 0, };
struct exit_function_list *__exit_funcs = &fnlist;
struct exit_function *
-DEFUN_VOID(__new_exitfn)
+__new_exitfn (void)
{
- register struct exit_function_list *l;
+ struct exit_function_list *l;
+ size_t i = 0;
+
+ __libc_lock_lock (lock)
for (l = __exit_funcs; l != NULL; l = l->next)
{
- register size_t i;
for (i = 0; i < l->idx; ++i)
if (l->fns[i].flavor == ef_free)
- return &l->fns[i];
- if (l->idx < sizeof(l->fns) / sizeof(l->fns[0]))
- return &l->fns[l->idx++];
+ break;
+ if (i < l->idx)
+ break;
+
+ if (l->idx < sizeof (l->fns) / sizeof (l->fns[0]))
+ {
+ i = l->idx++;
+ break;
+ }
}
- l = (struct exit_function_list *) malloc(sizeof(struct exit_function_list));
if (l == NULL)
- return NULL;
- l->next = __exit_funcs;
- __exit_funcs = l;
+ {
+ l = (struct exit_function_list *)
+ malloc (sizeof (struct exit_function_list));
+ if (l != NULL)
+ {
+ l->next = __exit_funcs;
+ __exit_funcs = l;
+
+ l->idx = 1;
+ i = 0;
+ }
+ }
+
+ /* Mark entry as used, but we don't know the flavor now. */
+ if (l != NULL)
+ l->fns[i].flavor = ef_us;
+
+ __libc_lock_unlock (lock)
- l->idx = 1;
- return &l->fns[0];
+ return l == NULL ? NULL : &l->fns[i];
}
diff --git a/stdlib/exit.c b/stdlib/exit.c
index 4f33a25cc4..ec7ee6a2db 100644
--- a/stdlib/exit.c
+++ b/stdlib/exit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996 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
@@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
-#include <ansidecl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -32,25 +31,26 @@ DEFINE_HOOK (__libc_atexit, (void))
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
void
-DEFUN(exit, (status), int status)
+exit (int status)
{
- register CONST struct exit_function_list *l;
+ const struct exit_function_list *l;
for (l = __exit_funcs; l != NULL; l = l->next)
{
- register size_t i = l->idx;
+ size_t i = l->idx;
while (i-- > 0)
{
- CONST struct exit_function *CONST f = &l->fns[i];
+ const struct exit_function *const f = &l->fns[i];
switch (f->flavor)
{
case ef_free:
+ case ef_us:
break;
case ef_on:
- (*f->func.on.fn)(status, f->func.on.arg);
+ (*f->func.on.fn) (status, f->func.on.arg);
break;
case ef_at:
- (*f->func.at)();
+ (*f->func.at) ();
break;
}
}
@@ -60,11 +60,10 @@ DEFUN(exit, (status), int status)
RUN_HOOK (__libc_atexit, ());
#else
{
- extern void EXFUN(_cleanup, (NOARGS));
- _cleanup();
+ extern void _cleanup (void);
+ _cleanup ();
}
#endif
- _exit(status);
+ _exit (status);
}
-
diff --git a/stdlib/exit.h b/stdlib/exit.h
index 214217853e..83d20b7451 100644
--- a/stdlib/exit.h
+++ b/stdlib/exit.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996 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
@@ -20,14 +20,14 @@ Cambridge, MA 02139, USA. */
struct exit_function
{
- enum { ef_free, ef_on, ef_at } flavor; /* `ef_free' MUST be zero! */
+ enum { ef_free, ef_us, ef_on, ef_at } flavor; /* `ef_free' MUST be zero! */
union
{
- void EXFUN((*at), (NOARGS));
+ void (*at) (void);
struct
{
- void EXFUN((*fn), (int status, PTR arg));
- PTR arg;
+ void (*fn) (int status, void *arg);
+ void *arg;
} on;
} func;
};
@@ -39,6 +39,6 @@ struct exit_function_list
};
extern struct exit_function_list *__exit_funcs;
-extern struct exit_function *EXFUN(__new_exitfn, (NOARGS));
+extern struct exit_function *__new_exitfn (void);
#endif /* exit.h */
diff --git a/stdlib/random.c b/stdlib/random.c
index e2b191b696..461b76f29b 100644
--- a/stdlib/random.c
+++ b/stdlib/random.c
@@ -22,6 +22,7 @@
* Rewritten to use reentrant functions by Ulrich Drepper, 1995.
*/
+#include <libc-lock.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
@@ -162,6 +163,11 @@ static struct random_data unsafe_state =
end_ptr : &randtbl[sizeof (randtbl) / sizeof (randtbl[0])]
};
+/* POSIX.1c requires that there is mutual exclusion for the `rand' and
+ `srand' functions to prevent concurrent calls from modifying common
+ data. */
+__libc_lock_define_initialized (static, lock)
+
/* Initialize the random number generator based on the given seed. If the
type is the trivial no-state-information type, just remember the seed.
Otherwise, initializes state[] based on the given "seed" via a linear
@@ -174,7 +180,9 @@ void
__srandom (x)
unsigned int x;
{
+ __libc_lock_lock (lock)
(void) __srandom_r (x, &unsafe_state);
+ __libc_lock_unlock (lock)
}
weak_alias (__srandom, srandom)
@@ -197,10 +205,16 @@ __initstate (seed, arg_state, n)
void *arg_state;
size_t n;
{
- void *ostate = (void *) &unsafe_state.state[-1];
+ void *ostate;
+
+ __libc_lock_lock (lock)
+
+ ostate = (void *) &unsafe_state.state[-1];
__initstate_r (seed, arg_state, n, &unsafe_state);
+ __libc_lock_unlock (lock)
+
return ostate;
}
@@ -218,10 +232,16 @@ void *
__setstate (arg_state)
void *arg_state;
{
- void *ostate = (void *) &unsafe_state.state[-1];
+ void *ostate;
+
+ __libc_lock_lock (lock)
+
+ ostate = (void *) &unsafe_state.state[-1];
if (__setstate_r (arg_state, &unsafe_state) < 0)
- return NULL;
+ ostate = NULL;
+
+ __libc_lock_unlock (lock)
return ostate;
}
@@ -244,8 +264,12 @@ __random ()
{
int32_t retval;
+ __libc_lock_lock (lock)
+
(void) __random_r (&unsafe_state, &retval);
+ __libc_lock_unlock (lock)
+
return retval;
}
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index cb48aa1f1c..d11b8bf73b 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -1,23 +1,23 @@
/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+ 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 Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
+ 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
+ Library General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/*
- * ANSI Standard: 4.10 GENERAL UTILITIES <stdlib.h>
+ * ISO S Standard: 4.10 GENERAL UTILITIES <stdlib.h>
*/
#ifndef _STDLIB_H