From: Jason Stewart (res0054p_at_[hidden])
Date: 2002-01-23 17:45:52
>Nope, putenv is POSIX, and _should_ work the same everywhere (ie the
>string is placed as is into the environment, so that further
>modifications to the same string modify the environment directly).
>Neither setenv and unsetenv are POSIX, although now you mention it
>having an explicit "unset" function (as opposed to calling set with
>an empty string) is probably a good idea). The problem with using
>SetEnviromentVariable directly is that future calls to getenv() won't
>pick it up, and the getenv() may be in a library you have no control
>over. putenv/getenv under VC (you don't need the underscore btw)
>both update the CRT environment and the "OS" environment. I don't
>know how well putenv/getenv are supported by other Windows compilers
>(or for macintosh - VC's putenv source is commented out for Mac).
Sorry, I looked it up in MSDN one time and it only speaks of _putenv and
says it is not ANSI. However, grepping in the header files shows it is
there. I did a (admitedly quick) search on the web for setenv and it looked
like it was posix but not ANSI. If you use SetEnvironmentVariable on Win32
you must use GetEnvironmentVariable. It avoids the allocation problem and
the threading problem that putenv have. When I was looking at the problem
when I first wrote my implementation of Environment I couldn't see how to
handle the fact that putenv actually used a pointer to the string you
passed it instead of a copy of the string. Now that I've seen yours its
obvious, you just have to solve the thread issue portably.
Actually variable expansion needs to be offered "standalone" as it
>were - you should be able to expand any string, regardless of whether
>it comes from the environment or not. It's probably worth having it
>support both %...% and $ (parentheses optional) according to certain
>flags (that would default to %...% under Win32 and $ elsewhere).
My code does support both. There are system wide settings for the start and
end delimiters (although maybe it should be per call instead of system
wide). The code might could be prettier but it does work, including
multiply nested variables.
> I agree totally. The problem is that the C++ standards committee
>want to keep C++ suitable for an operating system with as few
>requirements as possible - assuming the existence of environment
>variables would add an extra requirement. But this isn't really
>fair, just because an OS doesn't have native support for environment
>variables doens't mean you can't implement 'env' with sensible
My understanding is that some embedded systems don't even have files! How
do they get around that?
>Anyway I think boost is a good place for things that rely on OS-
>support that the C++ isn't happy about assuming exists (for instance
>the dir_it stuff really needs to be finalised. C++ itself doesn't
>assume OS's even have directories). All POSIX functionality, in
>particular, I think needs to be wrapped up in a recognised C++
>library. I've been doing this a bit recently (so far I've done
>glob, dlopen/sym/close and getenv/putenv. exec() is probably the
>next one on my list, although hiding the difference between fork+exec
>() and CreateProcess is going to be the main challenge!).
I'll let you tackle the fork+exec problem, I don't usually need that
functionality since I am mainly a Windows programmer who occasionally ports
stuff to Unix I have never used fork outside of a classroom (I'm not saying
its not useful, just that I've never thought to use it). The directory
iteration stuff I have done before. I wrote one similar to dir_it except
that it used my own Filename class instead of strings and didn't handle
properties as well. I want to extend it though because every time I use it
I want to recurse all directories so I've been thinking about making it
recurse internally. Then I could write a simple loop to deal with "all
matching files at this directory or below".