Hi, in luastuff.c we have static int os_setenv (lua_State *L) { char *value, *key, *val; key = (char *)luaL_optstring(L, 1, NULL); val = (char *)luaL_optstring(L, 2, NULL); if (key) { if (val) { value = xmalloc(strlen(key)+strlen(val)+2); sprintf(value,"%s=%s",key,val); if (putenv(value)) { return luaL_error(L, "unable to change environment"); } } else { #if defined(WIN32) || defined(__sun__) value = xmalloc(strlen(key)+2); sprintf(value,"%s=",key); if (putenv(value)) { return luaL_error(L, "unable to change environment"); } #else (void)unsetenv(key); #endif } } lua_pushboolean (L, 1); return 1; } Now putenv is not required by Posix, as opposed to setenv. The main rationale for "putenv" is that it leaves memory management of the string to the application, and thus can avoid leaking memory. However, the above code just uses xmalloc without deallocating previously set values, so it leaks, anyway. Basically I see two ways of dealing with this: a) maintain a table of key -> "key=value" mappings for environment variables that have been set by Lua. That way, one can keep track of what strings need to stay allocated, and which can be deallocated again. b) don't bother about the leak and use setenv instead. Option b) would be somewhat more portable, I believe. Of course, if people actually use os_setenv to switch around between environment variables frequently, the leak might get annoying at some point of time. -- David Kastrup
Taco Hoekwater
Hi David,
b) don't bother about the leak and use setenv instead.
Option b) would be somewhat more portable, I believe.
Rationale: it is not more portable, because win32 doesn't have it (and Solaris is unknown).
Great. The posixified manual page for "setenv" says this on Ubuntu: RATIONALE Unanticipated results may occur if setenv() changes the external variable environ. In particular, if the optional envp argument to main() is present, it is not changed, and thus may point to an obsolete copy of the environment (as may any other copy of environ). However, other than the aforementioned restriction, the developers of IEEE Std 1003.1-2001 intended that the traditional method of walking through the environment by way of the environ pointer must be supported. It was decided that setenv() should be required by this revision because it addresses a piece of missing functionality, and does not impose a significant burden on the implementor. There was considerable debate as to whether the System V putenv() function or the BSD setenv() function should be required as a mandatory function. The setenv() function was chosen because it permitted the implementation of the unsetenv() function to delete environmental variables, without specifying an additional interface. The putenv() function is available as an XSI extension. So it would appear that Posix chose to standardize one interface, and win32 picked another (the term "standardize" does not apply here really). Anyway, option a) presumably also would require to place the table keeping score of environment variables into Lua context 0, in order to make sure that it remains available until LuaTeX exits. -- David Kastrup
Anyway, option a) presumably also would require to place the table keeping score of environment variables into Lua context 0, in order to make sure that it remains available until LuaTeX exits.
There is an os.env table already, but it is initialized only once. In any case, I will probably move to the 'ex' interface soon instead of my own code+LuaFileSystem: http://lua-users.org/wiki/ExtensionProposal Best wishes, Taco
Taco Hoekwater
Anyway, option a) presumably also would require to place the table keeping score of environment variables into Lua context 0, in order to make sure that it remains available until LuaTeX exits.
There is an os.env table already, but it is initialized only once. In any case, I will probably move to the 'ex' interface soon instead of my own code+LuaFileSystem:
Well, one probably needs to wait at least until the namespace question discussed on that page has been cleared. A good security model will probably remain an area good for headaches. -- David Kastrup
Arthur Reutenauer
[setenv]
Rationale: it is not more portable, because win32 doesn't have it (and Solaris is unknown).
No, Solaris doesn't have it either.
That's the great thing about standards. People can agree on the best thing to do, and then ignore it. Sorry, I just assumed from reading the Posix manpage for that functionality that one could expect setenv but not putenv in general. Maybe there are strict Posix systems without XSI (?) around, in which case one would need to use setenv. Perhaps a case for autoconf? -- David Kastrup
Hi, David Kastrup wrote:
Arthur Reutenauer
writes: [setenv]
Rationale: it is not more portable, because win32 doesn't have it (and Solaris is unknown). No, Solaris doesn't have it either.
That's the great thing about standards. People can agree on the best thing to do, and then ignore it.
Sorry, I just assumed from reading the Posix manpage for that functionality that one could expect setenv but not putenv in general.
Maybe there are strict Posix systems without XSI (?) around, in which case one would need to use setenv.
That is true, we just haven't found one yet.
Perhaps a case for autoconf?
I much prefer to have a target-specific compiles via the makefile, like lua itself does. Autotools is a disaster unless you are willing to ignore all commercial platforms (including quite a few unices). But I have not gotten around to setting that up, so for the moment I simply write adhoc code with a few ifdefs. Taco
Taco Hoekwater
David Kastrup wrote:
Maybe there are strict Posix systems without XSI (?) around, in which case one would need to use setenv.
That is true, we just haven't found one yet.
Perhaps a case for autoconf?
I much prefer to have a target-specific compiles via the makefile, like lua itself does. Autotools is a disaster unless you are willing to ignore all commercial platforms (including quite a few unices).
Hm? The GNU stuff is portable across a lot of platforms, not least because of using autoconf.
But I have not gotten around to setting that up, so for the moment I simply write adhoc code with a few ifdefs.
The problem with the ifdefs is that the person writing a particular line of code rarely has access to the dozen or more platforms where it might need to run on. So he does not necessarily know what to put in that ifdef. Autoconf might not be the prettiest system around, but as far as I can see, it does its job. -- David Kastrup
Sorry, I just assumed from reading the Posix manpage for that functionality that one could expect setenv but not putenv in general.
Here I was speaking of Solaris 9 (dating back to 1999), I have yet to check for Solaris 10, but the setenv problem has always been around and it's an annoyance.
Here I was speaking of Solaris 9 (dating back to 1999), I have yet to check for Solaris 10
Solaris 10 has setenv and is POSIX.1-2001 compliant (see http://docs.sun.com/app/docs/doc/816-5168/6mbb3hrr3?a=view for setenv and http://docs.sun.com/app/docs/doc/816-5175/6mbba7f3i?a=view for an overview of the standards Solaris conform to).
participants (3)
-
Arthur Reutenauer
-
David Kastrup
-
Taco Hoekwater