diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2013-12-18 17:25:02 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2013-12-19 12:35:18 +0100 |
commit | 2d27ccbc105e84c27547a003aec624a3cc3bbd66 (patch) | |
tree | 1bf930bc9c2f2a9269e453ff143f58de67608c45 /trans | |
parent | b372e439e05e336d5e52aa0ce69c799c15691932 (diff) |
trans/fakeroot: shutdown the translator if the last client is gone
Previously, fakeroot would not exit if a process outlived the original
process started by settrans. This caused bugs like this:
% fakeroot-hurd /bin/sh -c 'sleep 1&' 2>&1 | tee
<hangs>
Fix this by exiting if the last client of fakeroot goes away.
If noone has a right to any control or protid port, noone can ever
reacquire any such right. So it is safe to shutdown the fakeroot
translator in that case.
* trans/fakeroot.c (fakeroot_netfs_release_protid): Shutdown the
translator if the last protid object is destroyed and no control port
is around either.
Diffstat (limited to 'trans')
-rw-r--r-- | trans/fakeroot.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/trans/fakeroot.c b/trans/fakeroot.c index 203f2c1b..0e0b618a 100644 --- a/trans/fakeroot.c +++ b/trans/fakeroot.c @@ -1,5 +1,5 @@ /* fakeroot -- a translator for faking actions that aren't really permitted - Copyright (C) 2002, 2003, 2008 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2008, 2013 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 @@ -184,6 +184,24 @@ fakeroot_netfs_release_protid (void *cookie) out: pthread_mutex_unlock (&np->lock); netfs_release_protid (cookie); + + int cports = ports_count_class (netfs_control_class); + int nports = ports_count_class (netfs_protid_class); + ports_enable_class (netfs_control_class); + ports_enable_class (netfs_protid_class); + if (cports == 0 && nports == 0) + { + /* The last client is gone. Our job is done. */ + error_t err = netfs_shutdown (0); + if (! err) + exit (EXIT_SUCCESS); + + /* If netfs_shutdown returns EBUSY, we lost a race against + fsys_goaway. Hence we ignore this error. */ + if (err != EBUSY) + error (1, err, "netfs_shutdown"); + } + pthread_mutex_unlock (&idport_ihash_lock); } |