diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sysdeps/mach/hurd/fork.c | 32 |
2 files changed, 29 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index 5d65725244..dd1dd7781a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2002-09-19 Neal H. Walfield <neal@cs.uml.edu> + + * sysdeps/mach/hurd/fork.c (__fork): Do not free the signal + thread's sigstate data structure if it has been allocated. + 2002-09-19 Roland McGrath <roland@redhat.com> * include/libc-symbols.h [HAVE_ASM_SET_DIRECTIVE] diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c index c5dee0cdad..b64a83d766 100644 --- a/sysdeps/mach/hurd/fork.c +++ b/sysdeps/mach/hurd/fork.c @@ -609,14 +609,17 @@ __fork (void) for (i = 0; i < _hurd_nports; ++i) __spin_unlock (&_hurd_ports[i].lock); - /* We are the only thread in this new task, so we will - take the task-global signals. */ + /* We are one of the (exactly) two threads in this new task, we + will take the task-global signals. */ _hurd_sigthread = ss->thread; - /* Unchain the sigstate structures for threads that existed in the - parent task but don't exist in this task (the child process). - Delay freeing them until later because some of the further setup - and unlocking might be required for free to work. */ + /* Claim our sigstate structure and unchain the rest: the + threads existed in the parent task but don't exist in this + task (the child process). Delay freeing them until later + because some of the further setup and unlocking might be + required for free to work. Before we finish cleaning up, + we will reclaim the signal thread's sigstate structure (if + it had one). */ oldstates = _hurd_sigstates; if (oldstates == ss) oldstates = ss->next; @@ -650,13 +653,26 @@ __fork (void) if (!err) err = __thread_resume (_hurd_msgport_thread); - /* Free the old sigstate structures. */ + /* Reclaim the signal thread's sigstate structure and free the + other old sigstate structures. */ while (oldstates != NULL) { struct hurd_sigstate *next = oldstates->next; - free (oldstates); + + if (oldstates->thread == _hurd_msgport_thread) + { + /* If we have a second signal state structure then we + must have been through here before--not good. */ + assert (_hurd_sigstates->next == 0); + _hurd_sigstates->next = oldstates; + oldstates->next = 0; + } + else + free (oldstates); + oldstates = next; } + /* XXX what to do if we have any errors here? */ pid = 0; |