Index: trunk/src/kmk/Makefile.am
===================================================================
--- trunk/src/kmk/Makefile.am	(revision 1704)
+++ trunk/src/kmk/Makefile.am	(revision 1705)
@@ -55,4 +55,5 @@
 		kmkbuiltin/append.c \
 		kmkbuiltin/cat.c \
+		kmkbuiltin/chmod.c \
 		kmkbuiltin/cmp.c \
 		kmkbuiltin/cmp_util.c \
Index: trunk/src/kmk/Makefile.kmk
===================================================================
--- trunk/src/kmk/Makefile.kmk	(revision 1704)
+++ trunk/src/kmk/Makefile.kmk	(revision 1705)
@@ -207,4 +207,5 @@
 	kmkbuiltin/append.c \
 	kmkbuiltin/cat.c \
+	kmkbuiltin/chmod.c \
 	kmkbuiltin/cmp.c \
 	kmkbuiltin/cmp_util.c \
@@ -237,4 +238,5 @@
 	kmk_append \
 	kmk_cat \
+	kmk_chmod \
 	kmk_cp \
 	kmk_cmp \
@@ -262,4 +264,9 @@
 kmk_cat_SOURCES = \
 	kmkbuiltin/cat.c
+
+kmk_chmod_TEMPLATE = BIN-KMK
+kmk_chmod_DEFS = kmk_builtin_chmod=main
+kmk_chmod_SOURCES = \
+	kmkbuiltin/chmod.c
 
 kmk_cmp_TEMPLATE = BIN-KMK
Index: trunk/src/kmk/kmkbuiltin.c
===================================================================
--- trunk/src/kmk/kmkbuiltin.c	(revision 1704)
+++ trunk/src/kmk/kmkbuiltin.c	(revision 1705)
@@ -208,4 +208,6 @@
         rc = kmk_builtin_test(argc, argv, environ, ppapszArgvToSpawn);
     /* rarely used commands: */
+    else if (!strcmp(pszCmd, "chmod"))
+        rc = kmk_builtin_chmod(argc, argv, environ);
     else if (!strcmp(pszCmd, "cp"))
         rc = kmk_builtin_cp(argc, argv, environ);
Index: trunk/src/kmk/kmkbuiltin.h
===================================================================
--- trunk/src/kmk/kmkbuiltin.h	(revision 1704)
+++ trunk/src/kmk/kmkbuiltin.h	(revision 1705)
@@ -39,4 +39,5 @@
 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_chmod(int argc, char **argv, char **envp);
 extern int kmk_builtin_cmp(int argc, char **argv, char **envp);
 extern int kmk_builtin_echo(int argc, char **argv, char **envp);
Index: trunk/src/kmk/kmkbuiltin/chmod.c
===================================================================
--- trunk/src/kmk/kmkbuiltin/chmod.c	(revision 1704)
+++ trunk/src/kmk/kmkbuiltin/chmod.c	(revision 1705)
@@ -39,11 +39,11 @@
 #endif /* not lint */
 #endif
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/chmod/chmod.c,v 1.33 2005/01/10 08:39:20 imp Exp $");
+/*#include <sys/cdefs.h> */
+/*__FBSDID("$FreeBSD: src/bin/chmod/chmod.c,v 1.33 2005/01/10 08:39:20 imp Exp $");*/
 
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include <err.h>
+#include "err.h"
 #include <errno.h>
 #include <fts.h>
@@ -52,10 +52,28 @@
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
-
-void usage(void);
+#ifndef _MSC_VER
+# include <unistd.h>
+#else
+# include "mscfakes.h"
+#endif 
+#include "getopt.h"
+#include "kmkbuiltin.h"
+
+#if defined(__APPLE__) && !defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)
+extern int lchmod(const char *, mode_t);
+#endif
+
+static int usage(FILE *);
+
+static struct option long_options[] =
+{
+    { "help",   					no_argument, 0, 261 },
+    { "version",   					no_argument, 0, 262 },
+    { 0, 0,	0, 0 },
+};
+
 
 int
-main(int argc, char *argv[])
+kmk_builtin_chmod(int argc, char *argv[], char **envp)
 {
 	FTS *ftsp;
@@ -68,7 +86,14 @@
 	int (*change_mode)(const char *, mode_t);
 
+	/* kmk: reset getopt and set progname */
+	g_progname = argv[0];
+	opterr = 1;
+	optarg = NULL;
+	optopt = 0;
+	optind = 0; /* init */
+
 	set = NULL;
 	Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
-	while ((ch = getopt(argc, argv, "HLPRXfghorstuvwx")) != -1)
+	while ((ch = getopt_long(argc, argv, "HLPRXfghorstuvwx", long_options, NULL)) != -1)
 		switch (ch) {
 		case 'H':
@@ -116,7 +141,12 @@
 			vflag++;
 			break;
+		case 261:
+			usage(stdout);
+			return 0;
+		case 262:
+			return kbuild_version(argv[0]);
 		case '?':
 		default:
-			usage();
+			return usage(stderr);
 		}
 done:	argv += optind;
@@ -124,10 +154,10 @@
 
 	if (argc < 2)
-		usage();
+		return usage(stderr);
 
 	if (Rflag) {
 		fts_options = FTS_PHYSICAL;
 		if (hflag)
-			errx(1,
+			return errx(1,
 		"the -R and -h options may not be specified together.");
 		if (Hflag)
@@ -147,8 +177,8 @@
 	mode = *argv;
 	if ((set = setmode(mode)) == NULL)
-		errx(1, "invalid file mode: %s", mode);
+		return errx(1, "invalid file mode: %s", mode);
 
 	if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
-		err(1, "fts_open");
+		return err(1, "fts_open");
 	for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
 		switch (p->fts_info) {
@@ -208,14 +238,19 @@
 	}
 	if (errno)
-		err(1, "fts_read");
+		rval = err(1, "fts_read");
 	free(set);
-	exit(rval);
+	fts_close(ftsp);
+	return rval;
 }
 
-void
-usage(void)
+int
+usage(FILE *out)
 {
-	(void)fprintf(stderr,
-	    "usage: chmod [-fhv] [-R [-H | -L | -P]] mode file ...\n");
-	exit(1);
+	(void)fprintf(out,
+	    "usage: %s [-fhv] [-R [-H | -L | -P]] mode file ...\n"
+	    "   or: %s --version\n"
+	    "   or: %s --help\n",
+	    g_progname, g_progname, g_progname);
+
+	return 1;
 }
