Boost logo

Boost :

Subject: Re: [boost] Environment Variables Library?
From: Michael Ainsworth (michael_at_[hidden])
Date: 2015-05-21 06:59:36


> On 21 May 2015, at 2:07 pm, Bjørn Roald <bjorn_at_[hidden]> wrote:
>
> <snip>

Hi Bjorn,

Thank you for a well thought out response. I appreciate the time you’ve given it.

> I think at least the primary purposes should be in the standard. So why not start with a small Boost library that as a minimum provide that, try out the response on this list then extend services based on demand and your preferences.

I agree.

> I am surprised of the focus by others on why environment variables are bad or out of fashion in some environments. While this may be true, I think it is rather irrelevant. Environment variables are a useful service provided in the runtime environment of C++ programs and should be standardized. Posix sadly does not reach all C++ programs, so it would be useful to have similar facilities inn the C++ standard.

While I agree with others that the use and appropriateness of environment variables varies across systems, I think it’s still common enough to warrant such a library, especially given that ISO standard C++ provides a partial implementation (e.g., std::getenv in <cstdlib>, but not ::unsetenv, ::setenv, etc, which are found in <unistd.h>).

> However, note that Posix setenv(...) and Windows SetEnvironmentVariable(...) does not pollute the global system or user environment. They do not have global side effects outside the process or possibly its subsequently created child processes. Thus processes (C++ programs) provides a sort of scope for environment variables.

That’s a good point, which I hadn’t considered.

> Arguments that what we normally need is simple enough with Posix or Windows APIs just hints that this may be simple to to provide as standardized facilities so it become trivial to write portable standard C++ code using environment variables with no #ifdefs or other ugliness. It may prove to be less simple than we expect, multi-byte characters and OS size limitations comes to my mind as obstacles, but I think this is worth trying out.

I agree. The library would be rather small but it would encourage DRY principles and be cross-platform (to the extent that systems are supported).

> The facilities for manipulating the environment for child processes may be a better fit for a separate library, e.g. Boost.Process, but there may be a case for something simple in the proposed library that can be managed in the process and passed when creating child processes as alternative to inheriting the current environment.

1. You might be right, but my first instinct was that environment variables and processes “fit” together.
2. On the other hand, a process management library (a Boost.Process revision?) that made use of the environment variable library would create a library dependency.

> One facility that could be nice is portable methods to convert environment variable values into basic types as well as some more complex types, in particular file system path and a sequence of file system paths come to my mind. E.g.:
>
> namespace env = boost::environment;
> namespace fs = boost::filesystem;
> std::vector<fs::path> paths = env::get_filesystem_paths("PATH");
> fs::path home = env::get("HOME");
> if(fs::is_directory(home))
> {
> paths.push_back(home / "bin";
> env::set_filesystem_paths("PATH", paths);
> }

The same arguments we’ve raised regarding the integration of environment-variables/processes would also apply here. That is:

Filesystems are logically independent on environment variables - the only commonality is the use of strings to denote file system locations (e.g., $PATH or %PATH%).
Integrating the two creates an (IMO) unnecessary dependency.

I do like the idea of providing dedicated functions for specific environment variables. For example, “boost::environment::get_path()”.

Regarding the PATH variable (and other “array-like” character-delimited environment variables), I was thinking of implementing this with iterators. For example:

namespace env = boost::environment;
environment& current = env::current_environment();

env::variable& path = current.get(“PATH”);
for (env::variable::iterator it = path.begin(), end = path.end(); it != end; ++it) {
    std::cout << *it << std::endl;
}

// Possible output:
// /bin
// /usr/bin
// /usr/local/bin
// /root/bin

path += "/var/lib/pgsql-9.4/bin";

> Beyond the simple generic handling of environment variables above, a library could provide truly portable accessors to some system wide and user environment settings. This may deal with variable name variations, and recommended use of platform API for each runtime environment, see:
>
> http://en.wikipedia.org/wiki/Environment_variable <http://en.wikipedia.org/wiki/Environment_variable>

Agreed. I thought of accessing other “environment” variables as well, such as the operating system category, name and version (e.g., “windows”, “Windows XP” and “Windows XP Service Pack 3 Build 12345”).

Once again, thank you for your time in thinking the matter over.

Michael.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk