Merge with git+ssh://hera.kernel.org/pub/scm/libs/klibc/klibc.git
diff --git a/include/stdlib.h b/include/stdlib.h
index 17efc30..487bcda 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -47,6 +47,7 @@
 __extern int putenv(const char *);
 __extern int setenv(const char *, const char *, int);
 __extern int unsetenv(const char *);
+__extern int clearenv(void);
 
 __extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
 
diff --git a/klibc/Makefile b/klibc/Makefile
index bf32f7c..f7b8ac5 100644
--- a/klibc/Makefile
+++ b/klibc/Makefile
@@ -41,6 +41,7 @@
 	  gethostname.o getdomainname.o getcwd.o \
 	  seteuid.o setegid.o \
 	  getenv.o setenv.o putenv.o __put_env.o unsetenv.o \
+	  clearenv.o nullenv.o \
 	  getopt.o readdir.o \
 	  syslog.o closelog.o pty.o getpt.o isatty.o reboot.o \
 	  time.o utime.o llseek.o nice.o getpriority.o \
diff --git a/klibc/__put_env.c b/klibc/__put_env.c
index 7e55f2c..8ee12e9 100644
--- a/klibc/__put_env.c
+++ b/klibc/__put_env.c
@@ -6,18 +6,23 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include "env.h"
 
-/* Initialized to zero, meaning "not malloc'd" */
 static size_t __environ_size;
+static char **__environ_alloc;
 
 /* str should be a duplicated version of the input string;
    len is the length of the key including the = sign */
 int __put_env(char *str, size_t len, int overwrite)
 {
+  static char * const null_environ = { NULL };
   char **p, *q;
   char **newenv;
   size_t n;
 
+  if ( !environ )
+    environ = (char **)null_environ;
+
   n = 1;			/* Include space for final NULL */
   for ( p = environ ; (q = *p) ; p++ ) {
     n++;
@@ -30,14 +35,19 @@
     }
   }
 
+  if ( __environ_alloc && environ != __environ_alloc ) {
+    free(__environ_alloc);
+    __environ_alloc = NULL;
+  }
+
   /* Need to extend the environment */
   if ( n < __environ_size ) {
     p[1] = NULL;
     *p = str;
     return 0;
   } else {
-    if ( __environ_size ) {
-      newenv = realloc(environ, (__environ_size << 1)*sizeof(char *));
+    if ( __environ_alloc ) {
+      newenv = realloc(__environ_alloc, (__environ_size << 1)*sizeof(char *));
       if ( !newenv )
 	return -1;
 
diff --git a/klibc/clearenv.c b/klibc/clearenv.c
new file mode 100644
index 0000000..036b20f
--- /dev/null
+++ b/klibc/clearenv.c
@@ -0,0 +1,17 @@
+/*
+ * clearenv.c
+ *
+ * Empty the environment
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "env.h"
+
+/* Note: if environ has been malloc'd, it will be freed on the next
+   setenv() or putenv() */
+int clearenv(void)
+{
+  environ = (char **)__null_environ;
+  return 0;
+}
diff --git a/klibc/env.h b/klibc/env.h
new file mode 100644
index 0000000..8c70f94
--- /dev/null
+++ b/klibc/env.h
@@ -0,0 +1,10 @@
+#ifndef ENV_H
+#define ENV_H
+
+/* str should be a duplicated version of the input string;
+   len is the length of the key including the = sign */
+int __put_env(char *str, size_t len, int overwrite);
+
+extern char * const __null_environ[];
+
+#endif
diff --git a/klibc/getenv.c b/klibc/getenv.c
index 84fc94c..b90cb48 100644
--- a/klibc/getenv.c
+++ b/klibc/getenv.c
@@ -11,6 +11,9 @@
   char **p, *q;
   int len = strlen(name);
 
+  if ( !environ )
+    return NULL;
+
   for ( p = environ ; (q = *p) ; p++ ) {
     if ( !strncmp(name, q, len) && q[len] == '=' ) {
       return q+(len+1);
diff --git a/klibc/nullenv.c b/klibc/nullenv.c
new file mode 100644
index 0000000..ba7e71c
--- /dev/null
+++ b/klibc/nullenv.c
@@ -0,0 +1,8 @@
+/*
+ * nullenv.c
+ */
+
+#include <stddef.h>
+#include "env.h"
+
+char * const __null_environ[] = { NULL };
diff --git a/klibc/putenv.c b/klibc/putenv.c
index 8138c65..3274fce 100644
--- a/klibc/putenv.c
+++ b/klibc/putenv.c
@@ -6,10 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-
-/* str should be a duplicated version of the input string;
-   len is the length of the key including the = sign */
-int __put_env(char *str, size_t len, int overwrite);
+#include "env.h"
 
 int putenv(const char *str)
 {
diff --git a/klibc/setenv.c b/klibc/setenv.c
index d4ada53..b149954 100644
--- a/klibc/setenv.c
+++ b/klibc/setenv.c
@@ -6,10 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-
-/* str should be a duplicated version of the input string;
-   len is the length of the key including the = sign */
-int __put_env(char *str, size_t len, int overwrite);
+#include "env.h"
 
 int setenv(const char *name, const char *val, int overwrite)
 {
diff --git a/klibc/unsetenv.c b/klibc/unsetenv.c
index 5f39f3d..61bd75f 100644
--- a/klibc/unsetenv.c
+++ b/klibc/unsetenv.c
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include "env.h"
 
 int unsetenv(const char *name)
 {
@@ -27,6 +28,9 @@
     }
   }
 
+  if ( !environ )
+    return 0;
+
   for ( p = environ ; (q = *p) ; p++ ) {
     if ( !strncmp(name,q,len) && q[len] == '=' )
       break;