diff --git a/ghc/lib/cbits/Makefile b/ghc/lib/cbits/Makefile
index 9266c58ba6d4036d686ea598affb55706be2db69..c9fecc4e33e206938668a7922029ec356ac3b048 100644
--- a/ghc/lib/cbits/Makefile
+++ b/ghc/lib/cbits/Makefile
@@ -1,37 +1,30 @@
-# $Id: Makefile,v 1.2 1996/11/21 16:47:46 simonm Exp $
-
-TOP = ../../..
-UnlitSuffixRules = YES
-include $(TOP)/ghc/mk/ghc.mk
-
-ARCHIVE=libHS_cbits.a
-DESTDIR=$(INSTLIBDIR_GHC)
-
-SRCS=\
-closeFile.lc		createDirectory.lc		\
-errno.lc		fileEOF.lc			\
-fileGetc.lc		fileLookAhead.lc		\
-filePosn.lc		filePutc.lc			\
-fileSize.lc		flushFile.lc			\
-getBufferMode.lc	getCurrentDirectory.lc		\
-getDirectoryContents.lc getLock.lc			\
-inputReady.lc		openFile.lc			\
-readFile.lc		removeDirectory.lc		\
-removeFile.lc		renameDirectory.lc		\
-renameFile.lc		seekFile.lc			\
-setBuffering.lc		setCurrentDirectory.lc		\
-system.lc		writeFile.lc
-
-LIBOBJS = $(patsubst %.lc, %.o, $(SRCS))
-
-%.o : %.c
-	@$(RM) $@
-	$(GHC) $(GHCFLAGS) -c $< -o $@
-
-clean ::
-	$(RM) $(SRCS:.lc=.c)
-
-C_DEP_SRCS = $(SRCS) 
-MKDEPENDC_OPTS = -I$(GHC_INCLUDES)
-
-include $(TOP)/mk/lib.mk
+# $Id: Makefile,v 1.3 1997/03/14 05:17:06 sof Exp $
+
+TOP = ../..
+include $(TOP)/mk/boilerplate.mk
+WAYS=
+
+LIBRARY=libHS_cbits.a
+INSTALL_LIBS+=$(LIBRARY)
+
+SRCS= $(wildcard *.lc)
+
+C_SRCS  = $(SRCS:.lc=.c)
+C_OBJS  = $(C_SRCS:.c=.o)
+LIBOBJS = $(C_OBJS)
+SRC_CC_OPTS = -I$(GHC_INCLUDE_DIR)
+
+#
+# Compile the files using the Haskell compiler (ghc really).
+# 
+CC=$(HC)
+
+#
+# Remove the intermediate .c files
+# (the .o's will be removed automatically by default mk setup)
+#
+CLEAN_FILES += $(C_SRCS)
+
+SRC_MKDEPENDC_OPTS += -I$(GHC_INCLUDE_DIR)
+
+include $(TOP)/mk/target.mk
diff --git a/ghc/lib/cbits/closeFile.lc b/ghc/lib/cbits/closeFile.lc
index f3efb3488de60abe78d1a089985099ddfc8dc49c..9f4c80eb8d289b2e326f1be75d0066fa1d98e8a4 100644
--- a/ghc/lib/cbits/closeFile.lc
+++ b/ghc/lib/cbits/closeFile.lc
@@ -10,11 +10,14 @@
 
 StgInt
 closeFile(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     int rc;
 
-    unlockFile(fileno((FILE *) fp));
+    if (unlockFile(fileno((FILE *) fp))) {
+       /* If it has been unlocked, don't bother fclose()ing */
+       return 0;
+    }
 
     while ((rc = fclose((FILE *) fp)) != 0) {
 	if (errno != EINTR) {
diff --git a/ghc/lib/cbits/fileEOF.lc b/ghc/lib/cbits/fileEOF.lc
index 81128d4d9cc4a1c7e72107b424fd25875af2873f..cdd3eb20cf2c16b77abf2d536a518c172f1713bf 100644
--- a/ghc/lib/cbits/fileEOF.lc
+++ b/ghc/lib/cbits/fileEOF.lc
@@ -10,7 +10,7 @@
 
 StgInt
 fileEOF(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     if (fileLookAhead(fp) != EOF)
 	return 0;
diff --git a/ghc/lib/cbits/fileGetc.lc b/ghc/lib/cbits/fileGetc.lc
index 336c0d9a7c18fe5715532eb30cc8a6969e5aea77..131c956364af3eab0b0334670d9f13ed7c7fbd2f 100644
--- a/ghc/lib/cbits/fileGetc.lc
+++ b/ghc/lib/cbits/fileGetc.lc
@@ -11,7 +11,7 @@
 
 StgInt
 fileGetc(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     int c;
 
diff --git a/ghc/lib/cbits/fileLookAhead.lc b/ghc/lib/cbits/fileLookAhead.lc
index df0d332ca72b98c69dd220c62116ab7536fdd29b..91a172251d6240c1e9e3d5fe298ab15966ef31a5 100644
--- a/ghc/lib/cbits/fileLookAhead.lc
+++ b/ghc/lib/cbits/fileLookAhead.lc
@@ -10,7 +10,7 @@
 
 StgInt
 fileLookAhead(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     int c;
 
diff --git a/ghc/lib/cbits/filePosn.lc b/ghc/lib/cbits/filePosn.lc
index 826c4f48b3118dcaf84279bfd51191904b9dac86..7a0d7907b80a6786ace9e994db551b737d2e5af9 100644
--- a/ghc/lib/cbits/filePosn.lc
+++ b/ghc/lib/cbits/filePosn.lc
@@ -10,7 +10,7 @@
 
 StgInt
 getFilePosn(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     StgInt posn;
 
@@ -29,7 +29,7 @@ StgAddr fp;
 
 StgInt
 setFilePosn(fp, posn)
-StgAddr fp;
+StgForeignObj fp;
 StgInt posn;
 {
     while (fseek((FILE *) fp, posn, SEEK_SET) != 0) {
diff --git a/ghc/lib/cbits/filePutc.lc b/ghc/lib/cbits/filePutc.lc
index bca57bafbeec439f3533f823177e886010972f2e..4e6b85bb04e452a0fb77c6f2cbf3fa2f47439530 100644
--- a/ghc/lib/cbits/filePutc.lc
+++ b/ghc/lib/cbits/filePutc.lc
@@ -11,7 +11,7 @@
 
 StgInt
 filePutc(fp, c)
-StgAddr fp;
+StgForeignObj fp;
 StgInt c;
 {
     int rc;
diff --git a/ghc/lib/cbits/fileSize.lc b/ghc/lib/cbits/fileSize.lc
index ed3da3c77acdc33eb2715ae2111d53605037fa88..34348feedf8355577ed91fb5634bfa3401e44fb1 100644
--- a/ghc/lib/cbits/fileSize.lc
+++ b/ghc/lib/cbits/fileSize.lc
@@ -18,7 +18,7 @@
   
 StgInt
 fileSize(fp, result)
-StgAddr fp;
+StgForeignObj fp;
 StgByteArray result;
 {
     struct stat sb;
diff --git a/ghc/lib/cbits/flushFile.lc b/ghc/lib/cbits/flushFile.lc
index 68aa4456c514222e783332531ad58435400c0abd..6cfd484e741eaac24aa4578c82c983cb477cf706 100644
--- a/ghc/lib/cbits/flushFile.lc
+++ b/ghc/lib/cbits/flushFile.lc
@@ -10,7 +10,7 @@
 
 StgInt
 flushFile(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     int rc;
 
diff --git a/ghc/lib/cbits/getBufferMode.lc b/ghc/lib/cbits/getBufferMode.lc
index 0c6bb44b70530de91773e6ccf26f75ccb37e2cd2..cb0b9840d2a25cb502d70f748c6cb5f5ecd208fe 100644
--- a/ghc/lib/cbits/getBufferMode.lc
+++ b/ghc/lib/cbits/getBufferMode.lc
@@ -28,7 +28,7 @@
 
 StgInt
 getBufferMode(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     struct stat sb;
 
diff --git a/ghc/lib/cbits/getLock.lc b/ghc/lib/cbits/getLock.lc
index f39014e25e0df15d42861e3a3aaeefb9c40d556d..1ed0dbf7eedfe3a70687b4bfd2e7a9d8634da960 100644
--- a/ghc/lib/cbits/getLock.lc
+++ b/ghc/lib/cbits/getLock.lc
@@ -85,18 +85,18 @@ int exclusive;
     return 0;
 }
 
-void
+int
 unlockFile(fd)
 int fd;
 {
-    int i;
+    int i, rc;
 
     for (i = 0; i < readLocks; i++)
 	if (readLock[i].fd == fd) {
 	    while (++i < readLocks)
 		readLock[i - 1] = readLock[i];
 	    readLocks--;
-	    return;
+	    return 0;
 	}
 
     for (i = 0; i < writeLocks; i++)
@@ -104,13 +104,15 @@ int fd;
 	    while (++i < writeLocks)
 		writeLock[i - 1] = writeLock[i];
 	    writeLocks--;
-	    return;
+	    return 0;
 	}
+     /* Signal that we did not find an entry */
+    return 1;
 }
 
 StgInt
 getLock(fp, exclusive)
-StgAddr fp;
+StgForeignObj fp;
 StgInt exclusive;
 {
     if (lockFile(fileno((FILE *) fp), exclusive) < 0) {
diff --git a/ghc/lib/cbits/inputReady.lc b/ghc/lib/cbits/inputReady.lc
index fc8184e994d9c1a81b7e9d002b7490ae9551d162..7e62f31eec1b38c3e400efd7671046e7fc53597d 100644
--- a/ghc/lib/cbits/inputReady.lc
+++ b/ghc/lib/cbits/inputReady.lc
@@ -22,7 +22,7 @@
 
 StgInt
 inputReady(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     int flags;
     int c;
diff --git a/ghc/lib/cbits/readFile.lc b/ghc/lib/cbits/readFile.lc
index 2b649e3dbd572dbd4f61e2db1d5a51a7e3b541e9..0cc9c2c7b9319ef3e95be070e9fbb1afd91443b3 100644
--- a/ghc/lib/cbits/readFile.lc
+++ b/ghc/lib/cbits/readFile.lc
@@ -13,7 +13,7 @@
 StgInt
 readBlock(buf, fp, size)
 StgAddr buf;
-StgAddr fp;
+StgForeignObj fp;
 StgInt size;
 {
     int count;
@@ -43,7 +43,7 @@ StgInt size;
 StgInt
 readLine(buf, fp, size)
 StgAddr buf;
-StgAddr fp;
+StgForeignObj fp;
 StgInt size;
 {
     if (feof((FILE *) fp)) {
@@ -70,7 +70,7 @@ StgInt size;
 
 StgInt
 readChar(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     int c;
 
diff --git a/ghc/lib/cbits/seekFile.lc b/ghc/lib/cbits/seekFile.lc
index caff60701875c966248b005430476f71ae990278..48c0cf7d3b91a942cc3991a09815a07f96365862 100644
--- a/ghc/lib/cbits/seekFile.lc
+++ b/ghc/lib/cbits/seekFile.lc
@@ -18,7 +18,7 @@
 
 StgInt
 seekFile(fp, whence, size, d)
-StgAddr fp;
+StgForeignObj fp;
 StgInt whence;
 StgInt size;
 StgByteArray d;
@@ -106,7 +106,7 @@ StgByteArray d;
 
 StgInt
 seekFileP(fp)
-StgAddr fp;
+StgForeignObj fp;
 {
     struct stat sb;
 
diff --git a/ghc/lib/cbits/setBuffering.lc b/ghc/lib/cbits/setBuffering.lc
index ffccf70ca0df76a103988cea06a8dded75da6771..0169b50ce2f26c62a8b21fd214d8892450782e00 100644
--- a/ghc/lib/cbits/setBuffering.lc
+++ b/ghc/lib/cbits/setBuffering.lc
@@ -30,7 +30,7 @@
 
 StgInt
 setBuffering(fp, size)
-StgAddr fp;
+StgForeignObj fp;
 StgInt size;
 {
     int flags;
diff --git a/ghc/lib/cbits/stgio.h b/ghc/lib/cbits/stgio.h
index 791323769ad333dc06138870be01c0cdc8c16ab1..82b223f9cd9cf29ae2e5c69cf7bf49b7f784e3dd 100644
--- a/ghc/lib/cbits/stgio.h
+++ b/ghc/lib/cbits/stgio.h
@@ -1,14 +1,14 @@
 #ifndef STGIO_H
 #define STGIO_H
 
-/* Decls for routines in ghc/runtime/io/ only used there.
+/* Decls for routines in ghc/lib/cbits/ only used there.
  * This file is used when compiling the Haskell library
  * that _ccalls_ those routines; and when compiling those
  * routines (to check consistency).
  */
 
 /* closeFile.lc */
-StgInt closeFile PROTO((StgAddr));
+StgInt closeFile PROTO((StgForeignObj));
 
 /* createDirectory.lc */
 StgInt createDirectory PROTO((StgByteArray));
@@ -30,29 +30,28 @@ void	stdErrno(STG_NO_ARGS);
 int	execvpe PROTO((char *, char **, char **));
 
 /* fileEOF.lc */
-StgInt	fileEOF PROTO((StgAddr));
-
+StgInt	fileEOF PROTO((StgForeignObj));
 /* fileGetc.lc */
-StgInt	fileGetc PROTO((StgAddr));
+StgInt	fileGetc PROTO((StgForeignObj));
 
 /* fileLookAhead.lc */
-StgInt	fileLookAhead PROTO((StgAddr));
+StgInt	fileLookAhead PROTO((StgForeignObj));
 
 /* filePosn.lc */
-StgInt	getFilePosn PROTO((StgAddr));
-StgInt	setFilePosn PROTO((StgAddr, StgInt));
+StgInt	getFilePosn PROTO((StgForeignObj));
+StgInt	setFilePosn PROTO((StgForeignObj, StgInt));
 
 /* filePutc.lc */
-StgInt	filePutc    PROTO((StgAddr, StgInt));
+StgInt	filePutc    PROTO((StgForeignObj, StgInt));
 
 /* fileSize.lc */
-StgInt	fileSize    PROTO((StgAddr, StgByteArray));
+StgInt	fileSize    PROTO((StgForeignObj, StgByteArray));
 
 /* flushFile.lc */
-StgInt	flushFile   PROTO((StgAddr));
+StgInt	flushFile   PROTO((StgForeignObj));
 
 /* getBufferMode.lc */
-StgInt	getBufferMode PROTO((StgAddr));
+StgInt	getBufferMode PROTO((StgForeignObj));
 
 /* getClockTime.lc */
 StgInt	getClockTime PROTO((StgByteArray, StgByteArray));
@@ -68,19 +67,23 @@ StgAddr getDirectoryContents PROTO((StgByteArray));
 
 /* getLock.lc */
 int     lockFile    PROTO((int, int));
-void    unlockFile  PROTO((int));
-StgInt	getLock	    PROTO((StgAddr, StgInt));
+int     unlockFile  PROTO((int));
+StgInt	getLock	    PROTO((StgForeignObj, StgInt));
 
 /* inputReady.lc */
-StgInt	inputReady  PROTO((StgAddr));
+StgInt	inputReady  PROTO((StgForeignObj));
 
 /* openFile.lc */
 StgAddr openFile PROTO((StgByteArray, StgByteArray));
 
+/* freeFile.lc */
+void freeStdChannel PROTO((StgForeignObj));
+void freeFile PROTO((StgForeignObj));
+
 /* readFile.lc */
-StgInt	readBlock PROTO((StgAddr, StgAddr, StgInt));
-StgInt	readLine PROTO((StgAddr, StgAddr, StgInt));
-StgInt	readChar PROTO((StgAddr));
+StgInt	readBlock PROTO((StgAddr, StgForeignObj, StgInt));
+StgInt	readLine PROTO((StgAddr,  StgForeignObj, StgInt));
+StgInt	readChar PROTO((StgForeignObj));
 
 /* removeDirectory.lc */
 StgInt removeDirectory PROTO((StgByteArray));
@@ -95,11 +98,11 @@ StgInt renameDirectory PROTO((StgByteArray, StgByteArray));
 StgInt renameFile PROTO((StgByteArray, StgByteArray));
 
 /* seekFile.lc */
-StgInt	seekFile  PROTO((StgAddr, StgInt, StgInt, StgByteArray));
-StgInt	seekFileP PROTO((StgAddr));
+StgInt	seekFile  PROTO((StgForeignObj, StgInt, StgInt, StgByteArray));
+StgInt	seekFileP PROTO((StgForeignObj));
 
 /* setBuffering.lc */
-StgInt	setBuffering PROTO((StgAddr, StgInt));
+StgInt	setBuffering PROTO((StgForeignObj, StgInt));
 
 /* setCurrentDirectory.lc */
 StgInt setCurrentDirectory PROTO((StgByteArray));
@@ -120,6 +123,6 @@ StgAddr toUTCTime PROTO((StgInt, StgByteArray, StgByteArray));
 StgAddr toClockSec PROTO((StgInt, StgInt, StgInt, StgInt, StgInt, StgInt, StgInt, StgByteArray));
 
 /* writeFile.lc */
-StgInt	writeFile PROTO((StgAddr, StgAddr, StgInt));
+StgInt	writeFile PROTO((StgAddr, StgForeignObj, StgInt));
 
 #endif /* ! STGIO_H */
diff --git a/ghc/lib/cbits/writeFile.lc b/ghc/lib/cbits/writeFile.lc
index 6981bf128ca2f87291956fa63a5221c48acadd95..71c7b0df173e69f75431ac8a9718e1e95f4cd88e 100644
--- a/ghc/lib/cbits/writeFile.lc
+++ b/ghc/lib/cbits/writeFile.lc
@@ -11,7 +11,7 @@
 StgInt
 writeFile(buf, fp, bytes)
 StgAddr buf;
-StgAddr fp;
+StgForeignObj fp;
 StgInt bytes;
 {
     int count;