diff --git a/basis/environment/environment-docs.factor b/basis/environment/environment-docs.factor index 0bf7f2a11f..fee30fa8a6 100644 --- a/basis/environment/environment-docs.factor +++ b/basis/environment/environment-docs.factor @@ -54,10 +54,18 @@ HELP: os-envs HELP: set-os-envs { $values { "assoc" "an association mapping strings to strings" } } { $description "Replaces the current set of environment variables." } +{ $warning "Leaks memory on Unix. If your program calls this function repeatedly, call " { $link set-os-envs-pointer } " with a malloced pointer and manage your memory instead." } { $notes "Names and values of environment variables are operating system-specific. Windows NT allows values up to 32766 characters in length." } ; +HELP: set-os-envs-pointer +{ $values { "malloc" "a pointer to memory from the heap obtained through " { $link malloc } " or similar" } } +{ $description "Set then " { $link environ } " pointer. Factor must retain a pointer to this memory until exiting the program." } +{ $notes + "Names and values of environment variables are operating system-specific." +} ; + HELP: set-os-env { $values { "value" string } { "key" string } } { $description "Set an environment variable." } @@ -72,7 +80,7 @@ HELP: unset-os-env "Names and values of environment variables are operating system-specific." } ; -{ os-env os-envs set-os-env unset-os-env set-os-envs change-os-env } related-words +{ os-env os-envs set-os-env unset-os-env set-os-envs set-os-envs-pointer change-os-env } related-words ARTICLE: "environment" "Environment variables" @@ -88,6 +96,10 @@ ARTICLE: "environment" "Environment variables" unset-os-env set-os-envs change-os-env +} +"Leak-free setting of all environment variables on Unix:" +{ $subsections + set-os-envs-pointer } ; ABOUT: "environment" diff --git a/basis/environment/environment.factor b/basis/environment/environment.factor index ef94a32f90..92859349b7 100644 --- a/basis/environment/environment.factor +++ b/basis/environment/environment.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: assocs combinators kernel sequences splitting system -vocabs init vocabs.loader ; +USING: assocs combinators init kernel sequences splitting +system vocabs vocabs.loader ; IN: environment HOOK: os-env os ( key -- value ) @@ -14,6 +14,8 @@ HOOK: (os-envs) os ( -- seq ) HOOK: (set-os-envs) os ( seq -- ) +HOOK: set-os-envs-pointer os ( malloc -- ) + : change-os-env ( key quot -- ) [ [ os-env ] keep ] dip dip set-os-env ; inline diff --git a/basis/environment/unix/unix.factor b/basis/environment/unix/unix.factor index ba9d54a42d..94177913c1 100644 --- a/basis/environment/unix/unix.factor +++ b/basis/environment/unix/unix.factor @@ -21,8 +21,10 @@ M: unix (os-envs) ( -- seq ) : set-void* ( value alien -- ) 0 set-alien-cell ; +M: unix set-os-envs-pointer ( malloc -- ) environ set-void* ; + M: unix (set-os-envs) ( seq -- ) - utf8 strings>alien malloc-byte-array environ set-void* ; + utf8 strings>alien malloc-byte-array set-os-envs-pointer ; os { { macosx [ "environment.unix.macosx" require ] }