[armedbear-devel] run-program :environment nil

Pascal J. Bourguignon pjb at informatimago.com
Tue Mar 27 13:56:19 UTC 2012


The spam filter at tiger.common-lisp.net is wonky.

http://permalink.gmane.org/gmane.lisp.armedbear.devel/2244

"Pascal J. Bourguignon"
<pjb at informatimago.com> writes:

> Mark Evenson <evenson at panix.com> writes:
>
>> On Mar 26, 2012, at 6:12 PM, Pascal J. Bourguignon wrote:
>>
>>> 
>>> (lisp-implementation-version) --> "1.0.1"
>>> 
>>> 
>>> The documentation of extensions:run-program is misleading:
>>> 
>>>    :environment 
>>>        An alist of STRINGs (name . value) describing the new
>>>        environment. The default is to copy the environment of the current
>>>        process.
>>> 
>>> The alist doesn't describe the NEW environment, it is only MERGED into
>>> the current environment.
>>
>> […]
>>
>> Which behavior would you prefer?
>
> I agree that for usual programs, merging is useful.
> On the other hand, if you mess with the environment it's often for
> security considerations, and there it's better to start with a blank
> slate.
>
> I certainly expected that :environment '() provide an empty environment,
> just like execle/execvpe:
>
>      char* args[]={"env",0};
>      char* envv[]={0};
>      execpe("/bin/env",args,envv);
>
>
>> We certainly have imprecise documentation here.  The merged environment
>> behavior what is easiest with the underlying JVM API which is based
>> on the notion of UNIX exec().  In practice, I would venture that
>> that most people would expect the merged behavior, as it is the
>> common pattern for such wrappers around UNIX execv() and friends
>> which have to copy the environment anyways at an operating system
>> level before it replaces it with the new code.  (Ok, since every
>> contemporary OS probably has "copy-on-write" semantics here, I'll
>> stop making OS-dependent statements of doubtful utility).
>
> I like the following API, which is implemented in clisp.
>
> (getenv)        --> the current environment as an a-list.
>                     (("LC_CTYPE" . "C") ("TERM" . "/bin/bash") …)
>
> (getenv "TERM") --> the string value, or NIL if the variable is not
>                     present in the environment.
>                     "/bin/bash"
>
>
> (setf (getenv "LC_CTYPE") "en_US.UTF-8")  
>
>                     changes the environment for the current process and
>                     its future children. 
>
>
> (setf (getenv "LC_CTYPE") nil)
>
>                     removes the environment variable if it exists in the
>                     environment of the current process and its future
>                     children. 
>
>
> Then merging behavior for run-program would be obtained with:
>
>    (run-program … :environment (acons "TERM" "linux" (getenv)))
>
> Replacing behavior:
>
>    (run-program … :environment '(("TERM" . "linux") 
>                                  ("SHELL" . "/bin/bash")))
>
> and an empty environment can be provided:
>
>    (run-program … :environment '())
>
>
> run-program wouldn't change the environment of the current process.
>
>       (let ((env (getenv)))
>         (run-program … :environment other-env)
>         (set-equal env (getenv) :test 'equal))
>         ;; (there's no guarantee on the order of the environment).
>         
>                                         
>
>> I would advocate tightening the documentation.  If Pascal has a
>> further need here, I'll take a stab at a version which would somehow
>> "wipe" the inherited environment.
>>
>> Since the semantics of our EXT:RUN-PROGRAM implementation were
>> cribbed from SBCL's under the need to implement just as much as
>> ASDF2 required, we should analyze what SBCL does in this situation
>> as well.
>>
>>> Also, in a shell environment, an empty variable is not the same as an
>>> inexistant variable, so I cannot just loop over all the existing
>>> variables to set them to an empty string.  I see no
>>> SYSTEM::%PROCESS-BUILDER-ENV-REM function…
>>
>> This sounds like you really want the ability to constructs a clean
>> NEW environment.  If we were able to implement that, would your
>> need to iterate through existing variables disappear?
>
> For the specific purpose of calling run-program, yes.
> However, I think it's useful to be able to iterate thru existing
> variables.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.





More information about the armedbear-devel mailing list