aboutsummaryrefslogtreecommitdiffstats
path: root/MgaRepo/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'MgaRepo/util.py')
-rw-r--r--MgaRepo/util.py141
1 files changed, 63 insertions, 78 deletions
diff --git a/MgaRepo/util.py b/MgaRepo/util.py
index dfae85c..538eae8 100644
--- a/MgaRepo/util.py
+++ b/MgaRepo/util.py
@@ -1,6 +1,7 @@
+#!/usr/bin/python3
+
from MgaRepo import Error, config
-import shlex
import subprocess
import getpass
import sys
@@ -10,89 +11,73 @@ import select
from io import StringIO
import httplib2
-class CommandError(Error):
- def __init__(self, cmdline, status, output):
- self.cmdline = cmdline
- self.status = status
- self.output = output
-
- def __str__(self):
- return "command failed: %s\n%s\n" % (self.cmdline, self.output)
+# Our own version of commands' commands_exec(). We have a commands
+# module directory, so we can't import Python's standard module
+
+# Our own version of commands' getstatusoutput(). We have a commands
+# module directory, so we can't import Python's standard module
+def commands_getstatusoutput(cmd):
+ """Return (status, output) of executing cmd in a shell."""
+ pipe = subprocess.Popen('{ ' + cmd + '; } 2>&1', stdin = subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines = True, shell = True)
+ of = pipe.stdout.fileno()
+ text = ''
+ pipe.stdin.close()
+ while True:
+ text += os.read(of,8192).decode('utf8')
+ status = pipe.poll()
+ if status is not None or text == '':
+ break
+ if text[-1:] == '\n': text = text[:-1]
+ return status, text
def execcmd(*cmd, **kwargs):
- assert (kwargs.get("collecterr") and kwargs.get("show")) or not kwargs.get("collecterr"), \
- ("execcmd is implemented to handle collecterr=True only if show=True")
- # split command args
- if isinstance(cmd[0], str):
- if len(cmd) is 1:
- cmdargs = shlex.split(cmd[0])
- else:
- cmdargs = cmd[:]
+ cmdstr = " ".join(cmd)
+ verbose = config.getbool("global", "verbose", 0)
+ if kwargs.get('info') :
+ prefix='LANGUAGE=C LC_TIME=C '
else:
- cmdargs = cmd[0][:]
-
- stdout = None
- stderr = None
- env = {}
- env.update(os.environ)
- if kwargs.get("info") or not kwargs.get("show") or (kwargs.get("show") and kwargs.get("collecterr")):
- if kwargs.get("info"):
- env.update({"LANGUAGE": "C", "LC_TIME": "C"})
+ prefix='LANG=C LANGUAGE=C LC_ALL=C '
+ if verbose:
+ print(prefix + cmdstr)
+ if kwargs.get("show"):
+ if kwargs.get("geterr"):
+ err = StringIO()
+ pstdin = kwargs.get("stdin") if kwargs.get("stdin") else None
+ p = subprocess.Popen(prefix + cmdstr, shell=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ stdin=pstdin)
+ of = p.stdout.fileno()
+ ef = p.stderr.fileno()
+ while True:
+ r,w,x = select.select((of,ef), (), ())
+ odata = None
+ if of in r:
+ odata = (os.read(of, 8192)).decode('utf8')
+ sys.stdout.write(odata)
+ edata = None
+ if ef in r:
+ edata = (os.read(ef, 8192)).decode('utf8')
+ err.write(edata)
+ sys.stderr.write(edata)
+
+ status = p.poll()
+ if status is not None and odata == '' and edata == '':
+ break
+ output = err.getvalue()
else:
- env.update({"LANG": "C", "LANGUAGE": "C", "LC_ALL": "C"})
- stdout = subprocess.PIPE
- if kwargs.get("collecterr"):
- stderr = subprocess.PIPE
+ status = os.system(cmdstr)
+ output = ""
+ else:
+ status, output = commands_getstatusoutput(prefix + cmdstr)
+ if status != 0 and not kwargs.get("noerror"):
+ if kwargs.get("cleanerr") and not verbose:
+ raise Error(output)
else:
- stderr = subprocess.STDOUT
-
- verbose = config.getbool("global", "verbose", 0)
+ raise Error("command failed: %s\n%s\n" % (cmdstr, output))
if verbose:
- print("cmd: " + str(cmd).lstrip("(").rstrip(")").replace("', '", "' '"))
-
- proc = subprocess.Popen(cmdargs, shell=False, stdout=stdout, stdin=kwargs.get("stdin"),
- stderr=stderr, env=env)
-
- output = ""
-
- if kwargs.get("show") and kwargs.get("collecterr"):
- error = StringIO()
- wl = []
- outfd = proc.stdout.fileno()
- errfd = proc.stderr.fileno()
- rl = [outfd, errfd]
- xl = wl
- while proc.poll() is None:
- mrl, _, _ = select.select(rl, wl, xl, 0.5)
- for fd in mrl:
- data = os.read(fd, 8192).decode('utf8')
- if fd == errfd:
- error.write(data)
- sys.stderr.write(data)
- else:
- sys.stdout.write(data)
- output = error.getvalue()
- else:
- # Make sure to avoid buffer getting full.
- # Otherwise if ie. using proc.wait() both python
- # and the process will just hang
- while proc.poll() is None:
- if proc.stdout is not None:
- output += proc.stdout.read(8192).decode('utf8')
- # Make sure that we've emptied the buffer entirely
- if proc.stdout is not None:
- output += proc.stdout.read().decode('utf8')
-
- if kwargs.get("strip", True):
- output = output.rstrip()
-
- if (not kwargs.get("noerror")) and proc.returncode != 0:
- if kwargs.get("cleanerr"):
- msg = output
- cmdline = subprocess.list2cmdline(cmdargs)
- raise CommandError(cmdline, proc.returncode, output)
-
- return proc.returncode, output
+ print(output)
+ sys.stdout.write(output)
+ return status, output
def get_output_exec(cmdstr):
output = StringIO()