[armedbear-devel] run-program :environment nil

Pascal J. Bourguignon pjb at informatimago.com
Tue Mar 27 13:42:17 UTC 2012


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