Index: /trunk/src/kmk/kmkbuiltin/cat.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/cat.c	(revision 3217)
+++ /trunk/src/kmk/kmkbuiltin/cat.c	(revision 3218)
@@ -47,8 +47,11 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/bin/cat/cat.c,v 1.32 2005/01/10 08:39:20 imp Exp $");
-#else
+#endif
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define FAKES_NO_GETOPT_H /* bird */
 #define NO_UDOM_SUPPORT /* kmk */
-#endif
-
 #include "config.h"
 #ifndef _MSC_VER
@@ -71,5 +74,5 @@
 #include <unistd.h>
 #include <stddef.h>
-#include "getopt.h"
+#include "getopt_r.h"
 #ifdef __sun__
 # include "solfakes.h"
@@ -81,8 +84,22 @@
 
 
-int bflag, eflag, nflag, sflag, tflag, vflag;
-/*int rval;*/
-const char *filename;
-
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+typedef struct CATINSTANCE
+{
+    PKMKBUILTINCTX pCtx;
+    int bflag, eflag, nflag, sflag, tflag, vflag;
+    /*int rval;*/
+    const char *filename;
+    /* function level statics from raw_cat (needs freeing): */
+    size_t bsize;
+    char *buf;
+} CATINSTANCE;
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
 static struct option long_options[] =
 {
@@ -94,7 +111,7 @@
 
 static int usage(PKMKBUILTINCTX pCtx, int fIsErr);
-static int scanfiles(PKMKBUILTINCTX pCtx, char *argv[], int cooked);
-static int cook_cat(PKMKBUILTINCTX pCtx, FILE *);
-static int raw_cat(PKMKBUILTINCTX pCtx, int);
+static int scanfiles(CATINSTANCE *pThis, char *argv[], int cooked);
+static int cook_cat(CATINSTANCE *pThis, FILE *);
+static int raw_cat(CATINSTANCE *pThis, int);
 
 #ifndef NO_UDOM_SUPPORT
@@ -105,36 +122,32 @@
 kmk_builtin_cat(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx)
 {
+	struct getopt_state_r gos;
+	CATINSTANCE This;
 	int ch, rc;
 
 	/* kmk: reinitialize globals */
-	bflag = eflag = nflag = sflag = tflag = vflag = 0;
-	filename = NULL;
-
-	/* kmk: reset getopt and set progname */
-	opterr = 1;
-	optarg = NULL;
-	optopt = 0;
-	optind = 0; /* init */
-
-#ifdef KMK_BUILTIN_STANDALONE /* kmk did this already. */
-	setlocale(LC_CTYPE, "");
-#endif
-
-	while ((ch = getopt_long(argc, argv, "benstuv", long_options, NULL)) != -1)
+	This.pCtx = pCtx;
+	This.bflag = This.eflag = This.nflag = This.sflag = This.tflag = This.vflag = 0;
+	This.filename = NULL;
+	This.bsize = 0;
+	This.buf = 0;
+
+	getopt_initialize_r(&gos, argc, argv, "benstuv", long_options, envp, pCtx);
+	while ((ch = getopt_long_r(&gos, NULL)) != -1)
 		switch (ch) {
 		case 'b':
-			bflag = nflag = 1;	/* -b implies -n */
+			This.bflag = This.nflag = 1;	/* -b implies -n */
 			break;
 		case 'e':
-			eflag = vflag = 1;	/* -e implies -v */
+			This.eflag = This.vflag = 1;	/* -e implies -v */
 			break;
 		case 'n':
-			nflag = 1;
+			This.nflag = 1;
 			break;
 		case 's':
-			sflag = 1;
+			This.sflag = 1;
 			break;
 		case 't':
-			tflag = vflag = 1;	/* -t implies -v */
+			This.tflag = This.vflag = 1;	/* -t implies -v */
 			break;
 		case 'u':
@@ -144,5 +157,5 @@
 			break;
 		case 'v':
-			vflag = 1;
+			This.vflag = 1;
 			break;
 		case 261:
@@ -154,10 +167,14 @@
 			return usage(pCtx, 1);
 		}
-	argv += optind;
-
-	if (bflag || eflag || nflag || sflag || tflag || vflag)
-		rc = scanfiles(pCtx, argv, 1);
+	argv += gos.optind;
+
+	if (This.bflag || This.eflag || This.nflag || This.sflag || This.tflag || This.vflag)
+		rc = scanfiles(&This, argv, 1);
 	else
-		rc = scanfiles(pCtx, argv, 0);
+		rc = scanfiles(&This, argv, 0);
+	if (This.buf) {
+		free(This.buf);
+		This.buf = NULL;
+	}
 #ifdef KMK_BUILTIN_STANDALONE /* don't allow messing with stdout */
 	if (fclose(stdout))
@@ -170,6 +187,7 @@
 int main(int argc, char **argv, char **envp)
 {
-    KMKBUILTINCTX Ctx = { "kmk_cat", NULL };
-    return kmk_builtin_cat(argc, argv, envp, &Ctx);
+	KMKBUILTINCTX Ctx = { "kmk_cat", NULL };
+	setlocale(LC_CTYPE, "");
+	return kmk_builtin_cat(argc, argv, envp, &Ctx);
 }
 #endif
@@ -188,5 +206,5 @@
 
 static int
-scanfiles(PKMKBUILTINCTX pCtx, char *argv[], int cooked)
+scanfiles(CATINSTANCE *pThis, char *argv[], int cooked)
 {
 	int i = 0;
@@ -200,27 +218,27 @@
 
 		if (path == NULL || strcmp(path, "-") == 0) {
-			filename = "stdin";
+			pThis->filename = "stdin";
 			fd = STDIN_FILENO;
 		} else {
-			filename = path;
+			pThis->filename = path;
 			fd = open(path, O_RDONLY);
 #ifndef NO_UDOM_SUPPORT
 			if (fd < 0 && errno == EOPNOTSUPP)
-				fd = udom_open(pCtx, path, O_RDONLY);
+				fd = udom_open(pThis, path, O_RDONLY);
 #endif
 		}
 		if (fd < 0) {
-			warn(pCtx, "%s", path);
+			warn(pThis->pCtx, "%s", path);
 			rc2 = 1; /* non fatal */
 		} else if (cooked) {
 			if (fd == STDIN_FILENO)
-				rc = cook_cat(pCtx, stdin);
+				rc = cook_cat(pThis, stdin);
 			else {
 				fp = fdopen(fd, "r");
-				rc = cook_cat(pCtx, fp);
+				rc = cook_cat(pThis, fp);
 				fclose(fp);
 			}
 		} else {
-			rc = raw_cat(pCtx, fd);
+			rc = raw_cat(pThis, fd);
 			if (fd != STDIN_FILENO)
 				close(fd);
@@ -233,5 +251,6 @@
 }
 
-static int cat_putchar(PKMKBUILTINCTX pCtx, char ch)
+static int
+cat_putchar(PKMKBUILTINCTX pCtx, char ch)
 {
 #ifndef KMK_BUILTIN_STANDALONE
@@ -245,5 +264,5 @@
 
 static int
-cook_cat(PKMKBUILTINCTX pCtx, FILE *fp)
+cook_cat(CATINSTANCE *pThis, FILE *fp)
 {
 	int ch, gobble, line, prev;
@@ -257,5 +276,5 @@
 	for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
 		if (prev == '\n') {
-			if (sflag) {
+			if (pThis->sflag) {
 				if (ch == '\n') {
 					if (gobble)
@@ -265,6 +284,6 @@
 					gobble = 0;
 			}
-			if (nflag && (!bflag || ch != '\n')) {
-				kmk_builtin_ctx_printf(pCtx, 0, "%6d\t", ++line);
+			if (pThis->nflag && (!pThis->bflag || ch != '\n')) {
+				kmk_builtin_ctx_printf(pThis->pCtx, 0, "%6d\t", ++line);
 				if (ferror(stdout))
 					break;
@@ -272,21 +291,21 @@
 		}
 		if (ch == '\n') {
-			if (eflag && cat_putchar(pCtx, '$') == EOF)
+			if (pThis->eflag && cat_putchar(pThis->pCtx, '$') == EOF)
 				break;
 		} else if (ch == '\t') {
-			if (tflag) {
-				if (cat_putchar(pCtx, '^') == EOF || cat_putchar(pCtx, 'I') == EOF)
+			if (pThis->tflag) {
+				if (cat_putchar(pThis->pCtx, '^') == EOF || cat_putchar(pThis->pCtx, 'I') == EOF)
 					break;
 				continue;
 			}
-		} else if (vflag) {
+		} else if (pThis->vflag) {
 			if (!isascii(ch) && !isprint(ch)) {
-				if (cat_putchar(pCtx, 'M') == EOF || cat_putchar(pCtx, '-') == EOF)
+				if (cat_putchar(pThis->pCtx, 'M') == EOF || cat_putchar(pThis->pCtx, '-') == EOF)
 					break;
 				ch = toascii(ch);
 			}
 			if (iscntrl(ch)) {
-				if (cat_putchar(pCtx, '^') == EOF ||
-				    cat_putchar(pCtx, ch == '\177' ? '?' :
+				if (cat_putchar(pThis->pCtx, '^') == EOF ||
+				    cat_putchar(pThis->pCtx, ch == '\177' ? '?' :
 				    ch | 0100) == EOF)
 					break;
@@ -294,51 +313,49 @@
 			}
 		}
-		if (cat_putchar(pCtx, ch) == EOF)
+		if (cat_putchar(pThis->pCtx, ch) == EOF)
 			break;
 	}
 	if (ferror(fp)) {
-		warn(pCtx, "%s", filename);
+		warn(pThis->pCtx, "%s", pThis->filename);
 		rc = 1;
 		clearerr(fp);
 	}
 	if (ferror(stdout))
-		return err(pCtx, 1, "stdout");
+		return err(pThis->pCtx, 1, "stdout");
 	return rc;
 }
 
 static int
-raw_cat(PKMKBUILTINCTX pCtx, int rfd)
+raw_cat(CATINSTANCE *pThis, int rfd)
 {
 	int off, wfd = fileno(stdout);
 	ssize_t nr, nw;
-	static size_t bsize;
-	static char *buf = NULL;
-	struct stat sbuf;
 
 	wfd = fileno(stdout);
-	if (buf == NULL) {
+	if (pThis->buf == NULL) {
+		struct stat sbuf;
 		if (fstat(wfd, &sbuf))
-			return err(pCtx, 1, "%s", filename);
+			return err(pThis->pCtx, 1, "%s", pThis->filename);
 #ifdef KBUILD_OS_WINDOWS
-		bsize = 16384;
+		pThis->bsize = 16384;
 #else
-		bsize = MAX(sbuf.st_blksize, 1024);
-#endif
-		if ((buf = malloc(bsize)) == NULL)
-			return err(pCtx, 1, "buffer");
-	}
-	while ((nr = read(rfd, buf, bsize)) > 0)
+		pThis->bsize = MAX(sbuf.st_blksize, 1024);
+#endif
+		if ((pThis->buf = malloc(pThis->bsize)) == NULL)
+			return err(pThis->pCtx, 1, "buffer");
+	}
+	while ((nr = read(rfd, pThis->buf, pThis->bsize)) > 0)
 		for (off = 0; nr; nr -= nw, off += nw) {
 #ifndef KMK_BUILTIN_STANDALONE
-			if (pCtx->pOut)
-				nw = output_write_text(pCtx->pOut, 0, buf, nr);
+			if (pThis->pCtx->pOut)
+				nw = output_write_text(pThis->pCtx->pOut, 0, pThis->buf + off, nr);
 			else
 #endif
-				nw = write(wfd, buf + off, (size_t)nr);
+				nw = write(wfd, pThis->buf + off, (size_t)nr);
 			if (nw < 0)
-				return err(pCtx, 1, "stdout");
+				return err(pThis->pCtx, 1, "stdout");
 		}
 	if (nr < 0) {
-		warn(pCtx, "%s", filename);
+		warn(pThis->pCtx, "%s", pThis->filename);
 		return 1;
 	}
@@ -349,5 +366,5 @@
 
 static int
-udom_open(PKMKBUILTINCTX pCtx, const char *path, int flags)
+udom_open(CATINSTANCE *pThis, const char *path, int flags)
 {
 	struct sockaddr_un sou;
@@ -383,9 +400,9 @@
 		case O_RDONLY:
 			if (shutdown(fd, SHUT_WR) == -1)
-				warn(pCtx, NULL);
+				warn(pThis->pCtx, NULL);
 			break;
 		case O_WRONLY:
 			if (shutdown(fd, SHUT_RD) == -1)
-				warn(pCtx, NULL);
+				warn(pThis->pCtx, NULL);
 			break;
 		default:
