Index: /trunk/ChangeLog
===================================================================
--- /trunk/ChangeLog	(revision 612)
+++ /trunk/ChangeLog	(revision 613)
@@ -3,4 +3,5 @@
 2006-11-25:
     - kmk, kBuild:
+        o Added mv as builtin command.
         o Added cat as builtin command.
         o Added GNU sed version 4.1.5 and ported it to MSC.
Index: /trunk/src/gmake/Makefile.kmk
===================================================================
--- /trunk/src/gmake/Makefile.kmk	(revision 612)
+++ /trunk/src/gmake/Makefile.kmk	(revision 613)
@@ -103,4 +103,5 @@
 	kmkbuiltin/install.c \
 	kmkbuiltin/mkdir.c \
+	kmkbuiltin/mv.c \
 	kmkbuiltin/ln.c \
 	kmkbuiltin/rm.c \
@@ -125,5 +126,5 @@
 # Standalone kmkbuiltin commands.
 #
-PROGRAMS += kmk_append kmk_cat 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_mv kmk_install kmk_ln kmk_rm kmk_rmdir
 
 kmk_append_TEMPLATE = BIN
@@ -218,4 +219,19 @@
 kmk_mkdir_DEFS += HAVE_CONFIG_H
 kmk_mkdir_SOURCES += \
+	kmkbuiltin/mscfakes.c \
+	getopt.c \
+	getopt1.c
+endif
+
+kmk_mv_TEMPLATE = BIN
+kmk_mv_DEFS = kmk_builtin_mv=main
+kmk_mv_SOURCES = \
+	kmkbuiltin/mv.c \
+	kmkbuiltin/err.c \
+	kmkbuiltin/strmode.c
+ifeq ($(filter-out win32 win64 win nt,$(BUILD_TARGET)),)
+kmk_mv_INCS += $(PATH_TARGET) .
+kmk_mv_DEFS += HAVE_CONFIG_H
+kmk_mv_SOURCES += \
 	kmkbuiltin/mscfakes.c \
 	getopt.c \
Index: /trunk/src/gmake/kmkbuiltin.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin.c	(revision 612)
+++ /trunk/src/gmake/kmkbuiltin.c	(revision 613)
@@ -192,10 +192,11 @@
     else if (!strcmp(pszCmd, "mkdir"))
         rc = kmk_builtin_mkdir(argc, argv, environ);
-    //else if (!strcmp(pszCmd, "mv"))
-    //    rc = kmk_builtin_mv(argc, argv, environ);
+    else if (!strcmp(pszCmd, "mv"))
+        rc = kmk_builtin_mv(argc, argv, environ);
     else if (!strcmp(pszCmd, "rm"))
         rc = kmk_builtin_rm(argc, argv, environ);
     else if (!strcmp(pszCmd, "rmdir"))
         rc = kmk_builtin_rmdir(argc, argv, environ);
+    /* rarely used commands: */
     else if (!strcmp(pszCmd, "cat"))
         rc = kmk_builtin_cat(argc, argv, environ);
Index: /trunk/src/gmake/kmkbuiltin/mv.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin/mv.c	(revision 612)
+++ /trunk/src/gmake/kmkbuiltin/mv.c	(revision 613)
@@ -42,37 +42,71 @@
 #endif /* not lint */
 #endif
+#if 0
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/bin/mv/mv.c,v 1.46 2005/09/05 04:36:08 csjp Exp $");
+#endif 
 
 #include <sys/types.h>
+#ifndef _MSC_VER
 #include <sys/acl.h>
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <sys/mount.h>
+#endif
 #include <sys/stat.h>
-#include <sys/mount.h>
-
-#include <err.h>
+
+#include "err.h"
 #include <errno.h>
 #include <fcntl.h>
+#ifndef _MSC_VER
 #include <grp.h>
+#endif 
 #include <limits.h>
+#ifndef _MSC_VER
 #include <paths.h>
 #include <pwd.h>
+#endif 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifndef _MSC_VER
 #include <sysexits.h>
 #include <unistd.h>
-
-int fflg, iflg, nflg, vflg;
-
-int	copy(char *, char *);
-int	do_move(char *, char *);
-int	fastcopy(char *, char *, struct stat *);
-void	usage(void);
+#else
+#include "mscfakes.h"
+#endif
+
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
+extern void strmode(mode_t mode, char *p);
+#endif
+
+static int fflg, iflg, nflg, vflg;
+
+static int	do_move(char *, char *);
+#ifdef CROSS_DEVICE_MOVE
+static int	fastcopy(char *, char *, struct stat *);
+static int	copy(char *, char *);
+#endif 
+static int	usage(void);
+
+#if defined(_MSC_VER) || defined(__EMX__) || 0
+static const char *user_from_uid(unsigned long id, int x)
+{
+	static char s_buf[64];
+	sprintf(s_buf, "%ld", id);
+	return s_buf;
+}
+static const char *group_from_gid(unsigned long id, int x)
+{
+	static char s_buf[64];
+	sprintf(s_buf, "%ld", id);
+	return s_buf;
+}
+#endif
+
 
 int
-main(int argc, char *argv[])
+kmk_builtin_mv(int argc, char *argv[])
 {
 	size_t baselen, len;
@@ -82,4 +116,19 @@
 	int ch;
 	char path[PATH_MAX];
+
+	/* kmk: reinitialize globals */
+	fflg = iflg = nflg = vflg = 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;
+#else
+	optind = 0; /* init */
+#endif
 
 	while ((ch = getopt(argc, argv, "finv")) != -1)
@@ -101,5 +150,5 @@
 			break;
 		default:
-			usage();
+			return usage();
 		}
 	argc -= optind;
@@ -107,5 +156,5 @@
 
 	if (argc < 2)
-		usage();
+		return usage();
 
 	/*
@@ -115,15 +164,19 @@
 	if (stat(argv[argc - 1], &sb) || !S_ISDIR(sb.st_mode)) {
 		if (argc > 2)
-			usage();
-		exit(do_move(argv[0], argv[1]));
+			return usage();
+		return do_move(argv[0], argv[1]);
 	}
 
 	/* It's a directory, move each file into it. */
 	if (strlen(argv[argc - 1]) > sizeof(path) - 1)
-		errx(1, "%s: destination pathname too long", *argv);
+		return errx(1, "%s: destination pathname too long", *argv);
 	(void)strcpy(path, argv[argc - 1]);
 	baselen = strlen(path);
 	endp = &path[baselen];
+#if defined(_MSC_VER) || defined(__EMX__)
+	if (!baselen || (*(endp - 1) != '/' && *(endp - 1) != '\\' && *(endp - 1) != ':')) {
+#else
 	if (!baselen || *(endp - 1) != '/') {
+#endif 
 		*endp++ = '/';
 		++baselen;
@@ -135,8 +188,15 @@
 		 */
 		p = *argv + strlen(*argv);
+#if defined(_MSC_VER) || defined(__EMX__)
+		while (p != *argv && (p[-1] == '/' || p[-1] == '\\'))
+			--p;
+		while (p != *argv && p[-1] != '/' && p[-1] != '/' && p[-1] != ':')
+			--p;
+#else
 		while (p != *argv && p[-1] == '/')
 			--p;
 		while (p != *argv && p[-1] != '/')
 			--p;
+#endif 
 
 		if ((baselen + (len = strlen(p))) >= PATH_MAX) {
@@ -149,8 +209,8 @@
 		}
 	}
-	exit(rval);
-}
-
-int
+	return rval;
+}
+
+static int
 do_move(char *from, char *to)
 {
@@ -167,5 +227,5 @@
 
 		/* prompt only if source exist */
-	        if (lstat(from, &sb) == -1) {
+		if (lstat(from, &sb) == -1) {
 			warn("%s", from);
 			return (1);
@@ -206,4 +266,8 @@
 
 	if (errno == EXDEV) {
+#ifndef CROSS_DEVICE_MOVE
+		warnx("cannot move `%s' to a different device: `%s'", from, to);
+		return (1);
+#else
 		struct statfs sfs;
 		char path[PATH_MAX];
@@ -229,4 +293,5 @@
 			}
 		}
+#endif 
 	} else {
 		warn("rename %s to %s", from, to);
@@ -234,4 +299,5 @@
 	}
 
+#ifdef CROSS_DEVICE_MOVE
 	/*
 	 * If rename fails because we're trying to cross devices, and
@@ -245,8 +311,10 @@
 	return (S_ISREG(sb.st_mode) ?
 	    fastcopy(from, to, &sb) : copy(from, to));
-}
-
+#endif 
+}
+
+#ifdef CROSS_DEVICE_MOVE
 int
-fastcopy(char *from, char *to, struct stat *sbp)
+static fastcopy(char *from, char *to, struct stat *sbp)
 {
 	struct timeval tval[2];
@@ -397,6 +465,8 @@
 	return (0);
 }
-
-void
+#endif /* CROSS_DEVICE_MOVE */
+
+
+static int
 usage(void)
 {
@@ -405,4 +475,4 @@
 		      "usage: mv [-f | -i | -n] [-v] source target",
 		      "       mv [-f | -i | -n] [-v] source ... directory");
-	exit(EX_USAGE);
-}
+	return EX_USAGE;
+}
