diff options
-rw-r--r-- | libical/ChangeLog | 7 | ||||
-rw-r--r-- | libical/src/libical/icaltime.c | 115 |
2 files changed, 64 insertions, 58 deletions
diff --git a/libical/ChangeLog b/libical/ChangeLog index 70de2b9037..95a7a619ff 100644 --- a/libical/ChangeLog +++ b/libical/ChangeLog @@ -1,3 +1,10 @@ +2001-05-10 JP Roseveaer <jpr@ximian.com> + + * src/libical/icaltime.c (set_tz, unset_tz): plug leak + (icaltime_as_timet): use altered functions + (icaltime_utc_offset): ditto + (icaltime_from_day_of_year): ditto + 2001-05-02 JP Rosevear <jpr@ximian.com> * src/libical/icalparser.c (icalparser_new): initialize diff --git a/libical/src/libical/icaltime.c b/libical/src/libical/icaltime.c index d29833f03f..d5b228b089 100644 --- a/libical/src/libical/icaltime.c +++ b/libical/src/libical/icaltime.c @@ -75,80 +75,76 @@ icaltime_from_timet(time_t tm, int is_date) /* Structure used by set_tz to hold an old value of TZ, and the new value, which is in memory we will have to free in unset_tz */ -struct set_tz_save {char* orig_tzid; char* new_env_str;}; +/* This will hold the last "TZ=XXX" string we used with putenv(). After we + call putenv() again to set a new TZ string, we can free the previous one. + As far as I know, no libc implementations actually free the memory used in + the environment variables (how could they know if it is a static string or + a malloc'ed string?), so we have to free it ourselves. */ +static char* saved_tz = NULL; -/* Temporarily change the TZ environmental variable. */ -struct set_tz_save set_tz(const char* tzid) -{ - - char *orig_tzid = 0; - char *new_env_str; - struct set_tz_save savetz; - size_t tmp_sz; - savetz.orig_tzid = 0; - savetz.new_env_str = 0; +/* If you use set_tz(), you must call unset_tz() some time later to restore the + original TZ. Pass unset_tz() the string that set_tz() returns. */ +char* set_tz(const char* tzid) +{ + char *old_tz, *old_tz_copy = NULL, *new_tz; - if(getenv("TZ") != 0){ - orig_tzid = (char*)icalmemory_strdup(getenv("TZ")); + /* Get the old TZ setting and save a copy of it to return. */ + old_tz = getenv("TZ"); + if(old_tz){ + old_tz_copy = (char*)malloc(strlen (old_tz) + 4); - if(orig_tzid == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return savetz; + if(old_tz_copy == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; } - } - - tmp_sz =strlen(tzid)+4; - new_env_str = (char*)malloc(tmp_sz); - if(new_env_str == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return savetz; + strcpy (old_tz_copy, "TZ="); + strcpy (old_tz_copy + 3, old_tz); } - - /* Copy the TZid into a string with the form that putenv expects. */ - strcpy(new_env_str,"TZ="); - strcpy(new_env_str+3,tzid); - putenv(new_env_str); + /* Create the new TZ string. */ + new_tz = (char*)malloc(strlen (tzid) + 4); - /* Old value of TZ and the string we will have to free later */ - savetz.orig_tzid = orig_tzid; - savetz.new_env_str = new_env_str; + if(new_tz == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } - return savetz; -} + strcpy (new_tz, "TZ="); + strcpy (new_tz + 3, tzid); -void unset_tz(struct set_tz_save savetz) -{ - /* restore the original TZ environment */ + /* Add the new TZ to the environment. */ + putenv(new_tz); - char* orig_tzid = savetz.orig_tzid; + /* Free any previous TZ environment string we have used. */ + if (saved_tz) + free (saved_tz); - if(orig_tzid!=0){ - size_t tmp_sz =strlen(orig_tzid)+4; - char* orig_env_str = (char*)malloc(tmp_sz); + /* Save a pointer to the TZ string we just set, so we can free it later. */ + saved_tz = new_tz; - if(orig_env_str == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return; - } - - strcpy(orig_env_str,"TZ="); - strcpy(orig_env_str+3,orig_tzid); + return old_tz_copy; /* This will be zero if the TZ env var was not set */ +} - putenv(orig_env_str); +void unset_tz(char *tzstr) +{ + /* restore the original environment */ - free(orig_tzid); + if(tzstr!=0){ + putenv(tzstr); } else { putenv("TZ"); /* Delete from environment */ } - if(savetz.new_env_str != 0){ - free(savetz.new_env_str); - } -} + /* Free any previous TZ environment string we have used. */ + if (saved_tz) + free (saved_tz); + /* Save a pointer to the TZ string we just set, so we can free it later. + (This can possibly be NULL if there was no TZ to restore.) */ + saved_tz = tzstr; +} time_t icaltime_as_timet(struct icaltimetype tt) { @@ -170,7 +166,7 @@ time_t icaltime_as_timet(struct icaltimetype tt) stm.tm_isdst = -1; if(tt.is_utc == 1 || tt.is_date == 1){ - struct set_tz_save old_tz = set_tz("UTC"); + char *old_tz = set_tz("UTC"); t = mktime(&stm); unset_tz(old_tz); } else { @@ -248,10 +244,11 @@ int icaltime_utc_offset(struct icaltimetype ictt, const char* tzid) time_t tt = icaltime_as_timet(ictt); time_t offset_tt; struct tm gtm; - struct set_tz_save old_tz; + + char *tz_str = 0; if(tzid != 0){ - old_tz = set_tz(tzid); + tz_str = set_tz(tzid); } /* Mis-interpret a UTC broken out time as local time */ @@ -260,7 +257,7 @@ int icaltime_utc_offset(struct icaltimetype ictt, const char* tzid) offset_tt = mktime(>m); if(tzid != 0){ - unset_tz(old_tz); + unset_tz(tz_str); } return tt-offset_tt; @@ -471,7 +468,7 @@ struct icaltimetype icaltime_from_day_of_year(short doy, short year) { struct tm stm; time_t tt; - struct set_tz_save old_tz = set_tz("UTC"); + char *old_tz = set_tz("UTC"); /* Get the time of january 1 of this year*/ memset(&stm,0,sizeof(struct tm)); @@ -565,3 +562,5 @@ struct icaldurationtype icaltime_subtract(struct icaltimetype t1, struct icaltimetype t2) */ + + |