Index: /trunk/ChangeLog
===================================================================
--- /trunk/ChangeLog	(revision 610)
+++ /trunk/ChangeLog	(revision 611)
@@ -3,4 +3,6 @@
 2006-11-25:
     - kmk, kBuild:
+        o Added cat as builtin command.
+        o Added GNU sed version 4.1.5 and ported it to MSC.
         o Added rmdir as builtin and external command.
         o Made mkdir not modify the argument strings.
Index: /trunk/src/gmake/Makefile.kmk
===================================================================
--- /trunk/src/gmake/Makefile.kmk	(revision 610)
+++ /trunk/src/gmake/Makefile.kmk	(revision 611)
@@ -97,4 +97,5 @@
 	kmkbuiltin.c \
 	kmkbuiltin/append.c \
+	kmkbuiltin/cat.c \
 	kmkbuiltin/cp.c \
 	kmkbuiltin/cp_utils.c \
@@ -124,5 +125,5 @@
 # Standalone kmkbuiltin commands.
 #
-PROGRAMS += kmk_append kmk_cp kmk_echo kmk_mkdir kmk_install kmk_ln kmk_rm kmk_rmdir
+PROGRAMS += kmk_append kmk_cat kmk_cp kmk_echo kmk_mkdir kmk_install kmk_ln kmk_rm kmk_rmdir
 
 kmk_append_TEMPLATE = BIN
@@ -132,4 +133,18 @@
 	kmkbuiltin/append.c \
 	kmkbuiltin/err.c
+
+kmk_cat_TEMPLATE = BIN
+kmk_cat_DEFS = kmk_builtin_cat=main
+kmk_cat_SOURCES = \
+	kmkbuiltin/cat.c \
+	kmkbuiltin/err.c
+ifeq ($(filter-out win32 win64 win nt,$(BUILD_TARGET)),)
+kmk_cat_INCS += $(PATH_TARGET) .
+kmk_cat_DEFS += HAVE_CONFIG_H
+kmk_cat_SOURCES += \
+	kmkbuiltin/mscfakes.c \
+	getopt.c \
+	getopt1.c
+endif
 
 kmk_cp_TEMPLATE = BIN
Index: /trunk/src/gmake/kmkbuiltin.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin.c	(revision 610)
+++ /trunk/src/gmake/kmkbuiltin.c	(revision 611)
@@ -198,5 +198,6 @@
     else if (!strcmp(pszCmd, "rmdir"))
         rc = kmk_builtin_rmdir(argc, argv, environ);
-    /* obsolete */
+    else if (!strcmp(pszCmd, "cat"))
+        rc = kmk_builtin_cat(argc, argv, environ);
     else if (!strcmp(pszCmd, "cp"))
         rc = kmk_builtin_cp(argc, argv, environ);
Index: /trunk/src/gmake/kmkbuiltin.h
===================================================================
--- /trunk/src/gmake/kmkbuiltin.h	(revision 610)
+++ /trunk/src/gmake/kmkbuiltin.h	(revision 611)
@@ -30,4 +30,5 @@
 extern int kmk_builtin_append(int argc, char **argv, char **envp);
 extern int kmk_builtin_cp(int argc, char **argv, char **envp);
+extern int kmk_builtin_cat(int argc, char **argv, char **envp);
 extern int kmk_builtin_echo(int argc, char **argv, char **envp);
 extern int kmk_builtin_install(int argc, char **argv, char **envp);
Index: /trunk/src/gmake/kmkbuiltin/cat.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin/cat.c	(revision 610)
+++ /trunk/src/gmake/kmkbuiltin/cat.c	(revision 611)
@@ -44,8 +44,14 @@
 #endif
 #endif /* not lint */
+#if 0
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/bin/cat/cat.c,v 1.32 2005/01/10 08:39:20 imp Exp $");
-
+#else
+#define NO_UDOM_SUPPORT /* kmk */
+#endif 
+
+#ifndef _MSC_VER
 #include <sys/param.h>
+#endif
 #include <sys/stat.h>
 #ifndef NO_UDOM_SUPPORT
@@ -56,5 +62,5 @@
 
 #include <ctype.h>
-#include <err.h>
+#include "err.h"
 #include <fcntl.h>
 #include <locale.h>
@@ -62,15 +68,19 @@
 #include <stdlib.h>
 #include <string.h>
+#ifndef _MSC_VER
 #include <unistd.h>
+#else
+#include "mscfakes.h"
+#endif 
 #include <stddef.h>
 
 int bflag, eflag, nflag, sflag, tflag, vflag;
-int rval;
+/*int rval;*/
 const char *filename;
 
-static void usage(void);
-static void scanfiles(char *argv[], int cooked);
-static void cook_cat(FILE *);
-static void raw_cat(int);
+static int usage(void);
+static int scanfiles(char *argv[], int cooked);
+static int cook_cat(FILE *);
+static int raw_cat(int);
 
 #ifndef NO_UDOM_SUPPORT
@@ -79,9 +89,27 @@
 
 int
-main(int argc, char *argv[])
-{
-	int ch;
-
+kmk_builtin_cat(int argc, char *argv[])
+{
+	int ch, rc;
+
+	/* kmk: reinitialize globals */
+	bflag = eflag = nflag = sflag = tflag = vflag = 0;
+	filename = NULL;
+
+	/* kmk: reset getopt and set progname */
+	g_progname = argv[0];
+	opterr = 1;
+	optarg = NULL;
+	optopt = 0;
+#if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__)
+	optreset = 1;
+	optind = 1;
+#else
+	optind = 0; /* init */
+#endif
+
+#ifdef kmk_builtin_cat /* kmk did this already. */
 	setlocale(LC_CTYPE, "");
+#endif 
 
 	while ((ch = getopt(argc, argv, "benstuv")) != -1)
@@ -109,27 +137,27 @@
 			break;
 		default:
-			usage();
+			return usage();
 		}
 	argv += optind;
 
 	if (bflag || eflag || nflag || sflag || tflag || vflag)
-		scanfiles(argv, 1);
+		rc = scanfiles(argv, 1);
 	else
-		scanfiles(argv, 0);
+		rc = scanfiles(argv, 0);
+#ifdef kmk_builtin_cat /* only in the external program. */
 	if (fclose(stdout))
-		err(1, "stdout");
-	exit(rval);
-	/* NOTREACHED */
-}
-
-static void
+		return err(1, "stdout");
+#endif
+	return rc;
+}
+
+static int
 usage(void)
 {
 	fprintf(stderr, "usage: cat [-benstuv] [file ...]\n");
-	exit(1);
-	/* NOTREACHED */
-}
-
-static void
+	return 1;
+}
+
+static int
 scanfiles(char *argv[], int cooked)
 {
@@ -137,4 +165,6 @@
 	char *path;
 	FILE *fp;
+	int rc2 = 0;
+	int rc = 0;
 
 	while ((path = argv[i]) != NULL || i == 0) {
@@ -154,28 +184,30 @@
 		if (fd < 0) {
 			warn("%s", path);
-			rval = 1;
+			rc2 = 1; /* non fatal */
 		} else if (cooked) {
 			if (fd == STDIN_FILENO)
-				cook_cat(stdin);
+				rc = cook_cat(stdin);
 			else {
 				fp = fdopen(fd, "r");
-				cook_cat(fp);
+				rc = cook_cat(fp);
 				fclose(fp);
 			}
 		} else {
-			raw_cat(fd);
+			rc = raw_cat(fd);
 			if (fd != STDIN_FILENO)
 				close(fd);
 		}
-		if (path == NULL)
+		if (rc || path == NULL)
 			break;
 		++i;
 	}
-}
-
-static void
+	return !rc ? rc2 : rc;
+}
+
+static int
 cook_cat(FILE *fp)
 {
 	int ch, gobble, line, prev;
+	int rc = 0;
 
 	/* Reset EOF condition on stdin. */
@@ -228,12 +260,13 @@
 	if (ferror(fp)) {
 		warn("%s", filename);
-		rval = 1;
+		rc = 1;
 		clearerr(fp);
 	}
 	if (ferror(stdout))
-		err(1, "stdout");
-}
-
-static void
+		return err(1, "stdout");
+	return rc;
+}
+
+static int
 raw_cat(int rfd)
 {
@@ -247,17 +280,22 @@
 	if (buf == NULL) {
 		if (fstat(wfd, &sbuf))
-			err(1, "%s", filename);
+			return err(1, "%s", filename);
+#ifdef _MSC_VER
+		bsize = 1024;
+#else
 		bsize = MAX(sbuf.st_blksize, 1024);
+#endif 
 		if ((buf = malloc(bsize)) == NULL)
-			err(1, "buffer");
+			return err(1, "buffer");
 	}
 	while ((nr = read(rfd, buf, bsize)) > 0)
 		for (off = 0; nr; nr -= nw, off += nw)
 			if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
-				err(1, "stdout");
+				return err(1, "stdout");
 	if (nr < 0) {
 		warn("%s", filename);
-		rval = 1;
-	}
+		return 1;
+	}
+	return 0;
 }
 
Index: /trunk/src/gmake/kmkbuiltin/mkdir.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin/mkdir.c	(revision 610)
+++ /trunk/src/gmake/kmkbuiltin/mkdir.c	(revision 611)
@@ -79,17 +79,17 @@
 	mode = NULL;
 
-        /* reinitialize globals */
-        vflag = 0;
-
-        /* kmk: reset getopt and set progname */
-        g_progname = argv[0];
-        opterr = 1;
-        optarg = NULL;
-        optopt = 0;
+    /* reinitialize globals */
+    vflag = 0;
+    
+    /* kmk: reset getopt and set progname */
+    g_progname = argv[0];
+    opterr = 1;
+    optarg = NULL;
+    optopt = 0;
 #if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__)
-        optreset = 1;
-        optind = 1;
+    optreset = 1;
+    optind = 1;
 #else
-        optind = 0; /* init */
+    optind = 0; /* init */
 #endif
 	while ((ch = getopt(argc, argv, "m:pv")) != -1)
Index: /trunk/src/gmake/variable.c
===================================================================
--- /trunk/src/gmake/variable.c	(revision 610)
+++ /trunk/src/gmake/variable.c	(revision 611)
@@ -1062,5 +1062,5 @@
 #ifdef CONFIG_WITH_KMK_BUILTIN
   /* The supported kMk Builtin commands. */
-  (void) define_variable ("KMK_BUILTIN", 11, "append cp echo install ln mkdir rm rmdir", o_default, 0);
+  (void) define_variable ("KMK_BUILTIN", 11, "append cp cat echo install ln mkdir rm rmdir", o_default, 0);
 #endif
 
