Index: ChangeLog =================================================================== RCS file: /cvs/gnome/sabayon/ChangeLog,v retrieving revision 1.176 retrieving revision 1.181 diff -u -p -r1.176 -r1.181 --- ChangeLog 26 Apr 2005 08:30:40 -0000 1.176 +++ ChangeLog 9 May 2005 15:13:04 -0000 1.181 @@ -0,0 +1,51 @@ +2005-05-09 Mark McLoughlin + + * lib/util.py: import errno module + +2005-05-09 Mark McLoughlin + + * lib/util.py: + (uninterruptible_spawnv): actually call + uninterruptible_spawnve() rather than os.spawnv + +2005-05-09 Mark McLoughlin + + * lib/usermod.py: don't import errno. + + * lib/util.py: + (uninterruptible_spawnve): if env is None, call + os.spawnv() since os.spawnve() seems to dislike + when env is None. + +2005-05-09 Mark McLoughlin + + * lib/usermod.py: move _uninterruptible_spawn() to .. + + * lib/util.py: + (uninterruptible_spawnv), + (uninterruptible_spawnve): ... here + + * admin-tool/profilesdialog.py, + lib/protosession.py: use uninterruptible variant + of os.spawnv() here too. + +2005-05-09 Mark McLoughlin + + Fix hang when exiting the prototype session on Ubuntu. + + Problem turned out to be that os.spawn() doesn't handle + EINTR from waitpid() on Linux: + http://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=686667 + + Thanks to Sebastien Bacher for help + in tracking the problem down. + + * lib/usermod.py: + (_uninterruptible_spawn): ignore EINTR from os.spawn() + (set_shell), (set_homedir): use _uninterruptible_spawn() + + * lib/protosession.py: + (ProtoSession.__session_child_watch_handler): emit the + "finished" signal before anything else so that we + still quit the mainloop even if we get an exception. + Index: admin-tool/profilesdialog.py =================================================================== RCS file: /cvs/gnome/sabayon/admin-tool/profilesdialog.py,v retrieving revision 1.20 retrieving revision 1.21 diff -u -p -r1.20 -r1.21 --- admin-tool/profilesdialog.py 3 Mar 2005 13:44:23 -0000 1.20 +++ admin-tool/profilesdialog.py 9 May 2005 12:49:34 -0000 1.21 @@ -240,7 +240,7 @@ class ProfilesDialog: argv = SESSION_TOOL_ARGV + [ PROTOTYPE_USER, user_path ] dprint ("Running session: %s" % argv) - os.spawnv (os.P_WAIT, argv[0], argv) + util.uninterruptible_spawnv (os.P_WAIT, argv[0], argv) self.dialog.set_sensitive (True) Index: lib/protosession.py =================================================================== RCS file: /cvs/gnome/sabayon/lib/protosession.py,v retrieving revision 1.22 retrieving revision 1.24 diff -u -p -r1.22 -r1.24 --- lib/protosession.py 16 Mar 2005 14:44:39 -0000 1.22 +++ lib/protosession.py 9 May 2005 12:49:35 -0000 1.24 @@ -190,13 +190,13 @@ class ProtoSession (gobject.GObject): self.xnest_pid = 0 self.xnest_child_watch = 0 + self.emit ("finished"); + self.force_quit () # If we're waiting for USR1, quit main loop if self.main_loop: self.main_loop.quit () - - self.emit ("finished"); return False @@ -435,7 +435,7 @@ class ProtoSession (gobject.GObject): # Apply the profile argv = APPLY_TOOL_ARGV + [ self.profile_file ] dprint ("Running apply tool: %s" % argv) - os.spawnve (os.P_WAIT, argv[0], argv, new_environ) + util.uninterruptible_spawnve (os.P_WAIT, argv[0], argv, new_environ) # Disable sabayon-xinitrc.sh new_environ["DISABLE_SABAYON_XINITRC"] = "yes" @@ -514,7 +514,7 @@ class ProtoSession (gobject.GObject): # FIXME: my, what a big hammer you have! argv = CLOBBER_USER_PROCESSES_ARGV + [ self.user_pw.pw_name ] dprint ("Clobbering existing processes running as user '%s': %s" % (self.user_pw.pw_name, argv)) - os.spawnv (os.P_WAIT, argv[0], argv) + util.uninterruptible_spawnv (os.P_WAIT, argv[0], argv) # Get an X server going self.__start_xnest () Index: lib/usermod.py =================================================================== RCS file: /cvs/gnome/sabayon/lib/usermod.py,v retrieving revision 1.3 retrieving revision 1.6 diff -u -p -r1.3 -r1.6 --- lib/usermod.py 16 Feb 2005 15:22:15 -0000 1.3 +++ lib/usermod.py 9 May 2005 13:52:40 -0000 1.6 @@ -31,7 +31,7 @@ def dprint (fmt, *args): def set_shell (username, shell): argv = USERMOD_ARGV + [ "-s", shell, username ] dprint ("Executing %s" % argv) - os.spawnv (os.P_WAIT, argv[0], argv) + util.uninterruptible_spawnv (os.P_WAIT, argv[0], argv) # # FIXME: @@ -42,7 +42,7 @@ def set_shell (username, shell): def set_homedir (username, homedir): argv = USERMOD_ARGV + [ "-d", homedir, username ] dprint ("Executing %s" % argv) - os.spawnv (os.P_WAIT, argv[0], argv) + util.uninterruptible_spawnv (os.P_WAIT, argv[0], argv) def create_temporary_homedir (uid, gid): temp_homedir = tempfile.mkdtemp (prefix = "sabayon-temp-home-") Index: lib/util.py =================================================================== RCS file: /cvs/gnome/sabayon/lib/util.py,v retrieving revision 1.14 retrieving revision 1.18 diff -u -p -r1.14 -r1.18 --- lib/util.py 1 Apr 2005 01:39:34 -0000 1.14 +++ lib/util.py 9 May 2005 15:13:04 -0000 1.18 @@ -24,6 +24,7 @@ import sys import pwd import gettext import locale +import errno from config import * ( @@ -140,6 +141,25 @@ def init_gettext (): """ locale.setlocale (locale.LC_ALL, "") gettext.install (PACKAGE, os.path.join (DATADIR, "locale")) + +# +# os.spawn() doesn't handle EINTR from waitpid() on Linux: +# http://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=686667 +# Best we can do is ignore the exception and carry on +# See bug #303034 +# +def uninterruptible_spawnve (mode, file, args, env): + try: + if env is None: + os.spawnv (mode, file, args) + else: + os.spawnve (mode, file, args, env) + except os.error, (err, str): + if err != errno.EINTR: + raise + +def uninterruptible_spawnv (mode, file, args): + uninterruptible_spawnve (mode, file, args, None) def run_unit_tests (): home_dir = get_home_dir ()