Index: /trunk/src/kmk/function.c
===================================================================
--- /trunk/src/kmk/function.c	(revision 3388)
+++ /trunk/src/kmk/function.c	(revision 3389)
@@ -5665,6 +5665,6 @@
     }
 
-  u = umask (002);
-  umask (u);
+  u = g_fUMask;
+  assert (u == umask (g_fUMask));
 
   if (symbolic)
@@ -5734,13 +5734,12 @@
       if (argv[1] != NULL)
           OS (error, reading_file, _("$(%s ) too many arguments for octal mode"), funcname);
+
+      umask (u);
+      g_fUMask = u;
   }
   else
   {
-      u = umask(0);
-      umask(u);
       OS (error, reading_file, _("$(%s ) symbol mode is not implemented"), funcname);
   }
-
-  umask(u);
 
   return o;
Index: /trunk/src/kmk/kmkbuiltin.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin.c	(revision 3388)
+++ /trunk/src/kmk/kmkbuiltin.c	(revision 3389)
@@ -402,5 +402,5 @@
                 {
                     /*
-                     * Call the worker function, making sure to preserve umask.
+                     * Call the worker function.
                      */
 #ifdef CONFIG_WITH_KMK_BUILTIN_STATS
@@ -408,6 +408,5 @@
 #endif
                     KMKBUILTINCTX Ctx;
-                    int const iUmask = umask(0);        /* save umask */
-                    umask(iUmask);
+                    assert(g_fUMask == umask(g_fUMask));
 
                     Ctx.pszProgName = pEntry->uName.s.sz;
@@ -448,5 +447,5 @@
                         rc = 99;
 
-                    umask(iUmask);                      /* restore it */
+                    assert(g_fUMask == umask(g_fUMask)); /* builtin command must preserve umask! */
 
 #ifdef CONFIG_WITH_KMK_BUILTIN_STATS
Index: /trunk/src/kmk/kmkbuiltin/chmod.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/chmod.c	(revision 3388)
+++ /trunk/src/kmk/kmkbuiltin/chmod.c	(revision 3389)
@@ -278,7 +278,9 @@
 
 #ifdef KMK_BUILTIN_STANDALONE
+mode_t g_fUMask;
 int main(int argc, char **argv, char **envp)
 {
     KMKBUILTINCTX Ctx = { "kmk_chmod", NULL };
+    umask(g_fUMask = umask(0077));
     return kmk_builtin_chmod(argc, argv, envp, &Ctx);
 }
Index: /trunk/src/kmk/kmkbuiltin/cp.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/cp.c	(revision 3388)
+++ /trunk/src/kmk/kmkbuiltin/cp.c	(revision 3389)
@@ -69,4 +69,5 @@
 #include <sys/stat.h>
 
+#include <assert.h>
 #include "err.h"
 #include <errno.h>
@@ -175,4 +176,6 @@
 volatile sig_atomic_t g_cp_info;
 #endif
+
+extern mode_t g_fUMask;
 
 
@@ -423,7 +426,9 @@
 
 #ifdef KMK_BUILTIN_STANDALONE
+mode_t g_fUMask;
 int main(int argc, char **argv, char **envp)
 {
     KMKBUILTINCTX Ctx = { "kmk_cp", NULL };
+    umask(g_fUMask = umask(0077));
     return kmk_builtin_cp(argc, argv, envp, &Ctx);
 }
@@ -445,6 +450,7 @@
 	 * permissions on created directories when not using -p.
 	 */
-	mask = ~umask(0777);
-	umask(~mask);
+	mask = g_fUMask;
+	assert(mask == umask(mask));
+	mask = ~mask;
 
 	if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL)
Index: /trunk/src/kmk/kmkbuiltin/install.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/install.c	(revision 3388)
+++ /trunk/src/kmk/kmkbuiltin/install.c	(revision 3389)
@@ -396,7 +396,9 @@
 
 #ifdef KMK_BUILTIN_STANDALONE
+mode_t g_fUMask;
 int main(int argc, char **argv, char **envp)
 {
 	KMKBUILTINCTX Ctx = { "kmk_install", NULL };
+	umask(g_fUMask = umask(0077));
 	return kmk_builtin_install(argc, argv, envp, &Ctx);
 }
Index: /trunk/src/kmk/kmkbuiltin/mkdir.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/mkdir.c	(revision 3388)
+++ /trunk/src/kmk/kmkbuiltin/mkdir.c	(revision 3389)
@@ -49,4 +49,5 @@
 #include "err.h"
 #include <errno.h>
+#include <assert.h>
 #ifndef _MSC_VER
 # include <libgen.h>
@@ -80,4 +81,5 @@
 };
 
+extern mode_t g_fUMask;
 
 extern void * bsd_setmode(const char *p);
@@ -167,7 +169,9 @@
 
 #ifdef KMK_BUILTIN_STANDALONE
+mode_t g_fUMask;
 int main(int argc, char **argv, char **envp)
 {
     KMKBUILTINCTX Ctx = { "kmk_mkdir", NULL };
+    umask(g_fUMask = umask(0077));
     return kmk_builtin_mkdir(argc, argv, envp, &Ctx);
 }
@@ -240,10 +244,16 @@
 			 * instead of doing chmod's.
 			 */
-			oumask = umask(0);
+#ifdef KMK_BUILTIN_STANDALONE
+			oumask = umask(0077);
+#else
+			oumask = g_fUMask;
+			assert(oumask == umask(g_fUMask));
+#endif
 			numask = oumask & ~(S_IWUSR | S_IXUSR);
-			(void)umask(numask);
+			if (numask != oumask)
+			    (void)umask(numask);
 			first = 0;
 		}
-		if (last)
+		if (last && oumask != numask)
 			(void)umask(oumask);
 		if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
@@ -255,5 +265,6 @@
 					retval = 1;
 					break;
-				} else if (!S_ISDIR(sb.st_mode)) {
+				}
+				if (!S_ISDIR(sb.st_mode)) {
 					if (last)
 						errno = EEXIST;
@@ -274,5 +285,5 @@
 		    *p = '/';
 	}
-	if (!first && !last)
+	if (!first && !last && oumask != numask)
 		(void)umask(oumask);
 	return (retval);
Index: /trunk/src/kmk/kmkbuiltin/setmode.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/setmode.c	(revision 3388)
+++ /trunk/src/kmk/kmkbuiltin/setmode.c	(revision 3389)
@@ -100,4 +100,7 @@
 #endif /* !S_ISTXT */
 
+extern mode_t g_fUMask; /* Initialize in main() and keep up to date. */
+
+
 /*
  * Given the old mode and an array of bitcmd structures, apply the operations
@@ -223,5 +226,6 @@
 	(void)sigprocmask(SIG_BLOCK, &signset, &sigoset);
 #endif
-	(void)umask(mask = umask(0));
+	mask = g_fUMask;
+	assert(mask == umask(g_fUMask));
 	mask = ~mask;
 #ifndef _MSC_VER
Index: /trunk/src/kmk/main.c
===================================================================
--- /trunk/src/kmk/main.c	(revision 3388)
+++ /trunk/src/kmk/main.c	(revision 3389)
@@ -821,4 +821,9 @@
 struct output make_sync;
 
+#ifdef KMK
+/** Current umask() value. */
+mode_t g_fUMask = 0022;
+#endif
+
 
 
@@ -1769,4 +1774,9 @@
 #endif
 
+#ifdef KMK
+  /* Get the incoming umask so we don't have to modify it later to get it. */
+  umask(g_fUMask = umask(0077));
+#endif
+
 #ifdef CONFIG_NEW_WIN32_CTRL_EVENT
   /* bird: dispatch signals in our own way to try avoid deadlocks. */
Index: /trunk/src/kmk/makeint.h
===================================================================
--- /trunk/src/kmk/makeint.h	(revision 3388)
+++ /trunk/src/kmk/makeint.h	(revision 3389)
@@ -1189,2 +1189,6 @@
 #endif
 
+#ifdef KMK
+/* main.c */
+extern mode_t g_fUMask;
+#endif
