--- old/efence-2.0.1/Makefile	Tue Jul  8 15:11:47 1997
+++ efence-2.1/Makefile	Wed Jul  9 10:57:19 1997
@@ -6,10 +6,15 @@
 CFLAGS= -g
 LIB_INSTALL_DIR= /usr/local/lib
 MAN_INSTALL_DIR= /usr/local/man/man3
+TARGETS= libefence.a
 
 PACKAGE_SOURCE= README libefence.3 Makefile efence.h \
 	efence.c page.c print.c eftest.c tstheap.c
 
+# Un-comment the following if you want to create a dynamic library
+# CFLAGS= -g -fPIC
+# TARGETS= libefence.a libefence.so
+
 # Un-comment the following if you are running HP/UX.
 # CFLAGS= -Aa -g -D_HPUX_SOURCE -DPAGE_PROTECTION_VIOLATED_SIGNAL=SIGBUS
 
@@ -27,7 +32,7 @@
 
 OBJECTS= efence.o page.o print.o
 
-all:	libefence.a tstheap eftest
+all:	$(TARGETS) tstheap eftest
 	@ echo
 	@ echo "Testing Electric Fence."
 	@ echo "After the last test, it should print that the test has PASSED."
@@ -37,15 +42,15 @@
 	@ echo "Electric Fence confidence test PASSED." 
 	@ echo
 
-install: libefence.a libefence.3
-	$(MV) libefence.a $(LIB_INSTALL_DIR)
-	$(CHMOD) 644 $(LIB_INSTALL_DIR)/libefence.a
+install: $(TARGETS) libefence.3
+	$(CP) $(TARGETS) $(LIB_INSTALL_DIR)
+	cd $(LIB_INSTALL_DIR); $(CHMOD) a+rX $(TARGETS)
 	$(CP) libefence.3 $(MAN_INSTALL_DIR)
-	$(CHMOD) 644 $(MAN_INSTALL_DIR)/libefence.3
+	$(CHMOD) a+r $(MAN_INSTALL_DIR)/libefence.3
 
 clean:
-	- rm -f $(OBJECTS) tstheap.o eftest.o tstheap eftest libefence.a \
-	 libefence.cat ElectricFence.shar
+	- rm -f $(OBJECTS) tstheap.o eftest.o tstheap eftest $(TARGETS) \
+	libefence.cat ElectricFence.shar
 
 roff:
 	nroff -man < libefence.3 > libefence.cat
@@ -59,6 +64,10 @@
 libefence.a: $(OBJECTS)
 	- rm -f libefence.a
 	$(AR) crv libefence.a $(OBJECTS)
+
+libefence.so: $(OBJECTS)
+	- rm -f $@
+	ld -shared $(OBJECTS) -o $@
 
 tstheap: libefence.a tstheap.o
 	- rm -f tstheap
--- old/efence-2.0.1/README	Tue Jul  8 15:11:46 1997
+++ efence-2.1/README	Wed Jul  9 10:02:15 1997
@@ -1,3 +1,27 @@
+This is Electric Fence 2.1
+
+I made some changes to the Electric Fence 2.0.1 by Bruce Perens to
+make it useful for me, and called this version by number 2.1.  I hope
+you agree with the changes:
+
+ - realloc was changed to accept null pointer as a parameter.  Some
+   systems seem to allow this.
+
+ - Messages may be redirected to another file descriptor or to a file
+   with EF_LOG_FILE environment variable.
+
+ - Building a dynamic library is added to Makefile.
+
+The author of these changes may be contacted at:
+
+Email: Jaakko.Hyvatti@iki.fi
+URL:   http://www.iki.fi/hyvatti/
+Phone: +358 40 5011222
+
+Please send any suggestions, bug reports and success stories concerning
+these changes to the Email address above.
+
+-----
 This is Electric Fence 2.0.1
 
 Electric Fence is a different kind of malloc() debugger. It uses the virtual
--- old/efence-2.0.1/efence.c	Tue Jul  8 15:11:47 1997
+++ efence-2.1/efence.c	Wed Jul  9 11:06:46 1997
@@ -34,8 +34,14 @@
 #include <unistd.h>
 #include <memory.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if defined(linux)
+#include <malloc.h> /* memalign */
+#endif
 
-static const char	version[] = "\n  Electric Fence 2.0.1"
+static const char	version[] = "\n  Electric Fence 2.1"
  " Copyright (C) 1987-1993 Bruce Perens.\n";
 
 /*
@@ -71,6 +77,16 @@
 typedef struct _Slot	Slot;
 
 /*
+ * EF_LOG_FD is a global variable that is used to control the error
+ * message outputs.  It is the file descriptor number to print the
+ * messages to.  If the value is -1, it will be set to 2 (stderr,
+ * standard error output at run time, or it is set to a descriptor
+ * opened for file named by the environment variable EF_LOG_FILE,
+ * if that variable exists.
+ */
+int		EF_LOG_FD = -1;
+
+/*
  * EF_ALIGNMENT is a global variable used to control the default alignment
  * of buffers returned by malloc(), calloc(), and realloc(). It is all-caps
  * so that its name matches the name of the environment variable that is used
@@ -183,6 +199,22 @@
 	char *	string;
 	Slot *	slot;
 
+	if ( EF_LOG_FD == -1 ) {
+		if ( (string = getenv("EF_LOG_FD")) != 0 )
+			EF_LOG_FD = atoi(string);
+		else if ( (string = getenv("EF_LOG_FILE")) != 0 ) {
+			EF_LOG_FD = open (string,
+					  O_CREAT|O_NOCTTY|O_APPEND|O_WRONLY,
+					  0644);
+			if ( EF_LOG_FD < 0 ) {
+				EF_LOG_FD = 2;
+				EF_Exit ("open(%s) failed: %s",
+					 string, __EF_stringErrorReport());
+			}
+		} else
+			EF_LOG_FD = 2;
+	}
+
 	EF_Print(version);
 
 	/*
@@ -699,30 +731,29 @@
 extern C_LINKAGE void *
 realloc(void * oldBuffer, size_t newSize)
 {
-	size_t	size;
+	size_t	size = 0;
 	Slot *	slot;
 	void *	newBuffer = malloc(newSize);
 
-	if ( allocationList == 0 )
-		EF_Abort("realloc() called before first malloc().");
-
-	Page_AllowAccess(allocationList, allocationListSize);
-	noAllocationListProtection = 1;
+	if (oldBuffer) {
+		Page_AllowAccess(allocationList, allocationListSize);
+		noAllocationListProtection = 1;
 	
-	slot = slotForUserAddress(oldBuffer);
+		slot = slotForUserAddress(oldBuffer);
 
-	if ( slot == 0 )
-		EF_Abort("free(%x): not from malloc().", oldBuffer);
+		if ( slot == 0 )
+			EF_Abort("free(%x): not from malloc().", oldBuffer);
 
-	if ( newSize < (size = slot->userSize) )
-		size = newSize;
+		if ( newSize < (size = slot->userSize) )
+			size = newSize;
 
-	if ( size > 0 )
-		memcpy(newBuffer, oldBuffer, size);
+		if ( size > 0 )
+			memcpy(newBuffer, oldBuffer, size);
 
-	free(oldBuffer);
-	noAllocationListProtection = 0;
-	Page_DenyAccess(allocationList, allocationListSize);
+		free(oldBuffer);
+		noAllocationListProtection = 0;
+		Page_DenyAccess(allocationList, allocationListSize);
+	}
 
 	if ( size < newSize )
 		memset(&(((char *)newBuffer)[size]), 0, newSize - size);
--- old/efence-2.0.1/efence.h	Tue Jul  8 15:11:47 1997
+++ efence-2.1/efence.h	Wed Jul  9 10:59:11 1997
@@ -19,3 +19,6 @@
 void			EF_Abort(const char * message, ...);
 void			EF_Exit(const char * message, ...);
 void			EF_Print(const char * message, ...);
+
+extern int		EF_LOG_FD;
+extern const char *	__EF_stringErrorReport(void);
--- old/efence-2.0.1/libefence.3	Tue Jul  8 15:11:47 1997
+++ efence-2.1/libefence.3	Wed Jul  9 11:07:36 1997
@@ -61,6 +61,18 @@
 extern int EF_PROTECT_FREE;
 .ft
 .fi
+.LP
+.nf
+.ft B
+extern int EF_ALLOW_MALLOC_0;
+.ft
+.fi
+.LP
+.nf
+.ft B
+extern int EF_LOG_FD;
+.ft
+.fi
 .SH DESCRIPTION
 .I Electric Fence
 helps you detect two common programming bugs:
@@ -116,6 +128,14 @@
 On Sun systems running SunOS 4.X, you'll probably have to use
 .B -Bstatic.
 .LP
+On modern systems with dynamic linking capabilities, you may not need
+to staticly link the library to the executable.  For example, on a
+Linux system, you may define an environment variable
+.B LD_PRELOAD=libefence.so
+and the application will link with the dynamic efence library on
+startup.  This way you do not need separate production and debug
+versions of the program.
+.LP
 Run your program
 .I using a debugger. 
 It's easier to work this way than to create a
@@ -195,6 +215,18 @@
 To change this value, set EF_ALLOC_MALLOC_0 in the shell environment to an
 integer value, or assign to the global integer variable EF_ALLOC_MALLOC_0 using
 a debugger.
+.TP
+EF_LOG_FD
+By default, Electric Fence reports its findings to file descriptor 2,
+the standard error output.  To change this value, set EF_LOG_FD or
+EF_LOG_FILE (see below) in the shell environment, or assign to the global
+integer variable EF_LOG_FD using a debugger.
+.TP
+EF_LOG_FILE
+To redirect the efence output to a file, set the shell environment
+variable EF_LOG_FILE to the file name all output from efence should
+go.  Then efence will open the file for appending and assign the file
+descriptor to EF_LOG_FD (see above).
 .SH WORD-ALIGNMENT AND OVERRUN DETECTION
 There is a conflict between the alignment restrictions that malloc() operates
 under and the debugging strategy used by Electric Fence. When detecting
--- old/efence-2.0.1/print.c	Tue Jul  8 15:11:47 1997
+++ efence-2.1/print.c	Wed Jul  9 07:46:06 1997
@@ -43,7 +43,7 @@
 	size = &buffer[NUMBER_BUFFER_SIZE] - s;
 
 	if ( size > 0 )
-		write(2, s, size);
+		write(EF_LOG_FD, s, size);
 }
 
 static void
@@ -59,7 +59,7 @@
 			c = *s++;
 			switch ( c ) {
 			case '%':
-				(void) write(2, &c, 1);
+				(void) write(EF_LOG_FD, &c, 1);
 				break;
 			case 's':
 				{
@@ -69,7 +69,7 @@
 					string = va_arg(args, char *);
 					length = strlen(string);
 
-					(void) write(2, string, length);
+					(void) write(EF_LOG_FD, string, length);
 				}
 				break;
 			case 'd':
@@ -78,7 +78,7 @@
 
 					if ( n < 0 ) {
 						char	c = '-';
-						write(2, &c, 1);
+						write(EF_LOG_FD, &c, 1);
 						n = -n;
 					}
 					printNumber(n, 10);
@@ -91,7 +91,7 @@
 				{
 					char	c = va_arg(args, char);
 					
-					(void) write(2, &c, 1);
+					(void) write(EF_LOG_FD, &c, 1);
 				}
 				break;
 			default:
@@ -102,7 +102,7 @@
 			}
 		}
 		else
-			(void) write(2, &c, 1);
+			(void) write(EF_LOG_FD, &c, 1);
 	}
 }
 
--- old/efence-2.0.1/page.c	Tue Jul  8 15:12:34 1997
+++ efence-2.1/page.c	Wed Jul  9 11:22:56 1997
@@ -15,17 +15,17 @@
 
 static caddr_t	startAddr = (caddr_t) 0;
 
-#if ( !defined(sgi) && !defined(_AIX) )
+#if ( !defined(sgi) && !defined(_AIX) && !defined(linux))
 extern int	sys_nerr;
 extern char *	sys_errlist[];
 #endif
 
-static const char *
-stringErrorReport(void)
+const char *
+__EF_stringErrorReport(void)
 {
 #if ( defined(sgi) )
 	return strerror(oserror());
-#elif ( defined(_AIX) )
+#elif ( defined(_AIX) || defined(linux) )
 	return strerror(errno);
 #else
 	if ( errno > 0 && errno < sys_nerr )
@@ -67,7 +67,7 @@
 #endif
 
 	if ( allocation == (caddr_t)-1 )
-		EF_Exit("mmap() failed: %s", stringErrorReport());
+		EF_Exit("mmap() failed: %s", __EF_stringErrorReport());
 
 	return (void *)allocation;
 }
@@ -83,7 +83,7 @@
 		if ( devZeroFd < 0 )
 			EF_Exit(
 			 "open() on /dev/zero failed: %s"
-			,stringErrorReport());
+			,__EF_stringErrorReport());
 	}
 
 	/*
@@ -107,7 +107,7 @@
 	startAddr = allocation + size;
 
 	if ( allocation == (caddr_t)-1 )
-		EF_Exit("mmap() failed: %s", stringErrorReport());
+		EF_Exit("mmap() failed: %s", __EF_stringErrorReport());
 
 	return (void *)allocation;
 }
@@ -116,7 +116,7 @@
 static void
 mprotectFailed(void)
 {
-	EF_Exit("mprotect() failed: %s", stringErrorReport());
+	EF_Exit("mprotect() failed: %s", __EF_stringErrorReport());
 }
 
 void
@@ -142,9 +142,9 @@
  * other operating systems handle it, so that I can enable it on those
  * systems.
  */
-#if ( defined(_AIX) )
+#if ( defined(_AIX) || defined(linux) )
 	if ( munmap((caddr_t)address, size) < 0 )
-		EF_Exit("munmap() failed: %s", stringErrorReport());
+		EF_Exit("munmap() failed: %s", __EF_stringErrorReport());
 #else
 	Page_DenyAccess(address, size);
 #endif
