It has a memory leak which I think I've tracked down to tzload, which I call via tzset.
The data that's mallocated by the time zone stuff in SunOS 4.x is: the array of transition times; the array of information about the State Of The Time Zone after a given transition time (offset from GMT, DST or not, index into the list of time zone abbreviation strings, etc.); the array of time zone types (indices into the array of information about the State Of The Time Zone after a given transition time); the array of "char"s that contains the aforementioned abbreviation strings. Applications can't get a pointer to any of the first three items, so they can be freed whenever "tzset()" is called. However, it appears that the array containing abbreviation strings isn't freed because, according to the comment, it "might have other references to it", presumably obtained by using the "tzname[]" array (in the SV environment) or by using the "tm_zone" member of "struct tm". Now, from the way I read POSIX 1003.1, it neither commits to pointers fetched from "tzname[]" remaining valid after a call to "tzset()", nor explicitly claims that one should *not* assume they'll still point somewhere valid. The "ctime" manual page *does*, however, explicitly note that calls to "tzset()" or "tzsetwall()" overwrite the array to which the "tm_zone" field points. So I'm not sure what provoked somebody to make "tzset()" *not* free up the abbreviation-strings array - which is kind of annoying, given that I'd be willing to bet I'm the person who made it not do so, and seem to remember having done so because some stupid piece of software broke when it *did* free it.... Unfortunately, the pointer to that array is in a structure pointed to by a static pointer. However, *if* you can call "localtime()" on a time that's known to be in a time zone that corresponds to the first abbreviation in the file - possibly easier said than done, although you might try passing it first a pointer to a value of -1, and then a pointer to a value of "-1 plus half a year", and then, for each of the times, if "localtime()" doesn't return a null pointer, save the "tm_zone" values and, if both of them are non-NULL, see which one is lower - you can try doing a "free()" on the "tm_zone" value for that time zone. This is a somewhat disgusting hack, but, well, that's life....
participants (1)
-
guy@auspex.com