The OpenBSD setenv permits non-POSIX key values--those containing "=" and the empty string.
The Ruby 1.8.7 and 1.9.3 packages in OpenBSD simply ignores this. At first I treated this as a harmless feature, but a serious issue has arisen. In Ruby 1.8.7, Ruby 1.9.3 and Rubinius on OpenBSD.
ENV[""]="abc" is perfectly acceptable in all three Ruby versions and introduces an environment variable whose name is the empty string.
ENV.clear does not clear the environment variables if one of them contains the empty string as a key. In Ruby 1.8.7 and Rubinius the environment variable whose key is the empty string remains in the environment while the others are deleted. In Ruby 1.9.3 ENV.clear throws an exception.
There are most likely also issues with keys containing "=".
I suggest that this should be handled in C code in OpenBSD by writing a POSIX-compatible wrapper around OpenBSD's setenv and unsetenv, and the change should be implemented at run time by using attach_function to the POSIX-compatible versions in kernel/platform/env.rb
The bug should also be fixed in Ruby 1.8.7 and Ruby 1.9.3, but that's a separate matter.
I have contacted other OpenBSD developers about this to see if they will consider changing the setenv/unsetenv implementations to make them more consistent/compliant. I'll update when I have more information.
The proper process to follow here is probably to go through MRI indeed first to see what their opinions on this are. I'm always hesitant about changing behavior from MRI in Rubinius, even if it can sometimes be dubious on MRI.
jeremyevans I imagine you have better contacts with the MRI developers and are much more familiar with OpenBSD. Unless you're very busy I'll leave the MRI bug report to you.
In the meantime I can issue a Rubinius patch to test compliance with the relevant MRI versions. I also have some POSIX wrappers in preparation, which I'll post on an my fork when it's ready. They're in C so they may be of use to the MRI team.
Incidentally can anyone help me on how to detect the platform in kernel/platform.env.rb so as to attach to the correct version of setenv? It seems to run in the bootstrap alpha so attempts to poll Rubinius::HOST and RUBY_PLATFORM fail.
I've kludged together some code for the wrappers. It's inexpertly plumbed in by creating a new predicate in the bootstrap ("Rubinius.openbsd?" ) because I don't know any other way to check at that stage. It passes the core/env tests with -X18, -X19 and -X20 (but MRI doesn't).
This bug will probably be fixed in OpenBSD sometime soon.
Okay. I'm still wading through bugs at the moment. Plenty more for me to do so I'll wait.
If OpenBSD will fix this, I feel that it's probably better to go with that and not add all this additional complexity to work around this. Especially if MRI doesn't do that either.
I've just committed the changes to OpenBSD to bring setenv(3) into POSIX compliance in this area.
Thanks. I look forward to running the code in snapshot soon!