summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorTim Bunce <Tim.Bunce@ig.co.uk>1997-06-11 12:00:00 +1200
committerTim Bunce <Tim.Bunce@ig.co.uk>1997-06-11 12:00:00 +1200
commit3e3baf6d63945cb64e829d6e5c70a7d00f3d3d03 (patch)
tree0143be655536dc428f4fa3cc7d01f6bcffe14c01 /util.c
parent08aa1457cd52a368c210ab76a3da91cfadabea1a (diff)
parent3458556dd685b1767b760a72bd2e9007b5c4575e (diff)
downloadperl-3e3baf6d63945cb64e829d6e5c70a7d00f3d3d03.tar.gz
[differences between cumulative patch application and perl5.004_01]perl-5.004_01
[editor's note: The changes between this and 5.004 were processed from the m1t2 release, which was a bad idea as it was the _01 release which had the final corrected attributions. The differences between the various m*t* releases do that; I considered it most valuable just to look at the _NN releases. Many patches have been separated out and/or applied from the p5p archives nonetheless.]
Diffstat (limited to 'util.c')
-rw-r--r--util.c107
1 files changed, 76 insertions, 31 deletions
diff --git a/util.c b/util.c
index fc245836d0..99eb7e0bd5 100644
--- a/util.c
+++ b/util.c
@@ -1334,7 +1334,7 @@ warn(pat,va_alist)
}
#ifndef VMS /* VMS' my_setenv() is in VMS.c */
-#ifndef _WIN32
+#ifndef WIN32
void
my_setenv(nam,val)
char *nam, *val;
@@ -1382,6 +1382,74 @@ char *nam, *val;
#endif /* MSDOS */
}
+#else /* if WIN32 */
+
+void
+my_setenv(nam,val)
+char *nam, *val;
+{
+
+#ifdef USE_WIN32_RTL_ENV
+
+ register char *envstr;
+ STRLEN namlen = strlen(nam);
+ STRLEN vallen;
+ char *oldstr = environ[setenv_getix(nam)];
+
+ /* putenv() has totally broken semantics in both the Borland
+ * and Microsoft CRTLs. They either store the passed pointer in
+ * the environment without making a copy, or make a copy and don't
+ * free it. And on top of that, they dont free() old entries that
+ * are being replaced/deleted. This means the caller must
+ * free any old entries somehow, or we end up with a memory
+ * leak every time my_setenv() is called. One might think
+ * one could directly manipulate environ[], like the UNIX code
+ * above, but direct changes to environ are not allowed when
+ * calling putenv(), since the RTLs maintain an internal
+ * *copy* of environ[]. Bad, bad, *bad* stink.
+ * GSAR 97-06-07
+ */
+
+ if (!val) {
+ if (!oldstr)
+ return;
+ val = "";
+ vallen = 0;
+ }
+ else
+ vallen = strlen(val);
+ New(904, envstr, namlen + vallen + 3, char);
+ (void)sprintf(envstr,"%s=%s",nam,val);
+ (void)putenv(envstr);
+ if (oldstr)
+ Safefree(oldstr);
+#ifdef _MSC_VER
+ Safefree(envstr); /* MSVCRT leaks without this */
+#endif
+
+#else /* !USE_WIN32_RTL_ENV */
+
+ /* The sane way to deal with the environment.
+ * Has these advantages over putenv() & co.:
+ * * enables us to store a truly empty value in the
+ * environment (like in UNIX).
+ * * we don't have to deal with RTL globals, bugs and leaks.
+ * * Much faster.
+ * Why you may want to enable USE_WIN32_RTL_ENV:
+ * * environ[] and RTL functions will not reflect changes,
+ * which might be an issue if extensions want to access
+ * the env. via RTL. This cuts both ways, since RTL will
+ * not see changes made by extensions that call the Win32
+ * functions directly, either.
+ * GSAR 97-06-07
+ */
+ SetEnvironmentVariable(nam,val);
+
+#endif
+}
+
+#endif /* WIN32 */
+
I32
setenv_getix(nam)
char *nam;
@@ -1389,41 +1457,18 @@ char *nam;
register I32 i, len = strlen(nam);
for (i = 0; environ[i]; i++) {
- if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
+ if (
+#ifdef WIN32
+ strnicmp(environ[i],nam,len) == 0
+#else
+ strnEQ(environ[i],nam,len)
+#endif
+ && environ[i][len] == '=')
break; /* strnEQ must come first to avoid */
} /* potential SEGV's */
return i;
}
-#else /* if _WIN32 */
-
-void
-my_setenv(nam,val)
-char *nam, *val;
-{
- register char *envstr;
- STRLEN namlen = strlen(nam);
- STRLEN vallen = strlen(val ? val : "");
-
- New(904, envstr, namlen + vallen + 3, char);
- (void)sprintf(envstr,"%s=%s",nam,val);
- if (!vallen) {
- /* An attempt to delete the entry.
- * We try to fix a Win32 process handling goof: Children
- * of the current process will end up seeing the
- * grandparent's entry if the current process has never
- * modified the entry being deleted. So we call _putenv()
- * twice: once to pretend to modify the entry, and the
- * second time to actually delete it. GSAR 97-03-19
- */
- envstr[namlen+1] = 'X'; envstr[namlen+2] = '\0';
- (void)_putenv(envstr);
- envstr[namlen+1] = '\0';
- }
- (void)_putenv(envstr);
-}
-
-#endif /* _WIN32 */
#endif /* !VMS */
#ifdef UNLINK_ALL_VERSIONS