os_getcwd(): do not realloc if there was no malloc().
[exim.git] / src / src / os.c
index 2b6f79c3fab66a24e121bb734e4194b0a5047d81..ca24e8dd27e47d42df5140e55de39cd0a072c6d8 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2016 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 #ifdef STAND_ALONE
@@ -833,38 +833,54 @@ os_get_dns_resolver_res(void)
 
 #endif /* OS_GET_DNS_RESOLVER_RES */
 
-
 /* ----------------------------------------------------------------------- */
 
 /***********************************************************
-*                 Time-related functions                   *
+*                 unsetenv()                               *
 ***********************************************************/
 
-/* At least Solaris, and probably others, don't have this */
+/* Most modern systems define int unsetenv(const char*),
+* some don't. */
+
+#if !defined(OS_UNSETENV)
+int
+os_unsetenv(const unsigned char * name)
+{
+return unsetenv((char *)name);
+}
+#endif
+
+/* ----------------------------------------------------------------------- */
 
-#ifndef _BSD_SOURCE
+/***********************************************************
+*               getcwd()                                   *
+***********************************************************/
 
-# include <time.h>
-# include <stdlib.h>
+/* Glibc allows getcwd(NULL, 0) to do auto-allocation. Some systems
+do auto-allocation, but need the size of the buffer, and others
+may not even do this. If the OS supports getcwd(NULL, 0) we'll use
+this, for all other systems we provide our own getcwd() */
 
-time_t
-timegm(struct tm * tm)
+#if !defined(OS_GETCWD)
+unsigned char *
+os_getcwd(unsigned char * buffer, size_t size)
 {
-time_t ret;
-char *tz;
-
-tz = getenv("TZ");
-setenv("TZ", "", 1);
-tzset();
-ret = mktime(tm);
-if (tz)
-  setenv("TZ", tz, 1);
-else
-  unsetenv("TZ");
-tzset();
-return ret;
+return (unsigned char *) getcwd((char *)buffer, size);
 }
+#else
+#ifndef PATH_MAX
+# define PATH_MAX 4096
+#endif
+unsigned char *
+os_getcwd(unsigned char * buffer, size_t size)
+{
+char * b = (char *)buffer;
 
+if (!size) size = PATH_MAX;
+if (!b && !(b = malloc(size))) return NULL;
+if (!(b = getcwd(b, size))) return NULL;
+return buffer ? buffer : realloc(b, strlen(b) + 1);
+}
 #endif
 
 /* ----------------------------------------------------------------------- */
@@ -872,7 +888,6 @@ return ret;
 
 
 
-
 /*************************************************
 **************************************************
 *             Stand-alone test program           *