Re: linking problems with tz-1994e `date' on Solaris 2.3
1. The Solaris 2.3 strftime gets confused about the timezone when it's linked together with `date'. I don't have the Solaris 2.3 source, so I don't know the details, but my guess is that Solaris 2.3 strftime assumes that tzset sets some global variables in the Solaris 2.3 library, but since we've substituted our own tzset this assumption no longer applies. The symptoms are that `date' prints the correct time but with either "GMT" or "" substituted for the time zone name.
As I remember, in SV-derived systems, "tzset()" will set the "timezone", "daylight", and "tzname" variables; in systems derived from more recent SV's (SVR3.1 and later, I think), it also sets "altzone".
SunOS 5.3 is SVR4-derived, so any time zone code installed on it should arrange to set "timezone", "altzone", "daylight", and "tzname" when "tzset()" is called. (It may, I think, reset them if there aren't single values for them that make sense - e.g., if there are different time zone abbreviations for standard time at different dates, or different time zone abbreviations for summer time at different dates, I think "localtime()" may change the setting of "tzname". That, at least, was the intent.)
It may be that "strftime()" is expecting "tzname" to be set; if it's not being set, that may be the source of the problem.
The SunOS 5.3 version of tzset() does set these variables: timezone daylight tzname altzone and it does reset them if TZ is not set properly. localtime() calls tzset(), so it will change the tzname[] values. joel
The SunOS 5.3 version of tzset() does set these variables: timezone daylight tzname altzone
and it does reset them if TZ is not set properly.
localtime() calls tzset(), so it will change the tzname[] values.
If by "the SunOS 5.3 version of 'tzset()'" you mean the one that comes with SunOS 5.3, that's exactly what I would have expected. The question, though, was whether the "tz94e" version of the code sets the variables in question. If USG_COMPAT is defined, it appears that it does, indeed, set "daylight" and "timezone"; if ALTZONE is defined, it sets "altzone". It appears that it always sets "tzname". All of the above is done in "settzname()", which is called by "tzsetwall()" and "tzset()". Given that, it's not obvious why
1. The Solaris 2.3 strftime gets confused about the timezone when it's linked together with `date'. I don't have the Solaris 2.3 source, so I don't know the details, but my guess is that Solaris 2.3 strftime assumes that tzset sets some global variables in the Solaris 2.3 library, but since we've substituted our own tzset this assumption no longer applies. The symptoms are that `date' prints the correct time but with either "GMT" or "" substituted for the time zone name.
would happen, as both versions of "tzset()" should, it appears, set "tzname[]".
From: guy@netapp.com (Guy Harris) Date: Mon, 4 Apr 1994 11:45:33 -0700 (PDT) If USG_COMPAT is defined, it appears that it does, indeed, set "daylight" and "timezone"; if ALTZONE is defined, it sets "altzone". It appears that it always sets "tzname". I had not defined USG_COMPAT or ALTZONE, but the problem does not go away when I do define it. Given that, it's not obvious why [the problem] would happen, as both versions of "tzset()" should, it appears, set "tzname[]". I don't know why it happens either. When Sun's strftime is entered, the variables in question already have the right values (timezone is 28800, daylight is 1, tzname is {"PST", "PDT"}, and altzone is 25200) if you compile with USG_COMPAT and ALTZONE. However, Sun's strftime does the wrong thing for the %Z format for some reason. A point of curiosity: Sun's strftime invokes mktime, which is tz's mktime in this case. Perhaps Sun's strftime expects something out of mktime that tz's mktime does not provide. I wonder why it calls mktime at all? So far the best workaround is to avoid linking with the vendor's strftime.
A point of curiosity: Sun's strftime invokes mktime, which is tz's mktime in this case.
Are you certain that it's not calling the 5.x "mktime()"? See below....
Perhaps Sun's strftime expects something out of mktime that tz's mktime does not provide. I wonder why it calls mktime at all?
5.x doesn't have "tm_zone" nor "tm_gmtoff" in "struct tm", does it? The SVR4 ABIs don't include it, and I don't think the SVR4 code from AT&T did. Hmm. I just remembered - C library code in SVR4-derived systems like 5.x, when calling routines not in, I think, the ANSI C name space, prepend an underscore to the name of the routine. Routines in the C library with names not in the ANSI C name space have that underscore prepended; references to the name without the prepended underscore resolve to the routine from the library if there's no routine in the program itself with the no-prependend-underscore name, or something such as that. Now, I'm not sure what happens to calls to the prepended-underscore name if there is a routine in the program with the no-prepended-underscore name, but I suspect it does *not* resolve to the routine in the program; that way, if you have a routine named "read()" in your program (where "in your program" includes "in a library of your own linked into your program), you don't break any ANSI C routines (e.g., standard I/O library routines) that might call "_read()" to do file system I/O. Could the 5.x "strftime()" be calling the 5.x "tzset()" rather than the "tzset()" from the library you've built? If so, is there some reason to expect the 5.x "tzset()" routine to e.g. fail to find the time zone file?
From: guy@netapp.com (Guy Harris) Date: Wed, 6 Apr 1994 16:44:48 -0700 (PDT)
Sun's strftime invokes mktime, which is tz's mktime in this case.
Are you certain that it's not calling the 5.x "mktime()"? See below.... Yes. Here is the gdb output. Notice that the `mktime' is tz's (at localtime.c:1404), whereas the strftime is Sun's. I include a backtrace (the output of the GDB `where' command) just before the point of failure -- Sun's strftime isn't handling the `%Z' format correctly for some reason. $ gdb -q date (gdb) b main Breakpoint 1 at 0x10edc: file date.c, line 85. (gdb) r Starting program: /net/twinsun/export/dark/u/eggert/src/lib/tz/date Breakpoint 1, main (argc=1, argv=0xeffffc0c) at date.c:85 85 register int aflag = 0; (gdb) b mktime Breakpoint 2 at 0x140d0: file localtime.c, line 1404. (gdb) c Continuing. Breakpoint 2, mktime (tmp=0xeffff9ec) at localtime.c:1404 1404 return time1(tmp, localsub, 0L); (gdb) c Continuing. Breakpoint 2, mktime (tmp=0xeffff9ec) at localtime.c:1404 1404 return time1(tmp, localsub, 0L); (gdb) where #0 mktime (tmp=0xeffff9ec) at localtime.c:1404 #1 0xef77fc14 in strftime () #2 0x1171c in timeout (fp=0x28220, format=0x145b0 "%X %Z %Y", tmp=0xeffffae8) at date.c:526 #3 0x11628 in display (format=0x0) at date.c:491 #4 0x112d0 in main (argc=1, argv=0xeffffc0c) at date.c:288 (gdb) c Continuing. Breakpoint 2, mktime (tmp=0xeffff93c) at localtime.c:1404 1404 return time1(tmp, localsub, 0L); (gdb) c Continuing. Wed Apr 6 19:44:40 1994 Program exited normally. (gdb)
Perhaps Sun's strftime expects something out of mktime that tz's mktime does not provide. I wonder why it calls mktime at all?
5.x doesn't have "tm_zone" nor "tm_gmtoff" in "struct tm", does it? That's correct -- the SunOS 5.3 <time.h> uses a minimal `struct tm'. C library code in SVR4-derived systems like 5.x, when calling routines not in, I think, the ANSI C name space, prepend an underscore to the name of the routine. That's true. But since mktime _is_ in the ANSI C name space, Sun doesn't have to (and doesn't) play that game with mktime. There is no `_mktime' in the library, and if you redefine mktime, as the tz package's `date' does, you're on your own. Could the 5.x "strftime()" be calling the 5.x "tzset()" rather than the "tzset()" from the library you've built? No. Here is a GDB session that shows this. tzset is being called only from localtime(). $ gdb -q ./date (gdb) b main Breakpoint 1 at 0x10edc: file date.c, line 85. (gdb) r Starting program: /net/twinsun/export/dark/u/eggert/src/lib/tz/./date Breakpoint 1, main (argc=1, argv=0xeffffc0c) at date.c:85 85 register int aflag = 0; (gdb) b tzset Breakpoint 2 at 0x132fc: file localtime.c, line 868. (gdb) b _tzset Breakpoint 3 at 0xef782dac (gdb) c Continuing. Breakpoint 2, tzset () at localtime.c:868 868 name = getenv("TZ"); (gdb) where #0 tzset () at localtime.c:868 #1 0x133e8 in localsub (timep=0xeffffae4, offset=0, tmp=0x24bb8) at localtime.c:920 #2 0x1350c in localtime (timep=0x24800) at localtime.c:962 #3 0x11598 in display (format=0x0) at date.c:487 #4 0x112d0 in main (argc=1, argv=0xeffffc0c) at date.c:288 (gdb) c Continuing. Wed Apr 6 22:11:44 1994 Program exited normally.
participants (3)
-
eggert@twinsun.com -
guy@netapp.com -
Joel.Tornatore@Eng.Sun.COM