timegm() function and state
One of my users reported that the first time timegm() is called, it returns -1. Investigating, it seems that there's a problem with the gmtptr state. Take the following code: int main(int argc, char *argv[]) { struct tm localt; localt.tm_sec = 0; localt.tm_min = 0; localt.tm_hour = 0; localt.tm_mday = 1; localt.tm_year = 113; localt.tm_mon = 0; localt.tm_wday = 0; localt.tm_yday = 0; localt.tm_isdst = 0; localt.tm_gmtoff = 0; localt.tm_zone = 0; mktime(&localt); printf("asctime: %s", asctime(&localt)); printf("timegm(&localt) = %d (errno %s)\n", timegm(&localt), strerror(errno)); printf("timegm(&localt) = %d (errno %s)\n", timegm(&localt), strerror(errno)); printf("timegm(&localt) = %d (errno %s)\n", timegm(&localt), strerror(errno)); return 0; } Run it and you get: asctime: Tue Jan 1 00:00:00 2013 timegm(&localt) = -1 (errno No such process) timegm(&localt) = 1356998400 (errno No such process) timegm(&localt) = 1356998400 (errno No such process) The first time timegm() is invoked, it fails. Subsequent invocations work correctly. I didn't manage to track down the root problem, but I found if I forced gmtptr to load (as gmtsub should), then everything works correctly. time_t timegm(tmp) struct tm * const tmp; { if (!gmt_is_set) { gmt_is_set = TRUE; #ifdef ALL_STATE gmtptr = (struct state *) calloc(1, sizeof *gmtptr); if (gmtptr != NULL) #endif /* defined ALL_STATE */ gmtload(gmtptr); } if (tmp != NULL) tmp->tm_isdst = 0; return time1(tmp, gmtsub, 0L); } I just copied the gmt_is_set test from gmtsub. I realize that gmtsub gets called anyways (timegm->time1->time2->gmtsub), but maybe the context doesn't get loaded quickly enough. I haven't tested, but I suspect that timeoff will have the same problem since it also invokes time1(..,gmtsub,..) without first ensuring the gmt context is loaded. Doug
participants (2)
-
Doug Bailey -
Paul Eggert