Index: configure.in
===================================================================
--- configure.in	(révision 12872)
+++ configure.in	(copie de travail)
@@ -2415,6 +2415,8 @@
    callgrind/callgrind_annotate
    callgrind/callgrind_control
    callgrind/tests/Makefile
+   exp-failgrind/Makefile
+   exp-failgrind/tests/Makefile
    helgrind/Makefile
    helgrind/tests/Makefile
    massif/Makefile
Index: exp-failgrind/fg_main.c
===================================================================
--- exp-failgrind/fg_main.c	(révision 0)
+++ exp-failgrind/fg_main.c	(révision 0)
@@ -0,0 +1,202 @@
+/*--------------------------------------------------------------------*/
+/*--- Failgrind: malloc and syscall failure generator.   fg_main.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Failgrind, malloc and syscall failure generator,
+   which volontary make fail some functions.
+
+   Copyright (C) 2012 Corentin LABBE
+      corentin.labbe@geomatys.fr
+
+   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.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_tool_basics.h"
+#include "pub_tool_libcbase.h"
+#include "pub_tool_libcprint.h"
+#include "pub_tool_options.h"
+#include "pub_tool_tooliface.h"
+
+#include "failgrind.h"
+
+static Int clo_percent;
+static Int clo_fail_class;
+static Int clo_functions_to_fail;
+
+static Bool fg_handle_client_request( ThreadId tid, UWord* arg, UWord* ret )
+{
+	switch (arg[0]) {
+	case _VG_USERREQ__GET_PERCENT:
+		*ret = clo_percent;
+		break;
+	case _VG_USERREQ__GET_FUNCTIONS_MAY_FAULT:
+		*ret = clo_functions_to_fail;
+		break;
+	default:
+		VG_(message)(Vg_UserMsg,
+				"Warning: unknown FailGrind client request code %llx\n",
+				(ULong)arg[0]);
+		return False;
+	}
+	return True;
+}
+
+static Bool fg_process_cmd_line_option(Char* arg)
+{
+	Char *tmp_str;
+	Int i = 0, len, j = 0;
+
+	if VG_BINT_CLO(arg, "--percent", clo_percent, 1, 100) {}
+	else if VG_BINT_CLO(arg, "--failclass", clo_fail_class, 0, FG_CLASS_LAST * 2 - 1) {}
+	else if VG_STR_CLO(arg, "--failfunc", tmp_str) {
+		len = VG_(strlen)(tmp_str);
+		do {
+			if (tmp_str[i] == ',' || i == len ) {
+				if (VG_(strncmp)(tmp_str + j, "malloc", 5) == 0) {
+					clo_functions_to_fail |= FG_FUNC_malloc;
+				} else if (VG_(strncmp)(tmp_str + j, "open", 4) == 0) {
+					clo_functions_to_fail |= FG_FUNC_open;
+				} else if (VG_(strncmp)(tmp_str + j, "read", 4) == 0) {
+					clo_functions_to_fail |= FG_FUNC_read;
+				} else if (VG_(strncmp)(tmp_str + j, "write", 5) == 0) {
+					clo_functions_to_fail |= FG_FUNC_write;
+				} else if (VG_(strncmp)(tmp_str + j, "fopen", 5) == 0) {
+					clo_functions_to_fail |= FG_FUNC_fopen;
+				} else if (VG_(strncmp)(tmp_str + j, "fread", 5) == 0) {
+					clo_functions_to_fail |= FG_FUNC_fread;
+				} else if (VG_(strncmp)(tmp_str + j, "fwrite", 6) == 0) {
+					clo_functions_to_fail |= FG_FUNC_fwrite;
+				} else if (VG_(strncmp)(tmp_str + j, "socket", 6) == 0) {
+					clo_functions_to_fail |= FG_FUNC_socket;
+				} else if (VG_(strncmp)(tmp_str + j, "connect", 6) == 0) {
+					clo_functions_to_fail |= FG_FUNC_connect;
+				} else if (VG_(strncmp)(tmp_str + j, "bind", 4) == 0) {
+					clo_functions_to_fail |= FG_FUNC_bind;
+				} else if (VG_(strncmp)(tmp_str + j, "listen", 6) == 0) {
+					clo_functions_to_fail |= FG_FUNC_listen;
+				} else if (VG_(strncmp)(tmp_str + j, "accept", 6) == 0) {
+					clo_functions_to_fail |= FG_FUNC_accept;
+				} else if (VG_(strncmp)(tmp_str + j, "send", 4) == 0) {
+					clo_functions_to_fail |= FG_FUNC_send;
+				} else if (VG_(strncmp)(tmp_str + j, "recv", 4) == 0) {
+					clo_functions_to_fail |= FG_FUNC_recv;
+				} else if (VG_(strncmp)(tmp_str + j, "all", 3) == 0) {
+					clo_functions_to_fail = FG_FUNC_LAST * 2 - 1;
+				} else {
+					VG_(printf)("ERROR: Unrecognized function: ");
+					for (; j < i && tmp_str[j] != ','; j++)
+						VG_(printf)("%c", tmp_str[j]);
+					VG_(printf)("\n");
+					return False;
+				}
+				j = i + 1;
+			}
+			i++;
+		} while (i <= len);
+	} else
+		return False;
+	return True;
+}
+
+static void fg_print_usage(void)
+{
+	VG_(printf)(
+"	--percent=<number>	percent of function call to fail\n"
+"	--failfunc=fn1,fn2,..	Comma separated list of functions to fail\n"
+"	--failclass=<number>	Class of function to fail\n"
+"		Malloc %d\n"
+"		IO operations (open, read, write) %d\n"
+"		FIO operations (fopen, fread, fwrite) %d\n"
+"		Network operations (socket connect accept listen bind poll setsockopt getsockopt) %d\n"
+	, FG_CLASS_MALLOC, FG_CLASS_IO, FG_CLASS_FIO, FG_CLASS_NETWORK
+	);
+}
+
+static void fg_print_debug_usage(void)
+{
+	VG_(printf)(
+"    (none)\n"
+	);
+}
+
+static void fg_post_clo_init(void)
+{
+	if ((clo_fail_class & FG_CLASS_MALLOC) > 0)
+		clo_functions_to_fail |= FG_FUNC_malloc;
+	if ((clo_fail_class & FG_CLASS_IO) > 0) {
+		clo_functions_to_fail |= FG_FUNC_open;
+		clo_functions_to_fail |= FG_FUNC_read;
+		clo_functions_to_fail |= FG_FUNC_write;
+	}
+	if ((clo_fail_class & FG_CLASS_FIO) > 0) {
+		clo_functions_to_fail |= FG_FUNC_fopen;
+		clo_functions_to_fail |= FG_FUNC_fread;
+		clo_functions_to_fail |= FG_FUNC_fwrite;
+	}
+	if ((clo_fail_class & FG_CLASS_NETWORK) > 0) {
+		clo_functions_to_fail |= FG_FUNC_socket;
+		clo_functions_to_fail |= FG_FUNC_connect;
+		clo_functions_to_fail |= FG_FUNC_bind;
+		clo_functions_to_fail |= FG_FUNC_listen;
+		clo_functions_to_fail |= FG_FUNC_accept;
+		clo_functions_to_fail |= FG_FUNC_send;
+		clo_functions_to_fail |= FG_FUNC_recv;
+	}
+}
+
+static
+IRSB* fg_instrument ( VgCallbackClosure* closure,
+                      IRSB* bb,
+                      VexGuestLayout* layout,
+                      VexGuestExtents* vge,
+                      IRType gWordTy, IRType hWordTy )
+{
+    return bb;
+}
+
+static void fg_fini(Int exitcode)
+{
+}
+
+static void fg_pre_clo_init(void)
+{
+   VG_(details_name)            ("Failgrind");
+   VG_(details_version)         (NULL);
+   VG_(details_description)     ("malloc and syscall failure generator");
+   VG_(details_copyright_author)(
+      "Copyright (C) 2012, and GNU GPL'd, by LABBE Corentin.");
+   VG_(details_bug_reports_to)  (VG_BUGS_TO);
+
+   VG_(details_avg_translation_sizeB) ( 275 );
+
+   VG_(basic_tool_funcs)        (fg_post_clo_init,
+                                 fg_instrument,
+                                 fg_fini);
+   VG_(needs_client_requests)     (fg_handle_client_request);
+   VG_(needs_command_line_options)(fg_process_cmd_line_option,
+				fg_print_usage,
+				fg_print_debug_usage);
+	clo_functions_to_fail = 0;
+}
+
+VG_DETERMINE_INTERFACE_VERSION(fg_pre_clo_init)
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
Index: exp-failgrind/tests/Makefile.am
===================================================================
Index: exp-failgrind/failgrind.h
===================================================================
--- exp-failgrind/failgrind.h	(révision 0)
+++ exp-failgrind/failgrind.h	(révision 0)
@@ -0,0 +1,44 @@
+#ifndef __FAILGRIND_H
+#define __FAILGRIND_H
+
+#include "valgrind.h"
+
+#define FG_CLASS_MALLOC (1u << 0)
+#define FG_CLASS_IO (1u << 1)
+#define FG_CLASS_FIO (1u << 2)
+#define FG_CLASS_NETWORK (1u << 3)
+/*#define FG_CLASS_NETWORK_CLIENT 8
+#define FG_CLASS_NETWORK_SERVER 16
+#define FG_CLASS_NETWORK_ALL 24*/
+#define FG_CLASS_LAST (1u << 3)
+
+#define FG_FUNC_malloc (1u << 0)
+
+#define FG_FUNC_open (1u << 1)
+#define FG_FUNC_read (1u << 2)
+#define FG_FUNC_write (1u << 3)
+
+#define FG_FUNC_fopen (1u << 4)
+#define FG_FUNC_fread (1u << 5)
+#define FG_FUNC_fwrite (1u << 6)
+
+#define FG_FUNC_socket (1u << 7)
+#define FG_FUNC_connect (1u << 8)
+#define FG_FUNC_bind (1u << 9)
+#define FG_FUNC_listen (1u << 10)
+#define FG_FUNC_accept (1u << 11)
+#define FG_FUNC_send (1u << 12)
+#define FG_FUNC_recv (1u << 13)
+
+#define FG_FUNC_LAST (1u << 13)
+
+typedef
+	enum {
+	_VG_USERREQ__GET_PERCENT = VG_USERREQ_TOOL_BASE('F','G') + 256,
+	_VG_USERREQ__GET_FUNCTIONS_MAY_FAULT
+} Vg_FailGrindClientRequest;
+
+#define VALGRIND_GET_PERCENT (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, _VG_USERREQ__GET_PERCENT, 0, 0, 0, 0, 0);
+#define VALGRIND_GET_FUNCTIONS_MAY_FAULT (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, _VG_USERREQ__GET_FUNCTIONS_MAY_FAULT, 0, 0, 0, 0, 0);
+
+#endif
Index: exp-failgrind/Makefile.am
===================================================================
--- exp-failgrind/Makefile.am	(révision 0)
+++ exp-failgrind/Makefile.am	(révision 0)
@@ -0,0 +1,83 @@
+include $(top_srcdir)/Makefile.tool.am
+
+noinst_HEADERS = failgrind.h
+
+noinst_PROGRAMS= exp-failgrind-@VGCONF_ARCH_PRI@-@VGCONF_OS@
+if VGCONF_HAVE_PLATFORM_SEC
+noinst_PROGRAMS += exp-failgrind-@VGCONF_ARCH_SEC@-@VGCONF_OS@
+endif
+
+
+exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_SOURCES = fg_main.c failgrind.h
+exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CPPFLAGS     = \
+	$(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
+exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS       = \
+	$(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
+exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_DEPENDENCIES = \
+	$(TOOL_DEPENDENCIES_@VGCONF_PLATFORM_PRI_CAPS@)
+exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDADD        = \
+        $(TOOL_LDADD_@VGCONF_PLATFORM_PRI_CAPS@)
+exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS      = \
+	$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
+exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
+	$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
+	@VALT_LOAD_ADDRESS_PRI@ \
+	$(LINK) \
+	$(exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
+	$(exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
+
+if VGCONF_HAVE_PLATFORM_SEC
+exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_SOURCES      = fg_main.c failgrind.h
+exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CPPFLAGS     = \
+	$(AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
+exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS       = \
+	$(AM_CFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) -O2
+exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_DEPENDENCIES = \
+	$(TOOL_DEPENDENCIES_@VGCONF_PLATFORM_SEC_CAPS@)
+exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDADD        = \
+	$(TOOL_LDADD_@VGCONF_PLATFORM_SEC_CAPS@)
+exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS      = \
+	$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
+exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
+	$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
+	@VALT_LOAD_ADDRESS_SEC@ \
+	$(LINK) \
+	$(exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
+	$(exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
+endif
+
+#----------------------------------------------------------------------------
+# vgpreload_exp-failgrind-<platform>.so
+#----------------------------------------------------------------------------
+
+noinst_PROGRAMS += vgpreload_exp-failgrind-@VGCONF_ARCH_PRI@-@VGCONF_OS@.so
+if VGCONF_HAVE_PLATFORM_SEC
+noinst_PROGRAMS += vgpreload_exp-failgrind-@VGCONF_ARCH_SEC@-@VGCONF_OS@.so
+endif
+
+if VGCONF_OS_IS_DARWIN
+noinst_DSYMS = $(noinst_PROGRAMS)
+endif
+
+VGPRELOAD_FAILGRIND_SOURCES_COMMON = fg_intercepts.c failgrind.h
+
+vgpreload_exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_so_SOURCES      = \
+	$(VGPRELOAD_FAILGRIND_SOURCES_COMMON)
+vgpreload_exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_so_CPPFLAGS     = \
+	$(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
+vgpreload_exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_so_CFLAGS       = \
+	$(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) $(AM_CFLAGS_PIC)
+vgpreload_exp_failgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
+
+if VGCONF_HAVE_PLATFORM_SEC
+vgpreload_exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_so_SOURCES      = \
+	$(VGPRELOAD_FAILGRIND_SOURCES_COMMON)
+vgpreload_exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_so_CPPFLAGS     = \
+	$(AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
+vgpreload_exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_so_CFLAGS       = \
+	$(AM_CFLAGS_@VGCONF_PLATFORM_SEC_CAPS@) $(AM_CFLAGS_PIC)
+vgpreload_exp_failgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
+endif
+
Index: exp-failgrind/fg_intercepts.c
===================================================================
--- exp-failgrind/fg_intercepts.c	(révision 0)
+++ exp-failgrind/fg_intercepts.c	(révision 0)
@@ -0,0 +1,421 @@
+/*--------------------------------------------------------------------*/
+/*-- Failgrind: malloc and syscall failure generator. fg_interceps.c -*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Failgrind, malloc and syscall failure generator,
+   which volontary make fail some functions.
+
+   Copyright (C) 2012 Corentin LABBE
+      corentin.labbe@geomatys.fr
+
+   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.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_tool_basics.h"
+#include "pub_tool_tooliface.h"
+#include "pub_tool_libcassert.h"
+#include "pub_tool_libcprint.h"
+#include "pub_tool_debuginfo.h"
+#include "pub_tool_libcbase.h"
+#include "pub_tool_options.h"
+#include "pub_tool_machine.h"
+#include "pub_tool_redir.h"
+
+#include "failgrind.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* for bind */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* for fopen */
+#include <stdio.h>
+
+#include <time.h>
+
+static int init_done;
+static int fault_percent;
+static int functions_to_fail;
+
+void * I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,malloc) ( size_t size );
+
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,open) ( const char *pathname, int flags, mode_t mode );
+ssize_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,read) ( int fd, void *buf, size_t count );
+ssize_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,write) ( int fd, void *buf, size_t count );
+
+FILE * I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,fopen) ( const char *pathname, const char *mode );
+size_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,fread) ( void *ptr, size_t size, size_t nmemb, FILE *stream );
+size_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,fwrite) ( const void *ptr, size_t size, size_t nmemb, FILE *stream );
+
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,socket) ( int domain, int type, int protocol );
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,connect) ( int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen );
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,bind) ( int sockfd, const struct sockaddr *my_addr, socklen_t addrlen );
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,listen) ( int sockfd, int backlog );
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,accept) ( int sock, struct sockaddr *addr, socklen_t addrlen );
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,recv) ( int s, void *buf, int len, unsigned int flags );
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,send) ( int s, void *buf, int len, unsigned int flags );
+
+static const int error_list_for_malloc[] = {ENOMEM};
+
+static const int error_list_for_open[] = {EACCES, EEXIST, EFAULT, EISDIR, ELOOP, EMFILE, ENAMETOOLONG, ENFILE, ENODEV, ENOENT, ENOMEM, ENOSPC, ENOTDIR, ENXIO, EOVERFLOW, EPERM, EROFS, ETXTBSY, EWOULDBLOCK};
+static const int error_list_for_read[] = {EAGAIN, EBADF, EFAULT, EINTR, EINVAL, EIO, EISDIR};
+static const int error_list_for_write[] = {EAGAIN, EBADF, EFAULT, EFBIG, EINTR, EINVAL, EIO, ENOSPC, EPIPE};
+
+static const int error_list_for_fopen[] = {EACCES, EEXIST, EFAULT, EISDIR, ELOOP, EMFILE, ENAMETOOLONG, ENFILE, ENODEV, ENOENT, ENOMEM, ENOSPC, ENOTDIR, ENXIO, EOVERFLOW, EPERM, EROFS, ETXTBSY, EWOULDBLOCK};
+/* manpage of fread/fwrite does not list possible errors values, so copy read/write values for the moment */
+static const int error_list_for_fread[] = {EAGAIN, EBADF, EFAULT, EINTR, EINVAL, EIO, EISDIR};
+static const int error_list_for_fwrite[] = {EAGAIN, EBADF, EFAULT, EFBIG, EINTR, EINVAL, EIO, ENOSPC, EPIPE};
+
+static const int error_list_for_socket[] = {EACCES, EAFNOSUPPORT, EINVAL, EMFILE, ENFILE, ENOBUFS, ENOMEM, EPROTONOSUPPORT};
+static const int error_list_for_connect[] = {EACCES, EPERM, EADDRINUSE, EAFNOSUPPORT, EAGAIN, EALREADY, EBADF, ECONNREFUSED, EFAULT, EINPROGRESS, EINTR, EISCONN, ENETUNREACH, ENOTSOCK, ETIMEDOUT};
+
+static const int error_list_for_bind[] = {EACCES, EADDRINUSE, EBADF, EINVAL, ENOTSOCK, EADDRNOTAVAIL, EFAULT, ELOOP, ENAMETOOLONG, ENOENT, ENOMEM, ENOTDIR, EROFS};
+static const int error_list_for_listen[] = {EADDRINUSE, EBADF, ENOTSOCK, EOPNOTSUPP};
+static const int error_list_for_accept[] = {EAGAIN, EWOULDBLOCK, EBADF, ECONNABORTED, EINTR, EINVAL, EMFILE, ENFILE, ENOTSOCK, EOPNOTSUPP, EFAULT, ENOBUFS, ENOMEM, EPROTO, EPERM, ENOSR, ESOCKTNOSUPPORT, EPROTONOSUPPORT, ETIMEDOUT};
+static const int error_list_for_recv[] = {EAGAIN, EBADF, ECONNREFUSED, EDESTADDRREQ, EFAULT, EINTR, EINVAL, ENOMEM, ENOTCONN, ENOTSOCK, };
+static const int error_list_for_send[] = {EAGAIN, EWOULDBLOCK, EBADF, ECONNRESET, EDESTADDRREQ, EFAULT, EINTR, EINVAL, EISCONN, EMSGSIZE, ENOBUFS, ENOMEM, ENOTCONN, ENOTSOCK, EOPNOTSUPP, EPIPE};
+
+/* TODO fopen fread fwrite
+	daemon
+	socket connect accept listen bind poll setsockopt getsockopt send recv
+	fgets fputs
+	getaddrinfo getnameinfo
+	execve
+	ioctl fcntl
+*/
+
+#define MUST_FAIL 0
+#define NO_FAIL 1
+/*============================================================================*/
+/*============================================================================*/
+/* Do all init (get values gived by user) and determine if we fail a function or not */
+static int do_fail(int fnid) {
+	if (init_done == 0) {
+		fault_percent = VALGRIND_GET_PERCENT;
+		functions_to_fail = VALGRIND_GET_FUNCTIONS_MAY_FAULT;
+		srand(time(NULL));
+		init_done = 1;
+	}
+	
+	if ((functions_to_fail & fnid) == 0)
+		return NO_FAIL;
+
+	if (rand()%100 >= fault_percent)
+		return NO_FAIL;
+	return MUST_FAIL;
+}
+
+#define FAILGRIND_GET_ERROR(_fg_fnname) _fg_fnname[rand() % (sizeof(_fg_fnname)/sizeof(_fg_fnname[0])) ]
+
+/*============================================================================*/
+/*============================================================================*/
+void * I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,malloc) ( size_t size )
+{
+	OrigFn fn;
+	void * r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+/*	VALGRIND_PRINTF("wrapper-pre malloc %d\n", size);*/
+
+	if (do_fail(FG_FUNC_malloc) == NO_FAIL) {
+		CALL_FN_W_W(r, fn, size);
+	} else {
+		VALGRIND_PRINTF("Do a fault for malloc\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_malloc);
+		return NULL;
+	}
+/*	VALGRIND_PRINTF("wrapper-post malloc %p\n", r);*/
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,open) ( const char *pathname, int flags, mode_t mode )
+{
+	OrigFn fn;
+	int r = 0;
+
+	VALGRIND_GET_ORIG_FN(fn);
+	if (pathname != NULL)
+		VALGRIND_PRINTF("wrapper-pre open %s\n", pathname);
+	else
+		VALGRIND_PRINTF("wrapper-pre open\n");
+
+	if (do_fail(FG_FUNC_open) == NO_FAIL) {
+		CALL_FN_W_WWW(r, fn, pathname, flags, mode);
+	} else {
+		VALGRIND_PRINTF("Do a fault for open\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_open);
+		return -1;
+	}
+/*	VALGRIND_PRINTF("wrapper-post open %d\n", r);*/
+	return r;
+}
+/*============================================================================*/
+/*============================================================================*/
+ssize_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,read) ( int fd, void *buf, size_t count )
+{
+	OrigFn fn;
+	ssize_t r = 0;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre read\n");
+
+	if (do_fail(FG_FUNC_read) == NO_FAIL) {
+		CALL_FN_W_WWW(r, fn, fd, buf, count);
+	} else {
+		VALGRIND_PRINTF("Do a fault for read\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_read);
+		return -1;
+	}
+	VALGRIND_PRINTF("wrapper-post read\n");
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+/* TODO faulting a write to fd stdin or stdout is useless,
+	but we cannot whitelist theses fd because the program could close it.
+	Perhaps tracking all close call to theses fd could help*/
+ssize_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,write) ( int fd, void *buf, size_t count )
+{
+	OrigFn fn;
+	ssize_t r = 0;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre write fd %d\n", fd);
+
+	if (do_fail(FG_FUNC_write) == NO_FAIL || fd < 3) {
+		CALL_FN_W_WWW(r, fn, fd, buf, count);
+	} else {
+		VALGRIND_PRINTF("Do a fault for write\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_write);
+		return -1;
+	}
+	VALGRIND_PRINTF("wrapper-post write\n");
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+FILE * I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,fopen) ( const char *pathname, const char *mode )
+{
+	OrigFn fn;
+	FILE *r = NULL;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	if (pathname != NULL)
+		VALGRIND_PRINTF("wrapper-pre fopen %s\n", pathname);
+	else
+		VALGRIND_PRINTF("wrapper-pre fopen\n");
+
+	if (do_fail(FG_FUNC_fopen) == NO_FAIL) {
+		CALL_FN_W_WW(r, fn, pathname, mode);
+	} else {
+		VALGRIND_PRINTF("Do a fault for fopen\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_fopen);
+		return NULL;
+	}
+	VALGRIND_PRINTF("wrapper-post fopen\n");
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+size_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,fread) ( void *ptr, size_t size, size_t nmemb, FILE *stream )
+{
+	OrigFn fn;
+	size_t r = 0;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+
+	if (do_fail(FG_FUNC_fread) == NO_FAIL) {
+		CALL_FN_W_WWWW(r, fn, ptr, size, nmemb, stream);
+	} else {
+		VALGRIND_PRINTF("Do a fault for fread\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_fread);
+		return 0;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+size_t I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,fwrite) ( const void *ptr, size_t size, size_t nmemb, FILE *stream )
+{
+	OrigFn fn;
+	size_t r = 0;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+
+	if (do_fail(FG_FUNC_fwrite) == NO_FAIL) {
+		CALL_FN_W_WWWW(r, fn, ptr, size, nmemb, stream);
+	} else {
+		VALGRIND_PRINTF("Do a fault for fwrite\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_fwrite);
+		return 0;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,socket) ( int domain, int type, int protocol )
+{
+	OrigFn fn;
+	int r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre socket\n");
+
+	if (do_fail(FG_FUNC_socket) == NO_FAIL) {
+		CALL_FN_W_WWW(r, fn, domain, type, protocol);
+	} else {
+		VALGRIND_PRINTF("Do a fault for socket\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_socket);
+		return -1;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,connect) ( int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen )
+{
+	OrigFn fn;
+	int r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre connect\n");
+
+	if (do_fail(FG_FUNC_connect) == NO_FAIL) {
+		CALL_FN_W_WWW(r, fn, sockfd, serv_addr, addrlen);
+	} else {
+		VALGRIND_PRINTF("Do a fault for connect\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_connect);
+		return -1;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,bind) ( int sockfd, const struct sockaddr *my_addr, socklen_t addrlen )
+{
+	OrigFn fn;
+	int r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre bind\n");
+
+	if (do_fail(FG_FUNC_bind) == NO_FAIL) {
+		CALL_FN_W_WWW(r, fn, sockfd, my_addr, addrlen);
+	} else {
+		VALGRIND_PRINTF("Do a fault for bind\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_bind);
+		return -1;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,listen) ( int sockfd, int backlog )
+{
+	OrigFn fn;
+	int r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre listen\n");
+
+	if (do_fail(FG_FUNC_listen) == NO_FAIL) {
+		CALL_FN_W_WW(r, fn, sockfd, backlog);
+	} else {
+		VALGRIND_PRINTF("Do a fault for listen\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_listen);
+		return -1;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,accept) ( int sock, struct sockaddr *addr, socklen_t addrlen )
+{
+	OrigFn fn;
+	int r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre accept\n");
+
+	if (do_fail(FG_FUNC_accept) == NO_FAIL) {
+		CALL_FN_W_WWW(r, fn, sock, addr, addrlen);
+	} else {
+		VALGRIND_PRINTF("Do a fault for accept\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_accept);
+		return -1;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,recv) ( int s, void *buf, int len, unsigned int flags )
+{
+	OrigFn fn;
+	int r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre recv\n");
+
+	if (do_fail(FG_FUNC_recv) == NO_FAIL) {
+		CALL_FN_W_WWWW(r, fn, s, buf, len, flags);
+	} else {
+		VALGRIND_PRINTF("Do a fault for recv\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_recv);
+		return -1;
+	}
+	return r;
+}
+
+/*============================================================================*/
+/*============================================================================*/
+int I_WRAP_SONAME_FNNAME_ZU(VG_Z_LIBC_SONAME,send) ( int s, void *buf, int len, unsigned int flags )
+{
+	OrigFn fn;
+	int r;
+	
+	VALGRIND_GET_ORIG_FN(fn);
+	VALGRIND_PRINTF("wrapper-pre send\n");
+
+	if (do_fail(FG_FUNC_send) == NO_FAIL) {
+		CALL_FN_W_WWWW(r, fn, s, buf, len, flags);
+	} else {
+		VALGRIND_PRINTF("Do a fault for send\n");
+		errno = FAILGRIND_GET_ERROR(error_list_for_send);
+		return -1;
+	}
+	return r;
+}
+
Index: Makefile.am
===================================================================
--- Makefile.am	(révision 12872)
+++ Makefile.am	(copie de travail)
@@ -10,6 +10,7 @@
 		lackey \
 		none \
 		helgrind \
+		exp-failgrind \
 		drd
 
 EXP_TOOLS = 	exp-sgcheck \
