Remove xmalloc.c, backport xalloc.h from tinc 1.1.
[tinc] / src / process.c
index 51c9e2a..bd85a80 100644 (file)
@@ -1,7 +1,7 @@
 /*
     process.c -- process management functions
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2013 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2015 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -47,11 +47,6 @@ extern bool use_logfile;
 static sigset_t emptysigset;
 #endif
 
-static void memory_full(int size) {
-       logger(LOG_ERR, "Memory exhausted (couldn't allocate %d bytes), exitting.", size);
-       exit(1);
-}
-
 /* Some functions the less gifted operating systems might lack... */
 
 #ifdef HAVE_MINGW
@@ -339,14 +334,50 @@ bool detach(void) {
 
        openlogger(identname, use_logfile?LOGMODE_FILE:(do_detach?LOGMODE_SYSLOG:LOGMODE_STDERR));
 
-       logger(LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d",
-                          VERSION, __DATE__, __TIME__, debug_level);
-
-       xalloc_fail_func = memory_full;
+       logger(LOG_NOTICE, "tincd %s starting, debug level %d",
+                          VERSION, debug_level);
 
        return true;
 }
 
+#ifdef HAVE_PUTENV
+void unputenv(char *p) {
+       char *e = strchr(p, '=');
+       if(!e)
+               return;
+       int len = e - p;
+#ifndef HAVE_UNSETENV
+#ifdef HAVE_MINGW
+       // Windows requires putenv("FOO=") to unset %FOO%
+       len++;
+#endif
+#endif
+       char var[len + 1];
+       memcpy(var, p, len);
+       var[len] = 0;
+#ifdef HAVE_UNSETENV
+       unsetenv(var);
+#else
+       // We must keep what we putenv() around in memory.
+       // To do this without memory leaks, keep things in a list and reuse if possible.
+       static list_t list = {};
+       for(list_node_t *node = list.head; node; node = node->next) {
+               char *data = node->data;
+               if(!strcmp(data, var)) {
+                       putenv(data);
+                       return;
+               }
+       }
+       char *data = xstrdup(var);
+       list_insert_tail(&list, data);
+       putenv(data);
+#endif
+}
+#else
+void putenv(const char *p) {}
+void unputenv(const char *p) {}
+#endif
+
 bool execute_script(const char *name, char **envp) {
 #ifdef HAVE_SYSTEM
        char *scriptname;
@@ -386,12 +417,10 @@ bool execute_script(const char *name, char **envp) {
 
        ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name);
 
-#ifdef HAVE_PUTENV
        /* Set environment */
        
        for(i = 0; envp[i]; i++)
                putenv(envp[i]);
-#endif
 
        scriptname[len - 1] = '\"';
        status = system(scriptname);
@@ -400,15 +429,8 @@ bool execute_script(const char *name, char **envp) {
 
        /* Unset environment */
 
-       for(i = 0; envp[i]; i++) {
-               char *e = strchr(envp[i], '=');
-               if(e) {
-                       char p[e - envp[i] + 1];
-                       strncpy(p, envp[i], e - envp[i]);
-                       p[e - envp[i]] = '\0';
-                       putenv(p);
-               }
-       }
+       for(i = 0; envp[i]; i++)
+               unputenv(envp[i]);
 
        if(status != -1) {
 #ifdef WEXITSTATUS