localtime() calls tzset() and hangs cupsd on Solaris #242

Closed
michaelrsweet opened this Issue Aug 22, 2003 · 2 comments

Comments

Projects
None yet
1 participant
Collaborator

michaelrsweet commented Aug 22, 2003

Version: 1.1.19
CUPS.org User: mike

The same signal handler bug is also triggered by localtime() on Solaris. Apparently Sun, in their infinite wisdom, call tzset() for each call to localtime(), which in turn calls malloc() and free() and hoses things totally when called from a signal handler.

Need to revamp the code to use gmtime() and to save the local timezone offset from the ReadConfiguration() function. That will allow local time to be reported without using localtime()...

Collaborator

michaelrsweet commented Aug 22, 2003

CUPS.org User: mike

Fixed in CVS...

Collaborator

michaelrsweet commented Aug 22, 2003

"str242.patch":

Index: conf.c

RCS file: /development/cvs/cups/scheduler/conf.c,v
retrieving revision 1.136
diff -u -r1.136 conf.c
--- conf.c 2003/07/20 12:42:33 1.136
+++ conf.c 2003/08/22 21:59:46
@@ -210,6 +210,8 @@
int run_user; /* User that will be running cupsd /
char *old_serverroot, /
Old ServerRoot /
*old_requestroot; /
Old RequestRoot */

  • time_t temptime; /* Temporary time info */
  • struct tm tempdate; / Temporary date/time info */

/*
@@ -403,6 +405,22 @@
MaxJobsPerUser = 0;
MaxJobsPerPrinter = 0;
MaxCopies = 100;
+

  • /*
  • * Set the time zone offset based on the output from localtime()...
  • * We do this so that GetDateTime() can use gmtime() and avoid the
  • * opportunity for a deadlock condition that Solaris offers if you
  • * call localtime() from a signal handler...
  • */
  • temptime = time(NULL);
  • tempdate = localtime(&temptime);

+#ifdef HAVE_TM_GMTOFF

  • TimeZoneOffset = tempdate->tm_gmtoff;
    +#else
  • TimeZoneOffset = timezone;
    +#endif /* HAVE_TM_GMTOFF */

/*

  • Read the configuration file...
    Index: conf.h

    RCS file: /development/cvs/cups/scheduler/conf.h,v
    retrieving revision 1.57
    diff -u -r1.57 conf.h
    --- conf.h 2003/08/01 20:00:53 1.57
    +++ conf.h 2003/08/22 21:59:46
    @@ -102,6 +102,8 @@
    /* User ID for server /
    VAR gid_t Group VALUE(0);
    /
    Group ID for server */
    +VAR time_t TimeZoneOffset VALUE(0);
  •               /\* Offset from UTC to local time _/
    

    VAR int ClassifyOverride VALUE(0),
    /_ Allow overrides? */
    ConfigFilePerm VALUE(0600),
    Index: log.c

    RCS file: /development/cvs/cups/scheduler/log.c,v
    retrieving revision 1.35
    diff -u -r1.35 log.c
    --- log.c 2003/07/25 17:37:09 1.35
    +++ log.c 2003/08/22 21:59:46
    @@ -79,26 +79,26 @@
    • Get the date and time from the UNIX time value, and then format it
    • into a string. Note that we can't use the strftime() function since
    • it is localized and will seriously confuse automatic programs if the
  • * month names are in the wrong language!
  • * month names are in the wrong language! Also, thanks to a marvelous
  • * deadlock condition present in most/all versions of Sun's C libraries
  • * we can't use localtime()...
  • * Also, we use the "timezone" variable that contains the current timezone
  • * offset from GMT in seconds so that we are reporting local time in the
  • * log files. If you want GMT, set the TZ environment variable accordingly
  • * before starting the scheduler.
  • * (*BSD and Darwin store the timezone offset in the tm structure)
  • * We use the "TimeZoneOffset" variable that contains the current
  • * timezone offset from UTC in seconds so that we are reporting local
  • * time in the log files. If you want GMT, set the TZ environment
  • * variable accordingly before starting the scheduler. Because of the
  • * static nature of the TimeZoneOffset variable, the time may not
  • * reflect daylight savings time accurately until you reconfigure or
    • restart the scheduler...
      */
  • date = localtime(&t);
  • t += TimeZoneOffset;
  • date = gmtime(&t);

snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]",
date->tm_mday, months[date->tm_mon], 1900 + date->tm_year,
date->tm_hour, date->tm_min, date->tm_sec,
-#ifdef HAVE_TM_GMTOFF

  •       date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60);
    

    -#else

  •       timezone / 3600, (timezone / 60) % 60);
    

    -#endif /* HAVE_TM_GMTOFF */

  •  TimeZoneOffset / 3600, (TimeZoneOffset / 60) % 60);
    

    return (s);
    }

michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment