Index: tests/pybin/tools.py
===================================================================
--- tests/pybin/tools.py	(revision ea6226569c27a942134dad8c4fb127053ee0c553)
+++ tests/pybin/tools.py	(revision b611fc3e40f3eb2ffacbcdf9ad131f5bfcdc6752)
@@ -11,9 +11,9 @@
 import subprocess
 import sys
+import tempfile
 import time
 import types
 
 from pybin import settings
-from subprocess import Popen, PIPE, STDOUT
 
 ################################################################################
@@ -27,14 +27,14 @@
 	# if this is a dry_run, only print the commands that would be ran
 	if settings.dry_run :
-		cmd = "cmd: {}".format(' '.join(cmd))
-		if output and output != subprocess.DEVNULL and output != subprocess.PIPE:
+		cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd))
+		if output and not isinstance(output, int):
 			cmd += " > "
 			cmd += output
 
-		if error and error != subprocess.DEVNULL and error != subprocess.PIPE and error != subprocess.STDOUT:
+		if error and not isinstance(error, int):
 			cmd += " 2> "
 			cmd += error
 
-		if input and input != subprocess.DEVNULL and os.path.isfile(input):
+		if input and not isinstance(input, int) and os.path.isfile(input):
 			cmd += " < "
 			cmd += input
@@ -45,15 +45,11 @@
 	with contextlib.ExitStack() as onexit:
 		# add input redirection if needed
-		if input and input != subprocess.DEVNULL:
-			if os.path.isfile(input):
-				input = open(input)
-				onexit.push(input)
-			else:
-				input = None
+		input = openfd(input, 'r', onexit, True)
 
 		# add output redirection if needed
-		if output and output != subprocess.DEVNULL and output != subprocess.PIPE:
-			output = open(output, 'w')
-			onexit.push(output)
+		output = openfd(output, 'w', onexit, False)
+
+		# add error redirection if needed
+		error = openfd(error, 'w', onexit, False)
 
 		# run the desired command
@@ -63,5 +59,5 @@
 				stdin =input,
 				stdout=output,
-				stderr=STDOUT,
+				stderr=error,
 				timeout=settings.timeout.single if timeout else None
 			)
@@ -91,4 +87,18 @@
 def is_exe(fname):
 	return os.path.isfile(fname) and os.access(fname, os.X_OK)
+
+def openfd(file, mode, exitstack, checkfile):
+	if not file:
+		return file
+
+	if isinstance(file, int):
+		return file
+
+	if checkfile and not os.path.isfile(file):
+		return None
+
+	file = open(file, mode)
+	exitstack.push(file)
+	return file
 
 # Remove 1 or more files silently
@@ -159,4 +169,14 @@
     return None
 
+@contextlib.contextmanager
+def tempdir():
+	cwd = os.getcwd()
+	with tempfile.TemporaryDirectory() as temp:
+		os.chdir(temp)
+		try:
+			yield temp
+		finally:
+			os.chdir(cwd)
+
 ################################################################################
 #               file handling
@@ -259,12 +279,12 @@
 
 def core_info(path):
+	if not os.path.isfile(path):
+		return 1, "ERR Executable path is wrong"
+
 	cmd   = os.path.join(settings.SRCDIR, "pybin/print-core.gdb")
 	if not os.path.isfile(cmd):
 		return 1, "ERR Printing format for core dumps not found"
 
-	dname = os.path.dirname(path)
-	core  = os.path.join(dname, "core" )
-	if not os.path.isfile(path):
-		return 1, "ERR Executable path is wrong"
+	core  = os.path.join(os.getcwd(), "core" )
 
 	if not os.path.isfile(core):
