 .travis.yml                          |  3 +++
 bindings/python/fiu_ctrl.in.py       |  2 +-
 libfiu/Makefile                      |  5 +++--
 libfiu/fiu-rc.c                      | 22 +++++++++++++++-------
 preload/posix/Makefile               |  2 +-
 preload/posix/generate               | 14 ++++++--------
 preload/posix/utils/extract_from_man | 20 ++++++++++----------
 preload/run/Makefile                 |  3 ++-
 tests/Makefile                       |  4 ++--
 tests/generated/generate-test        | 14 +++++++-------
 tests/perf-fsck.py                   | 18 +++++++++---------
 tests/test-fiu_ctrl.py               |  1 +
 tests/test-manyfps.py                |  6 +++---
 tests/utils/test-basic_ctrl.py       |  9 ++++++---
 tests/utils/wrap                     | 12 ++++++++----
 tests/wrap-python                    |  4 ++--
 16 files changed, 79 insertions(+), 60 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 120cbd2..1259383 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,7 @@
 # Configuration for https://travis-ci.org/
 
+dist: xenial
+
 language: c
 
 compiler:
@@ -9,6 +11,7 @@ compiler:
 addons:
     apt:
         packages:
+            - coreutils
             - python-dev
             - python3-dev
 
diff --git a/bindings/python/fiu_ctrl.in.py b/bindings/python/fiu_ctrl.in.py
index 8228e08..f9b6d8d 100644
--- a/bindings/python/fiu_ctrl.in.py
+++ b/bindings/python/fiu_ctrl.in.py
@@ -109,7 +109,7 @@ class PipeControl (_ControlBase):
     def _open_pipes(self):
         # Open the files, but wait if they are not there, as the child process
         # may not have created them yet.
-        fd_in = _open_with_timeout(self.path_in, "a")
+        fd_in = _open_with_timeout(self.path_in, "w")
         fd_out = _open_with_timeout(self.path_out, "r")
         return fd_in, fd_out
 
diff --git a/libfiu/Makefile b/libfiu/Makefile
index 6c2b90d..8b25679 100644
--- a/libfiu/Makefile
+++ b/libfiu/Makefile
@@ -1,6 +1,7 @@
 
 CFLAGS += -std=c99 -pedantic -Wall
-ALL_CFLAGS = -D_XOPEN_SOURCE=600 -fPIC -DFIU_ENABLE=1 $(CFLAGS)
+ALL_CFLAGS = -D_XOPEN_SOURCE=600 -fPIC -DFIU_ENABLE=1 \
+		$(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
 
 # Optimization CFLAGS, only used when doing a non-debug build.
 OPT_CFLAGS = -O3
@@ -38,7 +39,7 @@ else
 	NICE_CC = $(CC)
 endif
 
-LIB_VER=0.98
+LIB_VER=1.00
 LIB_SO_VER=0
 
 
diff --git a/libfiu/fiu-rc.c b/libfiu/fiu-rc.c
index 913cf6b..3db2cfc 100644
--- a/libfiu/fiu-rc.c
+++ b/libfiu/fiu-rc.c
@@ -6,7 +6,6 @@
 #include <stdio.h>		/* snprintf() */
 #include <string.h>		/* strncpy() */
 #include <stdlib.h>		/* malloc()/free() */
-#include <limits.h>		/* PATH_MAX */
 #include <sys/types.h>		/* getpid(), mkfifo() */
 #include <unistd.h>		/* getpid() */
 #include <sys/stat.h>		/* mkfifo() */
@@ -225,9 +224,9 @@ static int rc_do_command(int fdr, int fdw)
  * removed. If the process forks, a new pipe will be created.
  */
 
-static char npipe_basename[PATH_MAX] = {0};
-static char npipe_path_in[PATH_MAX] = {0};
-static char npipe_path_out[PATH_MAX] = {0};
+static char *npipe_basename = NULL;
+static char *npipe_path_in = NULL;
+static char *npipe_path_out = NULL;
 
 static void *rc_fifo_thread(void *unused)
 {
@@ -289,8 +288,17 @@ static int _fiu_rc_fifo(const char *basename)
 	/* see rc_fifo_thread() */
 	rec_count++;
 
-	snprintf(npipe_path_in, PATH_MAX, "%s-%d.in", basename, getpid());
-	snprintf(npipe_path_out, PATH_MAX, "%s-%d.out", basename, getpid());
+	/* Allocate the pipe paths. Will be composed of
+	 * "<basename>-<pid>.[in|out]", so leave plenty of room for the last
+	 * part, to handle potentially long pids.
+	 * These live through the entire life of the binary and are never
+	 * freed. */
+	int path_len = strlen(basename) + 40;
+	npipe_path_in = malloc(path_len);
+	npipe_path_out = malloc(path_len);
+
+	snprintf(npipe_path_in, path_len, "%s-%d.in", basename, getpid());
+	snprintf(npipe_path_out, path_len, "%s-%d.out", basename, getpid());
 
 	if (mkfifo(npipe_path_in, 0600) != 0 && errno != EEXIST) {
 		rec_count--;
@@ -329,7 +337,7 @@ int fiu_rc_fifo(const char *basename)
 	if (r < 0)
 		return r;
 
-	strncpy(npipe_basename, basename, PATH_MAX - 1);
+	npipe_basename = strdup(basename);
 	pthread_atfork(NULL, NULL, fifo_atfork_child);
 
 	return r;
diff --git a/preload/posix/Makefile b/preload/posix/Makefile
index 6ef224b..5c6162c 100644
--- a/preload/posix/Makefile
+++ b/preload/posix/Makefile
@@ -2,7 +2,7 @@
 CFLAGS += -std=c99 -Wall -O3
 ALL_CFLAGS = -D_XOPEN_SOURCE=600 -fPIC -DFIU_ENABLE=1 \
 		-D_LARGEFILE64_SOURCE=1 -I. -I../../libfiu/ \
-		$(CFLAGS)
+		$(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
 
 ifdef DEBUG
 ALL_CFLAGS += -g
diff --git a/preload/posix/generate b/preload/posix/generate
index 7a6fc03..5e1999a 100755
--- a/preload/posix/generate
+++ b/preload/posix/generate
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 Reads function information and generates code for the preloader library.
@@ -88,8 +88,7 @@ class Function:
 			elif k == 'variants':
 				self.variants = v.split();
 			else:
-				raise SyntaxError, \
-					"Unknown information: " + k
+				raise SyntaxError("Unknown information: " + k)
 
 	def __repr__(self):
 		s = '<F %(rt)s %(n)s ( %(p)s ) -- %(fn)s %(oe)s %(ve)s>' % \
@@ -124,7 +123,7 @@ class Function:
 			if self.on_error is None:
 				desc = "%s uses errno but has no on_error" % \
 					self.name
-				raise RuntimeError, desc
+				raise RuntimeError(desc)
 
 			# We can't put this as a macro parameter, so it has to
 			# be explicit 
@@ -163,7 +162,7 @@ class Function:
 
 	def apply_variant(self, v):
 		if v != 'off64_t':
-			raise SyntaxError, "Unknown function variant: " + v
+			raise SyntaxError("Unknown function variant: " + v)
 
 		f = copy.copy(self)
 
@@ -289,8 +288,7 @@ def parse_module(path):
 				elif k == 'v':
 					directives.append(Verbatim(v))
 				else:
-					raise SyntaxError, \
-						("Unknown directive", l)
+					raise SyntaxError("Unknown directive", l)
 			else:
 				current_func = Function(l, ctx)
 		else:
@@ -342,7 +340,7 @@ def write_function_list(directives, path):
 
 
 def usage():
-	print "Use: ./generate input.mod output.c file_list.fl"
+	print("Use: ./generate input.mod output.c file_list.fl")
 
 def main():
 	if len(sys.argv) < 4:
diff --git a/preload/posix/utils/extract_from_man b/preload/posix/utils/extract_from_man
index 7e3d1bf..bbaef78 100755
--- a/preload/posix/utils/extract_from_man
+++ b/preload/posix/utils/extract_from_man
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # encoding: utf8
 
 """
@@ -67,7 +67,7 @@ def get_ret_on_error(sections):
 
 	# remove spaces and newlines to make it easier detect the patterns
 	s = ' '.join(sections['RETURN VALUE'].split())
-	print s
+	print(s)
 
 	# Note: the '(-|‐)' regexp matches both the normal minus sign ('-')
 	# and the UTF-8 hypen sign ('‐', or \xe2\x80\x90); sadly both usually
@@ -80,7 +80,7 @@ def get_ret_on_error(sections):
 		r'[Oo]ther((-|‐) )?wise, (?P<ev>[-\w]+) shall be returned',
 		r'Other((-|‐) )?wise, the functions shall return (?P<ev>[-\w]+) and'
 	]
-	regexps = map(re.compile, regexps)
+	regexps = list(map(re.compile, regexps))
 
 	possible_errors = []
 	for regexp in regexps:
@@ -141,7 +141,7 @@ def get_defs(sections):
 if __name__ == '__main__':
 
 	if len(sys.argv) > 1:
-		print __doc__
+		print(__doc__)
 		sys.exit(1)
 
 	s = extract_sections(sys.stdin)
@@ -149,16 +149,16 @@ if __name__ == '__main__':
 	errnos = get_possible_errnos(s)
 	incs, funcs = get_defs(s)
 
-	print '\n'.join( 'include: ' + i for i in incs)
-	print
+	print('\n'.join( 'include: ' + i for i in incs))
+	print()
 
-	print '\n'.join(funcs)
+	print('\n'.join(funcs))
 
 	if on_error:
-		print '\ton error:', ' || '.join(on_error)
+		print('\ton error:', ' || '.join(on_error))
 
 	if errnos:
-		print '\tvalid errnos:', wrap(' '.join(sorted(set(errnos))),
-				60, indent = 2)
+		print('\tvalid errnos:', wrap(' '.join(sorted(set(errnos))),
+				60, indent = 2))
 
 
diff --git a/preload/run/Makefile b/preload/run/Makefile
index 448413d..5ad08e4 100644
--- a/preload/run/Makefile
+++ b/preload/run/Makefile
@@ -1,7 +1,8 @@
 
 CFLAGS += -std=c99 -Wall -O3
 ALL_CFLAGS = -D_XOPEN_SOURCE=600 -fPIC -DFIU_ENABLE=1 \
-		-I. -I../../libfiu/ $(CFLAGS)
+		-I. -I../../libfiu/ \
+		$(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
 
 ifdef DEBUG
 ALL_CFLAGS += -g
diff --git a/tests/Makefile b/tests/Makefile
index f0d3c85..7a289ac 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -16,13 +16,13 @@ ifneq ($(V), 1)
 	NICE_RUN = @echo "  RUN $<"; \
 		   LD_LIBRARY_PATH=../libfiu/ \
 		   LD_PRELOAD=./libs/fiu_run_preload.so:./libs/fiu_posix_preload.so
-	NICE_PY = @echo "  PY  $<"; ./wrap-python 2
+	NICE_PY = @echo "  PY  $<"; ./wrap-python 3
 	NICE_LN = @echo "  LN $@"; ln -f
 else
 	NICE_CC = $(CC)
 	NICE_RUN = LD_LIBRARY_PATH=../libfiu/ \
 		   LD_PRELOAD=./libs/fiu_run_preload.so:./libs/fiu_posix_preload.so
-	NICE_PY = ./wrap-python 2
+	NICE_PY = ./wrap-python 3
 	NICE_LN = ln -f
 endif
 
diff --git a/tests/generated/generate-test b/tests/generated/generate-test
index fec4585..7fc0804 100755
--- a/tests/generated/generate-test
+++ b/tests/generated/generate-test
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 Generate C testcases based on the given configuration file.
@@ -8,13 +8,13 @@ testing a wrapper.
 """
 
 import sys
-import ConfigParser
+import configparser
 import argparse
 from string import Template
 
 
 def listify(x):
-	if isinstance(x, (str, unicode)):
+	if isinstance(x, str):
 		return [x]
 	return x
 
@@ -103,7 +103,7 @@ def generate(options, outfile):
 	outfile.write("#include <errno.h>\n")
 
 	includes = options.get("include", [])
-	if isinstance(includes, (str, unicode)):
+	if isinstance(includes, str):
 		includes = includes.split()
 	for i in includes:
 		outfile.write("#include <%s>\n" % i)
@@ -135,7 +135,7 @@ def main():
 	parser = argparse.ArgumentParser(
 			description ="Generate C testcases")
 	parser.add_argument("-c", "--conf", metavar = "C",
-			required = True, type = file,
+			required = True, type = argparse.FileType('rt'),
 			help = "configuration file")
 	parser.add_argument("-o", "--out", metavar = "F",
 			required = True,
@@ -158,8 +158,8 @@ def main():
 		# anything.
 	}
 
-	conf = ConfigParser.SafeConfigParser(conf_defaults)
-	conf.readfp(args.conf)
+	conf = configparser.ConfigParser(conf_defaults)
+	conf.read_file(args.conf)
 
 	section = conf.sections()[0]
 
diff --git a/tests/perf-fsck.py b/tests/perf-fsck.py
index 8d367b9..3e8a536 100644
--- a/tests/perf-fsck.py
+++ b/tests/perf-fsck.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 Performance tests using fsck.ext2 on a test file.
@@ -52,14 +52,14 @@ def run_and_time(name, args):
     end = time.time()
 
     if verbose == 2:
-        print 'Ran %s -> %d' % (args, status)
+        print('Ran %s -> %d' % (args, status))
 
     if status != 0:
-        print 'Error running %s: %s' % (args[0], status)
+        print('Error running %s: %s' % (args[0], status))
         raise RuntimeError
 
-    print '%-10s u:%.3f  s:%.3f  r:%.3f' % (
-            name, rusage.ru_utime, rusage.ru_stime, end - start)
+    print('%-10s u:%.3f  s:%.3f  r:%.3f' % (
+            name, rusage.ru_utime, rusage.ru_stime, end - start))
 
 
 def run_fsck(name, fiu_args):
@@ -72,7 +72,7 @@ def run_fsck(name, fiu_args):
     stdout, stderr = child.communicate()
 
     if child.returncode != 0:
-        print 'Error running fsck: %s' % child.returncode
+        print('Error running fsck: %s' % child.returncode)
         raise RuntimeError
 
     # Find the times reported by fsck.
@@ -95,8 +95,8 @@ def run_fsck(name, fiu_args):
         sys_time = float(times[2])
         break
 
-    print '%-10s u:%.3f  s:%.3f  r:%.3f' % (
-            name, user_time, sys_time, real_time)
+    print('%-10s u:%.3f  s:%.3f  r:%.3f' % (
+            name, user_time, sys_time, real_time))
 
 
 def check_test_file():
@@ -110,7 +110,7 @@ def check_test_file():
             ["mkfs.ext2", "-F", test_file],
             stdout = open('/dev/null', 'w'))
     if retcode != 0:
-        print 'Error running mkfs.ext2:', retcode
+        print('Error running mkfs.ext2:', retcode)
         return
 
 
diff --git a/tests/test-fiu_ctrl.py b/tests/test-fiu_ctrl.py
index 04e2fbc..398d58e 100644
--- a/tests/test-fiu_ctrl.py
+++ b/tests/test-fiu_ctrl.py
@@ -14,6 +14,7 @@ fiu_ctrl.PLIBPATH = "./libs/"
 
 def run_cat(**kwargs):
     return fiu_ctrl.Subprocess(["./small-cat"],
+        universal_newlines = True,
         stdin = subprocess.PIPE, stdout = subprocess.PIPE,
         stderr = subprocess.PIPE, **kwargs)
 
diff --git a/tests/test-manyfps.py b/tests/test-manyfps.py
index 5679993..b2de4e5 100644
--- a/tests/test-manyfps.py
+++ b/tests/test-manyfps.py
@@ -15,11 +15,11 @@ for i in range(N):
 
 # Remove only half and check again; this will stress the shrinking of our data
 # structures.
-for i in range(N / 2):
+for i in range(N // 2):
     fiu.disable(str(i))
 
-for i in range(N / 2, N):
+for i in range(N // 2, N):
     assert fiu.fail(str(i))
 
-for i in range(N / 2, N):
+for i in range(N // 2, N):
     fiu.disable(str(i))
diff --git a/tests/utils/test-basic_ctrl.py b/tests/utils/test-basic_ctrl.py
index 4723d8d..3938548 100755
--- a/tests/utils/test-basic_ctrl.py
+++ b/tests/utils/test-basic_ctrl.py
@@ -1,11 +1,12 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import os
 import subprocess
 import time
 
 def fiu_ctrl(p, args):
-    subprocess.check_call("./wrap fiu-ctrl".split() + args + [str(p.pid)])
+    subprocess.check_call("./wrap fiu-ctrl".split() + args + [str(p.pid)],
+            universal_newlines = True)
 
 def launch_sh():
     # We use cat as a subprocess as it is reasonably ubiquitous, simple and
@@ -15,6 +16,7 @@ def launch_sh():
     # We also set LC_ALL=C as we test the output for the word "error", which
     # does not necessarily appear in other languages.
     p = subprocess.Popen("./wrap fiu-run -x cat".split(),
+            universal_newlines = True,
             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
             stderr=subprocess.PIPE,
             env=dict(os.environ, LC_ALL="C"))
@@ -34,7 +36,8 @@ def send_cmd(p, cmd):
 
 # Launch a subprocess and check that it shows up in fiu-ls.
 p = launch_sh()
-out = subprocess.check_output("./wrap fiu-ls".split())
+out = subprocess.check_output("./wrap fiu-ls".split(),
+        universal_newlines = True)
 assert ("%s: cat" % p.pid) in out, out
 
 # Send it a command and check that it works.
diff --git a/tests/utils/wrap b/tests/utils/wrap
index ad32b9d..7c68979 100755
--- a/tests/utils/wrap
+++ b/tests/utils/wrap
@@ -5,18 +5,22 @@
 #
 # The first argument is the utility to run.
 
+BASE="$(realpath `dirname ${0}`/../..)"
+
+export LD_LIBRARY_PATH="$BASE/libfiu:$LD_LIBRARY_PATH"
+
 case "$1" in
 "fiu-ctrl")
-	BIN=../../utils/fiu-ctrl
+	BIN=$BASE/utils/fiu-ctrl
 	ARGS=
 	;;
 "fiu-ls")
-	BIN=../../utils/fiu-ls
+	BIN=$BASE/utils/fiu-ls
 	ARGS=
 	;;
 "fiu-run")
-	BIN=../../preload/run/fiu-run
-	ARGS="-l ./libs"
+	BIN=$BASE/preload/run/fiu-run
+	ARGS="-l $BASE/tests/utils/libs"
 	;;
 esac
 
diff --git a/tests/wrap-python b/tests/wrap-python
index aab0667..d0c2153 100755
--- a/tests/wrap-python
+++ b/tests/wrap-python
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Python wrapper, which makes it able to import the built (and not the
 # installed) version of libfiu.
@@ -34,7 +34,7 @@ os.environ["LD_LIBRARY_PATH"] = ":".join([lib_path, \
 # Find out the corresponding module path for the desired python version. The
 # path must be absolute
 mod_bins = glob.glob(os.path.dirname(sys.argv[0]) +
-			"/../bindings/python/build/lib*-%s.*/fiu_ll.so" \
+			"/../bindings/python/build/lib*-%s.*/fiu.py" \
 				% py_ver)
 if not mod_bins:
 	sys.stderr.write(("Can't find python%s bindings, run " +
