From 42e9ac4b3e8f34b054e45bfb61c3d6e4153be8b1 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 7 Jun 2007 12:02:59 +0000 Subject: When using a pty for logging, use setsid() to create a new session and make the pty into the controlling terminal of the new session. This makes interactive ebuild behave properly in interactive cases like check_license() where ${PAGER:-less} is invoked. svn path=/main/trunk/; revision=6747 --- pym/portage/process.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'pym/portage/process.py') diff --git a/pym/portage/process.py b/pym/portage/process.py index dfc106e6b..0cb175375 100644 --- a/pym/portage/process.py +++ b/pym/portage/process.py @@ -111,9 +111,19 @@ def cleanup(): atexit_register(cleanup) +# Make sure the original terminal attributes are reverted at exit. +if sys.stdin.isatty(): + import termios + _stdin_termios = termios.tcgetattr(sys.stdin.fileno()) + def _reset_stdin_termios(stdin_termios): + import termios + termios.tcsetattr(sys.stdin.fileno(), termios.TCSAFLUSH, stdin_termios) + atexit_register(_reset_stdin_termios, _stdin_termios) + del termios, _stdin_termios, _reset_stdin_termios + def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, uid=None, gid=None, groups=None, umask=None, logfile=None, - path_lookup=True): + path_lookup=True, pre_exec=None): """ Spawns a given command. @@ -140,6 +150,8 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, @type logfile: String @param path_lookup: If the binary is not fully specified then look for it in PATH @type path_lookup: Boolean + @param pre_exec: A function to be called with no arguments just prior to the exec call. + @type pre_exec: callable logfile requires stdout and stderr to be assigned to this process (ie not pointed somewhere else.) @@ -194,7 +206,7 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, if not pid: try: _exec(binary, mycommand, opt_name, fd_pipes, - env, gid, groups, uid, umask) + env, gid, groups, uid, umask, pre_exec) except Exception, e: # We need to catch _any_ exception so that it doesn't # propogate out of this function and cause exiting @@ -251,7 +263,8 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, # Everything succeeded return 0 -def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask): +def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, + pre_exec): """ Execute a given binary with options @@ -274,6 +287,8 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask): @type uid: Integer @param umask: an int representing a unix umask (see man chmod for umask details) @type umask: Integer + @param pre_exec: A function to be called with no arguments just prior to the exec call. + @type pre_exec: callable @rtype: None @returns: Never returns (calls os.execve) """ @@ -315,6 +330,8 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask): os.setuid(uid) if umask: os.umask(umask) + if pre_exec: + pre_exec() # And switch to the new process. os.execve(binary, myargs, env) -- cgit v1.2.3-1-g7c22