summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-03-08 06:16:41 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-03-08 06:16:41 -0800
commit685786b3715e984fb37929dfac9891924f60d811 (patch)
treef5d543f87ec7ad22d5c1f7d28b6927d6d6931932
parentd61e8cacdaea0235f564a7e966c5742bc1f010d8 (diff)
downloadtxr-685786b3715e984fb37929dfac9891924f60d811.tar.gz
txr-685786b3715e984fb37929dfac9891924f60d811.tar.bz2
txr-685786b3715e984fb37929dfac9891924f60d811.zip
Allow nil value in setenv.
* sysif.c (setenv_wrap): If value is nil, and overwrite is missing or t, call unsetenv. * txr.1: Documented.
-rw-r--r--sysif.c8
-rw-r--r--txr.146
2 files changed, 51 insertions, 3 deletions
diff --git a/sysif.c b/sysif.c
index 3b8341cc..d0a06ca0 100644
--- a/sysif.c
+++ b/sysif.c
@@ -703,8 +703,12 @@ val getenv_wrap(val name)
static val setenv_wrap(val name, val value, val overwrite)
{
char *nameu8 = utf8_dup_to(c_str(name));
- char *valu8 = utf8_dup_to(c_str(value));
- setenv(nameu8, valu8, default_arg(overwrite, t) != nil);
+ char *valu8 = value ? utf8_dup_to(c_str(value)) : 0;
+ int ovw = default_arg(overwrite, t) != nil;
+ if (valu8)
+ setenv(nameu8, valu8, ovw);
+ else if (ovw)
+ unsetenv(nameu8);
free(valu8);
free(nameu8);
return value;
diff --git a/txr.1 b/txr.1
index fd4dd621..5d817140 100644
--- a/txr.1
+++ b/txr.1
@@ -35353,6 +35353,19 @@ function creates or modifies the environment variable indicated by
The
.meta value
string argument specifies the new value for the variable.
+If
+.meta value
+is
+.codn nil ,
+then
+.code setenv
+behaves like
+.codn unsetenv ,
+except that it observes the
+.meta overwrite-p
+argument. That is to say, the meaning of a null
+.meta value
+is that the variable is to be removed.
If the
.meta overwrite-p
@@ -35366,11 +35379,22 @@ effectively giving rise to a two-argument form of
.code setenv
which creates or overwrites environment variables.
+A variable removal is deemed to be an overwrite.
+Thus if both
+.meta value
+and
+.meta overwrite-p
+are
+.codn nil ,
+then
+.code setenv
+does nothing.
+
The
.code setenv
function unconditionally returns
.meta value
-regardless of whether or not it overwrites an existing variable.
+regardless of whether or not it overwrites or removes an existing variable.
The
.code unsetenv
@@ -35380,6 +35404,26 @@ specified by
if it exists. On some platforms, it instead sets the environment variable
to the empty string.
+Note: supporting removal semantics in
+.code setenv
+allows for the following simple save/modify/restore pattern:
+
+.cblk
+ (let* ((old-val (getenv "SOME-VAR")))
+ (unwind-protect
+ (progn (setenv "SOME-VAR" new-val)
+ ...)
+ (setenv "SOME-VAR" old-val)))
+.cble
+
+This works in the case when
+.code SOME-VAR
+exists, as well as in the case that it doesn't exist.
+In both cases, its previous value or, respectively, non-existence,
+is restored by the
+.code unwind-protect
+cleanup form.
+
.SS* System Programming
.coNP Accessor @ errno
.synb