diff options
author | Roland McGrath <roland@gnu.org> | 2002-09-20 03:31:58 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2002-09-20 03:31:58 +0000 |
commit | 4ac9bb2e4a9c8be4c0f27ef7ede2bc7a9e219083 (patch) | |
tree | 9623636c75d05aa97c55066aa37ba1f64860baf6 /sysdeps/mach | |
parent | 3c9117108e4bb02d66b454eee6ac6853efee78d5 (diff) | |
download | glibc-4ac9bb2e4a9c8be4c0f27ef7ede2bc7a9e219083.tar.gz |
* sysdeps/mach/hurd/fork.c (__fork): Do not free the signal
thread's sigstate data structure if it has been allocated.
Diffstat (limited to 'sysdeps/mach')
-rw-r--r-- | sysdeps/mach/hurd/fork.c | 32 |
1 files changed, 24 insertions, 8 deletions
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; |