diff -r d51331eaec15 -r e8262ca32109 thirdparty/vcs-load-dirs/vcs_support/util.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thirdparty/vcs-load-dirs/vcs_support/util.py Tue May 12 15:52:53 2009 +0200 @@ -0,0 +1,172 @@ +# Copyright (C) 2003-2007 John Goerzen +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os, sys, re + +nulldev = None +verbose = 0 + +class ExecProblem(Exception): + pass + +def mainexec(program, args = [], child_stdout = None, + child_stdin = None, child_stderr = None, wait = 1, closefds = []): + """Runs the program as a sub-process, passing to it args if specified. + The sub-process has its file descriptors adjusted as per the arguments. + + If wait is 1, wait until the child exits, then return the result code from + os.waitpid(). + + If wait is 0, return the PID immediately.""" + global verbose + def setfds(source, dest): + if source != None: + if hasattr(source, 'fileno'): + source = source.fileno() + os.dup2(source, dest) + + pid = os.fork() + if not pid: + if verbose: + print "Running: ", program, args + setfds(child_stdin, 0) + setfds(child_stdout, 1) + setfds(child_stderr, 2) + for fd in closefds: + os.close(fd) + os.execvp(program, (program,) + tuple(args)) + sys.exit(255) + else: + if wait: + return os.waitpid(pid, 0)[1] + else: + return pid + +def safeexec(program, args = [], child_stdout = None, + child_stdin = None, child_stderr = None, + expected = 0): + """Calls mainexec() with the appropriate arguments, and raises + an exception if the program died with a signal or returned an + error code other than expected. This function will always wait.""" + result = mainexec(program, args, child_stdout, child_stdin, child_stderr) + return checkresult(result, expected) + +def getstdoutsafeexec(program, args, expected = 0): + pipes = os.pipe() + pid = mainexec(program, args, child_stdout = pipes[1], wait = 0) + os.close(pipes[1]) + fd = os.fdopen(pipes[0], 'r') + retval = fd.readlines() + checkpid(pid, expected) + os.close(pipes[0]) + return retval + +def silentsafeexec(program, args, expected = 0): + """Silently runs the specified program.""" + null = getnull() + result = mainexec(program, args, null, null, null) + return checkresult(result, expected) + +def checkresult(result, expected): + info = [] + if os.WIFSIGNALED(result): + info.append("got signal %d" % os.WTERMSIG(result)) + if os.WIFEXITED(result): + info.append("exited with code %d" % os.WEXITSTATUS(result)) + info = ",".join(info) + if not os.WIFEXITED(result): + raise ExecProblem, info + if os.WEXITSTATUS(result) != expected: + raise ExecProblem, info + " (expected exit code %d)" % expected + return result + +def checkpid(pid, expected): + return checkresult(os.waitpid(pid, 0)[1], expected) + +def getnull(): + global nulldev + if not nulldev: + nulldev = open("/dev/null", "w+") + return nulldev + +def chdircmd(newdir, func, *args, **kwargs): + cwd = os.getcwd() + os.chdir(newdir) + try: + return apply(func, args, kwargs) + finally: + os.chdir(cwd) + +def maketree(path, addpath = None, ignore = [], res = None): + thisdir = os.listdir(path) + retval = [] + others = [] + if res == None: + res = [re.compile(x) for x in ignore] + for item in thisdir: + skip = 0 + for retest in res: + if retest.search(item): + skip = 1 + break + if skip: + continue + dirname = os.path.join(path, item) + if os.path.isdir(dirname) and not os.path.islink(dirname): + if addpath: + retval.append(os.path.join(addpath, item) + '/') + else: + retval.append(item + '/') + if addpath: + newaddpath = os.path.join(addpath, item) + else: + newaddpath = item + others.extend(maketree(dirname, newaddpath, res = res)) + else: + if addpath: + retval.append(os.path.join(addpath, item)) + else: + retval.append(item) + return sorttree(retval + others) + +def sorttree(srctree, filesfirst = False): + retval = [] + dirs = [x for x in srctree if x.endswith('/')] + files = [x for x in srctree if not x.endswith('/')] + dirs.sort() + files.sort() + if filesfirst: + return files + dirs + else: + return dirs + files + + +def copyfrom(srcdir, destdir): + pipes = os.pipe() + verbargs = [] + #if verbose: + # verbargs.append('-v') + readerpid = chdircmd(srcdir, mainexec, "tar", ["-cSpf", "-", "."], + child_stdout = pipes[1], wait = 0, + closefds = [pipes[0]]) + writerpid = chdircmd(destdir, mainexec, "tar", ["-xSpf", "-"] + verbargs, + child_stdin = pipes[0], wait = 0, closefds = [pipes[1]]) + os.close(pipes[0]) + os.close(pipes[1]) + checkpid(readerpid, 0) + checkpid(writerpid, 0) +