 .gitignore                           |    1 +
 LICENSE                              |   10 +++---
 Makefile                             |   20 +++++++++++---
 libfiu/Makefile                      |   47 +++++++++++++++++++++++++++-----
 libfiu/fiu-rc.c                      |   22 +++++++++------
 libfiu/libfiu.3                      |    2 +-
 libfiu/libfiu.pc.in                  |    4 +-
 preload/Makefile                     |   13 +++++++--
 preload/posix/Makefile               |    5 +++-
 preload/posix/codegen.c              |   19 ++++++++++---
 preload/posix/codegen.h              |   30 +++++++++++++++++---
 preload/posix/generate               |   25 ++++++++++++++---
 preload/posix/modules/libc.str.mod   |   15 ++++++++++
 preload/posix/modules/posix.custom.c |   48 ++++++++++++++++++++++++++++++++-
 preload/posix/modules/posix.io.mod   |    7 +++++
 preload/run/Makefile                 |   16 ++++++++---
 preload/run/fiu-run.1                |    2 +-
 preload/run/fiu-run.in               |    2 +-
 utils/Makefile                       |   14 +++++++---
 utils/fiu-ctrl.1                     |    4 +-
 20 files changed, 245 insertions(+), 61 deletions(-)

diff --git a/.gitignore b/.gitignore
index 1011ae1..7740f5e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ libfiu/*.o
 libfiu/libfiu.a
 libfiu/libfiu.pc
 libfiu/libfiu.so
+libfiu/libfiu.so.*
 libfiu/build-flags
 preload/posix/*.o
 preload/posix/*.so
diff --git a/LICENSE b/LICENSE
index edb80f0..987d3b9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -5,7 +5,7 @@ using. But I also believe that it's important that people share and give back;
 so I'm placing this work under the following license.
 
 
-BOLA - Buena Onda License Agreement (v1.0)
+BOLA - Buena Onda License Agreement (v1.1)
 ------------------------------------------
 
 This work is provided 'as-is', without any express or implied warranty. In no
@@ -19,12 +19,12 @@ However, if you want to be "buena onda", you should:
 
 1. Not take credit for it, and give proper recognition to the authors.
 2. Share your modifications, so everybody benefits from them.
-4. Do something nice for the authors.
-5. Help someone who needs it: sign up for some volunteer work or help your
+3. Do something nice for the authors.
+4. Help someone who needs it: sign up for some volunteer work or help your
    neighbour paint the house.
-6. Don't waste. Anything, but specially energy that comes from natural
+5. Don't waste. Anything, but specially energy that comes from natural
    non-renewable resources. Extra points if you discover or invent something
    to replace them.
-7. Be tolerant. Everything that's good in nature comes from cooperation.
+6. Be tolerant. Everything that's good in nature comes from cooperation.
 
 
diff --git a/Makefile b/Makefile
index 4aa8326..9d418e1 100644
--- a/Makefile
+++ b/Makefile
@@ -4,10 +4,14 @@ default: all
 
 install: all_install
 
+uninstall: all_uninstall
+
 all: libfiu preload utils
 
 all_install: libfiu_install preload_install utils_install
 
+all_uninstall: libfiu_uninstall preload_uninstall utils_uninstall
+
 
 libfiu:
 	$(MAKE) -C libfiu
@@ -18,6 +22,8 @@ libfiu_clean:
 libfiu_install:
 	$(MAKE) -C libfiu install
 
+libfiu_uninstall:
+	$(MAKE) -C libfiu uninstall
 
 
 preload: libfiu
@@ -29,6 +35,9 @@ preload_clean:
 preload_install: preload
 	$(MAKE) -C preload install
 
+preload_uninstall:
+	$(MAKE) -C preload uninstall
+
 
 utils:
 	$(MAKE) -C utils
@@ -39,6 +48,9 @@ utils_clean:
 utils_install: utils
 	$(MAKE) -C utils install
 
+utils_uninstall:
+	$(MAKE) -C utils uninstall
+
 
 bindings: python2 python3
 
@@ -65,11 +77,11 @@ python_clean:
 clean: python_clean preload_clean libfiu_clean utils_clean
 
 
-.PHONY: default all clean install all_install \
-	libfiu libfiu_clean libfiu_install \
+.PHONY: default all clean install all_install uninstall all_uninstall \
+	libfiu libfiu_clean libfiu_install libfiu_uninstall \
 	python2 python2_install python3 python3_install python_clean \
 	bindings bindings_install bindings_clean \
-	preload preload_clean preload_install \
-	utils utils_clean utils_install
+	preload preload_clean preload_install preload_uninstall \
+	utils utils_clean utils_install utils_uninstall
 
 
diff --git a/libfiu/Makefile b/libfiu/Makefile
index e312976..98a0c61 100644
--- a/libfiu/Makefile
+++ b/libfiu/Makefile
@@ -14,6 +14,9 @@ endif
 # prefix for installing the binaries
 PREFIX=/usr/local
 
+# prefix for eventual location of binaries
+DESTDIR=$(PREFIX)
+
 # install utility, we assume it's GNU/BSD compatible
 INSTALL=install
 
@@ -27,6 +30,9 @@ else
 	NICE_CC = $(CC)
 endif
 
+LIB_VER=0.13
+LIB_SO_VER=0
+
 
 default: all
 
@@ -35,13 +41,17 @@ all: libs libfiu.pc
 libfiu.pc: build-flags libfiu.pc.in
 	@echo "generating libfiu.pc"
 	@cat libfiu.pc.in | \
-		sed 's@++PREFIX++@$(PREFIX)@g' \
+		sed 's@++DESTDIR++@$(DESTDIR)@g' | \
+		sed 's@++LIB_VER++@$(LIB_VER)@g' \
 		> libfiu.pc
 
 libs: libfiu.so libfiu.a
 
 libfiu.so: build-flags fiu.h $(OBJS)
-	$(NICE_CC) $(ALL_CFLAGS) -shared -fPIC $(OBJS) -lpthread -o libfiu.so
+	$(NICE_CC) $(ALL_CFLAGS) -shared -fPIC \
+		-Wl,-soname,libfiu.so.$(LIB_SO_VER) \
+		$(OBJS) -lpthread -o libfiu.so.$(LIB_VER)
+	ln -fs libfiu.so.$(LIB_VER) libfiu.so
 
 libfiu.a: build-flags fiu.h $(OBJS)
 	$(AR) cr libfiu.a $(OBJS)
@@ -49,7 +59,9 @@ libfiu.a: build-flags fiu.h $(OBJS)
 
 install-lib: libs libfiu.pc
 	$(INSTALL) -d $(PREFIX)/lib
-	$(INSTALL) -m 0755 libfiu.so $(PREFIX)/lib
+	$(INSTALL) -m 0755 libfiu.so.$(LIB_VER) $(PREFIX)/lib
+	ln -fs libfiu.so.$(LIB_VER) $(PREFIX)/lib/libfiu.so
+	ln -fs libfiu.so.$(LIB_VER) $(PREFIX)/lib/libfiu.so.$(LIB_SO_VER)
 	$(INSTALL) -m 0755 libfiu.a $(PREFIX)/lib
 	$(INSTALL) -d $(PREFIX)/include
 	$(INSTALL) -m 0644 fiu.h $(PREFIX)/include
@@ -62,11 +74,27 @@ install-lib: libs libfiu.pc
 	@echo
 
 install-man:
-	$(INSTALL) -d $(PREFIX)/man/man3
-	$(INSTALL) -m 0644 libfiu.3 $(PREFIX)/man/man3/
+	$(INSTALL) -d $(PREFIX)/share/man/man3
+	$(INSTALL) -m 0644 libfiu.3 $(PREFIX)/share/man/man3/
 
 install: install-lib install-man
 
+uninstall-lib:
+	$(RM) $(PREFIX)/lib/libfiu.so
+	$(RM) $(PREFIX)/lib/libfiu.so.$(LIB_VER)
+	$(RM) $(PREFIX)/lib/libfiu.so.$(LIB_SO_VER)
+	$(RM) $(PREFIX)/lib/libfiu.a
+	$(RM) $(PREFIX)/include/fiu.h
+	$(RM) $(PREFIX)/include/fiu-control.h
+	$(RM) $(PREFIX)/include/fiu-local.h
+	$(RM) $(PREFIX)/lib/pkgconfig/libfiu.pc
+
+uninstall-man:
+	$(RM) $(PREFIX)/share/man/man3/libfiu.3
+
+uninstall: uninstall-lib uninstall-man
+
+
 BF = $(ALL_CFLAGS) ~ $(PREFIX)
 build-flags: .force-build-flags
 	@if [ x"$(BF)" != x"`cat build-flags 2>/dev/null`" ]; then \
@@ -82,10 +110,13 @@ $(OBJS): build-flags
 	$(NICE_CC) $(ALL_CFLAGS) -c $< -o $@
 
 clean:
-	rm -f libfiu.pc $(OBJS) libfiu.so libfiu.a build-flags
-	rm -f *.bb *.bbg *.da *.gcov *.gcda *.gcno gmon.out
+	rm -f libfiu.pc $(OBJS) libfiu.so libfiu.so.$(LIB_VER) libfiu.a
+	rm -f *.bb *.bbg *.da *.gcov *.gcda *.gcno gmon.out build-flags
 
-.PHONY: default all libs install-lib install-man install clean \
+.PHONY: default all libs \
+	install-lib install-man install \
+	uninstall-lib uninstall-man uninstall \
+	clean \
 	.force-build-flags
 
 
diff --git a/libfiu/fiu-rc.c b/libfiu/fiu-rc.c
index 92ef78c..3a9151b 100644
--- a/libfiu/fiu-rc.c
+++ b/libfiu/fiu-rc.c
@@ -137,8 +137,6 @@ static int rc_process_cmd(char *cmd)
 	} else {
 		return -1;
 	}
-
-	return 0;
 }
 
 /* Read remote control directives from fdr and process them, writing the
@@ -180,14 +178,22 @@ static char npipe_path_out[PATH_MAX];
 
 static void *rc_fifo_thread(void *unused)
 {
-	int fdr, fdw, r;
+	int fdr, fdw, r, errcount;
 
 	/* increment the recursion count so we're not affected by libfiu,
 	 * otherwise we could make the remote control useless by enabling all
 	 * failure points */
 	rec_count++;
 
+	errcount = 0;
+
 reopen:
+	if (errcount > 10) {
+		fprintf(stderr, "libfiu: Too many errors in remote control "
+				"thread, shutting down\n");
+		return NULL;
+	}
+
 	fdr = open(npipe_path_in, O_RDONLY);
 	if (fdr < 0)
 		return NULL;
@@ -202,6 +208,7 @@ reopen:
 		r = rc_do_command(fdr, fdw);
 		if (r < 0 && errno != EPIPE) {
 			perror("libfiu: Error reading from remote control");
+			errcount++;
 			close(fdr);
 			close(fdw);
 			goto reopen;
@@ -213,10 +220,7 @@ reopen:
 		}
 	}
 
-	close(fdr);
-	close(fdw);
-
-	return NULL;
+	/* we never get here */
 }
 
 static void fifo_atexit(void)
@@ -235,12 +239,12 @@ static int _fiu_rc_fifo(const char *basename)
 	snprintf(npipe_path_in, PATH_MAX, "%s-%d.in", basename, getpid());
 	snprintf(npipe_path_out, PATH_MAX, "%s-%d.out", basename, getpid());
 
-	if (mkfifo(npipe_path_in, 0600) != 0) {
+	if (mkfifo(npipe_path_in, 0600) != 0 && errno != EEXIST) {
 		rec_count--;
 		return -1;
 	}
 
-	if (mkfifo(npipe_path_out, 0600) != 0) {
+	if (mkfifo(npipe_path_out, 0600) != 0 && errno != EEXIST) {
 		unlink(npipe_path_in);
 		rec_count--;
 		return -1;
diff --git a/libfiu/libfiu.3 b/libfiu/libfiu.3
index 4178027..ab46ae1 100644
--- a/libfiu/libfiu.3
+++ b/libfiu/libfiu.3
@@ -70,7 +70,7 @@ for more details.
 
 
 .TP
-.BI "int fiu_init(" flags ")"
+.BI "fiu_init(" flags ")"
 Initializes the library. Ideally, you should only call this once, although it
 can cope with multiple calls. The flags parameter is currently unused and must
 be set to 0. Returns 0 on success, < 0 on error.
diff --git a/libfiu/libfiu.pc.in b/libfiu/libfiu.pc.in
index 4f1907d..937d57b 100644
--- a/libfiu/libfiu.pc.in
+++ b/libfiu/libfiu.pc.in
@@ -1,12 +1,12 @@
 
-prefix=++PREFIX++
+prefix=++DESTDIR++
 libdir=${prefix}/lib
 includedir=${prefix}/include
 
 Name: libfiu
 Description: Fault injection in userspace
 URL: http://blitiri.com.ar/p/libfiu/
-Version: 0.12
+Version: ++LIB_VER++
 Libs: -L${libdir} -lfiu
 Cflags: -I${includedir}
 
diff --git a/preload/Makefile b/preload/Makefile
index a575d71..9eb3b96 100644
--- a/preload/Makefile
+++ b/preload/Makefile
@@ -5,6 +5,8 @@ all: posix run
 
 install: posix_install run_install
 
+uninstall: posix_uninstall run_uninstall
+
 clean: posix_clean run_clean
 
 
@@ -17,6 +19,9 @@ posix_clean:
 posix_install:
 	$(MAKE) -C posix/ install
 
+posix_uninstall:
+	$(MAKE) -C posix/ uninstall
+
 run:
 	$(MAKE) -C run/
 
@@ -26,9 +31,11 @@ run_clean:
 run_install:
 	$(MAKE) -C run/ install
 
+run_uninstall:
+	$(MAKE) -C run/ uninstall
 
 
-.PHONY: default clean install \
-	posix posix_clean posix_install \
-	run run_clean run_install 
+.PHONY: default clean install uninstall\
+	posix posix_clean posix_install posix_uninstall \
+	run run_clean run_install run_uninstall
 
diff --git a/preload/posix/Makefile b/preload/posix/Makefile
index ce0be4e..40ca573 100644
--- a/preload/posix/Makefile
+++ b/preload/posix/Makefile
@@ -82,11 +82,14 @@ install: fiu_posix_preload.so
 	$(INSTALL) -d $(PREFIX)/lib
 	$(INSTALL) -m 0755 fiu_posix_preload.so $(PREFIX)/lib
 
+uninstall:
+	$(RM) $(PREFIX)/lib/fiu_posix_preload.so
+
 clean:
 	rm -f $(OBJS) $(GEN_OBJS:.o=.c) $(GEN_FL) build-flags
 	rm -f function_list fiu_posix_preload.so
 	rm -f *.bb *.bbg *.da *.gcov *.gcda *.gcno gmon.out
 
-.PHONY: default install clean .force-build-flags
+.PHONY: default install uninstall clean .force-build-flags
 
 
diff --git a/preload/posix/codegen.c b/preload/posix/codegen.c
index 0f078e8..71644c5 100644
--- a/preload/posix/codegen.c
+++ b/preload/posix/codegen.c
@@ -9,7 +9,7 @@
 void *_fiu_libc;
 
 /* Recursion counter, per-thread */
-int __thread _fiu_called;
+int __thread _fiu_called = 0;
 
 /* Let the user know if there is no constructor priorities support, just in
  * case there are bugs when building/running without them */
@@ -17,17 +17,28 @@ int __thread _fiu_called;
 #warning "Building without using constructor priorities"
 #endif
 
-static void constructor_attr(200) _fiu_init(void)
+void constructor_attr(200) _fiu_init(void)
 {
-	_fiu_called = 0;
+	static int initialized = 0;
+
+	/* When built without constructor priorities, we could be called more
+	 * than once during the initialization phase: one because we're marked
+	 * as a constructor, and another when one of the other constructors
+	 * sees that it doesn't have _fiu_libc set. */
+
+	printd("_fiu_init() start (%d)\n", initialized);
+	if (initialized)
+		goto exit;
 
 	_fiu_libc = dlopen("libc.so.6", RTLD_NOW);
 	if (_fiu_libc == NULL) {
 		fprintf(stderr, "Error loading libc: %s\n", dlerror());
 		exit(1);
 	}
+	initialized = 1;
 
-	printd("done\n");
+exit:
+	printd("_fiu_init() done\n");
 }
 
 /* this runs after all function-specific constructors */
diff --git a/preload/posix/codegen.h b/preload/posix/codegen.h
index 04d00ee..6a3444e 100644
--- a/preload/posix/codegen.h
+++ b/preload/posix/codegen.h
@@ -8,6 +8,7 @@
 
 /* Pointer to the dynamically loaded library */
 extern void *_fiu_libc;
+void _fiu_init(void);
 
 /* Recursion counter, per-thread */
 extern int __thread _fiu_called;
@@ -37,14 +38,16 @@ extern int __thread _fiu_called;
 	#define rec_inc()				\
 		do {					\
 			_fiu_called++;			\
-			fprintf(stderr, "I: %d\n", _fiu_called); \
+			fprintf(stderr, "I: %d %s\n", _fiu_called, \
+					__FUNCTION__);	\
 			fflush(stderr);			\
 		} while (0)
 
 	#define rec_dec()				\
 		do {					\
 			_fiu_called--;			\
-			fprintf(stderr, "D: %d\n", _fiu_called); \
+			fprintf(stderr, "D: %d %s\n", _fiu_called, \
+					__FUNCTION__);	\
 			fflush(stderr);			\
 		} while (0)
 
@@ -53,7 +56,7 @@ extern int __thread _fiu_called;
 			if (_fiu_called)		\
 				fprintf(stderr, "\t");	\
 			_fiu_called++;			\
-			fprintf(stderr, "%5.5d ", getpid()); \
+			fprintf(stderr, "%6.6d ", getpid()); \
 			fprintf(stderr, "%s(): ", __FUNCTION__ ); \
 			fprintf(stderr, __VA_ARGS__);	\
 			fflush(stderr);			\
@@ -73,6 +76,10 @@ extern int __thread _fiu_called;
 	static void constructor_attr(201) _fiu_init_##NAME(void) \
 	{							\
 		rec_inc();					\
+								\
+		if (_fiu_libc == NULL)				\
+			_fiu_init();				\
+								\
 		_fiu_orig_##NAME = (RTYPE (*) PARAMST)		\
 				dlsym(_fiu_libc, #NAME);	\
 		rec_dec();					\
@@ -117,13 +124,14 @@ extern int __thread _fiu_called;
 /* Generates the body of the function for functions that affect errno. The
  * return value is hardcoded. Assumes int valid_errnos[] exist was properly
  * defined. */
-#define mkwrap_body_errno(FIU_NAME, FAIL_RET, NVERRNOS) \
+#define mkwrap_body_errno(FIU_NAME, FAIL_RET) \
 								\
 		fstatus = fiu_fail(FIU_NAME);			\
 		if (fstatus != 0) {				\
 			void *finfo = fiu_failinfo();		\
 			if (finfo == NULL) {			\
-				errno = valid_errnos[random() % NVERRNOS]; \
+				errno = valid_errnos[random() % \
+					sizeof(valid_errnos) / sizeof(int)]; \
 			} else {				\
 				errno = (long) finfo;		\
 			}					\
@@ -131,9 +139,21 @@ extern int __thread _fiu_called;
 			goto exit;				\
 		}
 
+/* Generates a body part that will reduce the CNT parameter in a random
+ * amount when the given point of failure is enabled. Can be combined with the
+ * other body generators. */
+#define mkwrap_body_reduce(FIU_NAME, CNT)			\
+								\
+		fstatus = fiu_fail(FIU_NAME);			\
+		if (fstatus != 0) {				\
+			CNT -= random() % CNT;			\
+		}
 
 #define mkwrap_bottom(NAME, PARAMSN)				\
 								\
+		if (_fiu_orig_##NAME == NULL)			\
+			_fiu_init_##NAME();			\
+								\
 		r = (*_fiu_orig_##NAME) PARAMSN;		\
 								\
 	exit:							\
diff --git a/preload/posix/generate b/preload/posix/generate
index b5a3989..e7aac43 100755
--- a/preload/posix/generate
+++ b/preload/posix/generate
@@ -50,6 +50,9 @@ class Function:
 		self.use_errno = False
 		self.valid_errnos = []
 
+		# if the given parameter should be reduced by a random amount
+		self.reduce = None
+
 	def load_from_definition(self, definition):
 		m = func_def_re.match(definition)
 		self.name = m.group("name")
@@ -70,6 +73,8 @@ class Function:
 			elif k == 'valid errnos':
 				self.use_errno = True
 				self.valid_errnos = v.split()
+			elif k == 'reduce':
+				self.reduce = v
 			else:
 				raise SyntaxError, \
 					"Unknown information: " + k
@@ -99,6 +104,10 @@ class Function:
 				(self.ret_type, self.name, self.params,
 					paramsn, paramst) )
 
+		if self.reduce:
+			f.write('mkwrap_body_reduce("%s/reduce", %s)\n' % \
+					(self.fiu_name, self.reduce) )
+
 		if self.use_errno:
 			if self.on_error is None:
 				desc = "%s uses errno but has no on_error" % \
@@ -109,9 +118,8 @@ class Function:
 			# be explicit 
 			self.write_valid_errnos(f)
 
-			f.write('mkwrap_body_errno("%s", %s, %d)\n' % \
-					(self.fiu_name, self.on_error,
-						len(self.valid_errnos)) )
+			f.write('mkwrap_body_errno("%s", %s)\n' % \
+					(self.fiu_name, self.on_error) )
 		elif self.on_error is not None:
 			f.write('mkwrap_body_hardcoded("%s", %s)\n' % \
 					(self.fiu_name, self.on_error) )
@@ -124,13 +132,19 @@ class Function:
 
 	def write_valid_errnos(self, f):
 		"Generates the code for the static list of valid errnos."
-		f.write("\tint valid_errnos[] = {\n")
+		f.write("\tstatic const int valid_errnos[] = {\n")
 		for e in self.valid_errnos:
 			f.write("\t  #ifdef %s\n" % e)
 			f.write("\t\t%s,\n" % e)
 			f.write("\t  #endif\n")
 		f.write("\t};\n");
 
+	def fiu_names(self):
+		n = [self.fiu_name]
+		if self.reduce:
+			n.append(self.fiu_name + '/reduce')
+		return n
+
 
 class Include:
 	"Represents an include directive"
@@ -273,7 +287,8 @@ def write_function_list(directives, path):
 	f = open(path, 'a')
 	for d in directives:
 		if isinstance(d, Function):
-			f.write("%-32s%s\n" % (d.name, d.fiu_name))
+			f.write("%-32s%s\n" % (d.name, \
+				', '.join(d.fiu_names())) )
 
 
 def usage():
diff --git a/preload/posix/modules/libc.str.mod b/preload/posix/modules/libc.str.mod
new file mode 100644
index 0000000..3873d19
--- /dev/null
+++ b/preload/posix/modules/libc.str.mod
@@ -0,0 +1,15 @@
+
+include: <string.h>
+include: <errno.h>
+
+fiu name base: libc/str/
+
+char *strdup(const char *s);
+	on error: NULL
+	valid errnos: ENOMEM
+
+char *strndup(const char *s, size_t n);
+	on error: NULL
+	valid errnos: ENOMEM
+
+
diff --git a/preload/posix/modules/posix.custom.c b/preload/posix/modules/posix.custom.c
index 55329fa..5caff6f 100644
--- a/preload/posix/modules/posix.custom.c
+++ b/preload/posix/modules/posix.custom.c
@@ -21,6 +21,10 @@ static int (*_fiu_orig_open) (const char *pathname, int flags, ...) = NULL;
 static void constructor_attr(201) _fiu_init_open(void)
 {
 	rec_inc();
+
+	if (_fiu_libc == NULL)
+		_fiu_init();
+
 	_fiu_orig_open = (int (*) (const char *, int, ...))
 			 dlsym(_fiu_libc, "open");
 	rec_dec();
@@ -60,8 +64,48 @@ int open(const char *pathname, int flags, ...)
 	/* Use the normal macros to complete the function, now that we have a
 	 * set mode to something */
 
-	int valid_errnos[] = { EACCES, EFAULT, EFBIG, EOVERFLOW, ELOOP, EMFILE, ENAMETOOLONG, ENFILE, ENOENT, ENOMEM, ENOSPC, ENOTDIR, EROFS };
-mkwrap_body_errno("posix/io/oc/open", -1, 13)
+	static const int valid_errnos[] = {
+	  #ifdef EACCESS
+		EACCES,
+	  #endif
+	  #ifdef EFAULT
+		EFAULT,
+	  #endif
+	  #ifdef EFBIG
+		EFBIG,
+	  #endif
+	  #ifdef EOVERFLOW
+		EOVERFLOW,
+	  #endif
+	  #ifdef ELOOP
+		ELOOP,
+	  #endif
+	  #ifdef EMFILE
+		EMFILE,
+	  #endif
+	  #ifdef ENAMETOOLONG
+		ENAMETOOLONG,
+	  #endif
+	  #ifdef ENFILE
+		ENFILE,
+	  #endif
+	  #ifdef ENOENT
+		ENOENT,
+	  #endif
+	  #ifdef ENOMEM
+		ENOMEM,
+	  #endif
+	  #ifdef ENOSPC
+		ENOSPC,
+	  #endif
+	  #ifdef ENOTDIR
+		ENOTDIR,
+	  #endif
+	  #ifdef EROFS
+		EROFS
+	  #endif
+	};
+mkwrap_body_errno("posix/io/oc/open", -1)
 mkwrap_bottom(open, (pathname, flags, mode))
 
 
diff --git a/preload/posix/modules/posix.io.mod b/preload/posix/modules/posix.io.mod
index 62b918a..dd9bb2d 100644
--- a/preload/posix/modules/posix.io.mod
+++ b/preload/posix/modules/posix.io.mod
@@ -36,28 +36,35 @@ fiu name base: posix/io/rw/
 ssize_t read(int fd, void *buf, size_t count);
 	on error: -1
 	valid errnos: EBADFD EFAULT EINTR EINVAL EIO EISDIR EOVERFLOW
+	reduce: count
 
 ssize_t pread(int fd, void *buf, size_t count, off_t offset);
 	on error: -1
 	valid errnos: EBADFD EFAULT EINTR EINVAL EIO EISDIR EOVERFLOW
+	reduce: count
 
 ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
 	on error: -1
 	valid errnos: EBADFD EFAULT EINTR EINVAL EIO EISDIR EOVERFLOW
+	reduce: iovcnt
 
 
 ssize_t write(int fd, const void *buf, size_t count);
 	on error: -1
 	valid errnos: EBADFD EFAULT EFBIG EINTR EINVAL EIO ENOSPC
+	reduce: count
 
 ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
 	on error: -1
 	valid errnos: EBADFD EFAULT EFBIG EINTR EINVAL EIO ENOSPC \
 		EOVERFLOW
+	reduce: count
 
 ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
 	on error: -1
 	valid errnos: EBADFD EFAULT EFBIG EINTR EINVAL EIO ENOSPC
+	reduce: iovcnt
+
 
 int truncate(const char *path, off_t length);
 	on error: -1
diff --git a/preload/run/Makefile b/preload/run/Makefile
index 4328548..bd4fca3 100644
--- a/preload/run/Makefile
+++ b/preload/run/Makefile
@@ -14,6 +14,9 @@ endif
 # prefix for installing the binaries
 PREFIX=/usr/local
 
+# location of preload libraries
+PLIBPATH=$(PREFIX)/lib
+
 # install utility, we assume it's GNU/BSD compatible
 INSTALL=install
 
@@ -55,7 +58,7 @@ fiu_run_preload.so: build-flags $(OBJS)
 		-o fiu_run_preload.so
 
 fiu-run: build-flags fiu-run.in
-	cat fiu-run.in | sed "s+@@PREFIX@@+$(PREFIX)+g" > fiu-run
+	cat fiu-run.in | sed "s+@@PLIBPATH@@+$(PLIBPATH)+g" > fiu-run
 	chmod +x fiu-run
 
 install: fiu_run_preload.so fiu-run
@@ -63,13 +66,18 @@ install: fiu_run_preload.so fiu-run
 	$(INSTALL) -m 0755 fiu_run_preload.so $(PREFIX)/lib
 	$(INSTALL) -d $(PREFIX)/bin
 	$(INSTALL) -m 0755 fiu-run $(PREFIX)/bin
-	$(INSTALL) -d $(PREFIX)/man/man1
-	$(INSTALL) -m 0644 fiu-run.1 $(PREFIX)/man/man1/
+	$(INSTALL) -d $(PREFIX)/share/man/man1
+	$(INSTALL) -m 0644 fiu-run.1 $(PREFIX)/share/man/man1/
+
+uninstall:
+	$(RM) $(PREFIX)/lib/fiu_run_preload.so
+	$(RM) $(PREFIX)/bin/fiu-run
+	$(RM) $(PREFIX)/share/man/man1/fiu-run.1
 
 clean:
 	rm -f $(OBJS) fiu_run_preload.so fiu-run build-flags
 	rm -f *.bb *.bbg *.da *.gcov *.gcda *.gcno gmon.out
 
-.PHONY: default install clean .force-build-flags
+.PHONY: default install uninstall clean .force-build-flags
 
 
diff --git a/preload/run/fiu-run.1 b/preload/run/fiu-run.1
index bcc9788..888cce4 100644
--- a/preload/run/fiu-run.1
+++ b/preload/run/fiu-run.1
@@ -62,7 +62,7 @@ enable failure points in the POSIX and libc functions):
 
 .RS
 .nf
-fiu-run -x -e posix/io/* -p 10 -e libc/mm/malloc -p 5 fortune
+fiu\-run \-x \-e posix/io/* \-p 10 \-e libc/mm/malloc \-p 5 fortune
 .fi
 .RE
 
diff --git a/preload/run/fiu-run.in b/preload/run/fiu-run.in
index 4870097..db33777 100644
--- a/preload/run/fiu-run.in
+++ b/preload/run/fiu-run.in
@@ -8,7 +8,7 @@
 FIFO_PREFIX="${TMPDIR:-/tmp}/fiu-ctrl"
 
 # default library path to look for preloader libraries
-PLIBPATH="@@PREFIX@@/lib"
+PLIBPATH="@@PLIBPATH@@"
 
 # the enable string to pass to the preload library (via the FIU_ENABLE
 # environment variable)
diff --git a/utils/Makefile b/utils/Makefile
index 3943711..6c7891d 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -12,12 +12,18 @@ install:
 	$(INSTALL) -d $(PREFIX)/bin
 	$(INSTALL) -m 0755 fiu-ctrl $(PREFIX)/bin
 	$(INSTALL) -m 0755 fiu-ls $(PREFIX)/bin
-	$(INSTALL) -d $(PREFIX)/man/man1
-	$(INSTALL) -m 0644 fiu-ctrl.1 $(PREFIX)/man/man1/
-	$(INSTALL) -m 0644 fiu-ls.1 $(PREFIX)/man/man1/
+	$(INSTALL) -d $(PREFIX)/share/man/man1
+	$(INSTALL) -m 0644 fiu-ctrl.1 $(PREFIX)/share/man/man1/
+	$(INSTALL) -m 0644 fiu-ls.1 $(PREFIX)/share/man/man1/
+
+uninstall:
+	$(RM) $(PREFIX)/bin/fiu-ctrl
+	$(RM) $(PREFIX)/bin/fiu-ls
+	$(RM) $(PREFIX)/share/man/man1/fiu-ctrl.1
+	$(RM) $(PREFIX)/share/man/man1/fiu-ls.1
 
 clean:
 
-.PHONY: default install clean
+.PHONY: default install uninstall clean
 
 
diff --git a/utils/fiu-ctrl.1 b/utils/fiu-ctrl.1
index ceafd6b..d739f9a 100644
--- a/utils/fiu-ctrl.1
+++ b/utils/fiu-ctrl.1
@@ -49,7 +49,7 @@ failure point \fIlibc/mm/malloc\fR with a 5% of probability to fail:
 
 .RS
 .nf
-fiu-ctrl -e posix/io/read -p 25 -e libc/mm/malloc -p 5 12345
+fiu\-ctrl \-e posix/io/read \-p 25 \-e libc/mm/malloc \-p 5 12345
 .fi
 .RE
 
@@ -58,7 +58,7 @@ failure point \fIposix/io/read\fR:
 
 .RS
 .nf
-fiu-ctrl -d posix/io/read 12345
+fiu\-ctrl \-d posix/io/read 12345
 .fi
 .RE
 

