linking problems with tz-1994e `date' on Solaris 2.3
I had two problems linking tz-1994e `date' under 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. The workaround is to use tz's strftime instead. 2. The system `getopt' and tz `getopt' clash as follows. In Solaris 2.3, `getopt' is broken into two object modules to make its more efficient in a shared library. One, `opt_data.o', merely contains the modifiable data (optind, optarg, opterr, and optopt). (The other, getopt.o, contains the code.) opt_data.o contains definitions for all four symbols, whereas tz's getopt contains two definitions (opterr and optind) and two common symbols (optopt and optarg). This confuses the Solaris 2.3 linker: it brings in opt_data to resolve the common symbols, but then it complains that opterr and optind are multiply defined. Here are the symptoms: gcc -static -Dlint -g -O -Wall -DTZDIR=\"etc/zoneinfo\" date.o localtime.o asctime.o getopt.o \ -lc ,lib.a -o date ld: fatal: symbol `optind' is multiply defined: (file getopt.o and file /usr/lib/libc.a(opt_data.o)); ld: fatal: symbol `opterr' is multiply defined: (file getopt.o and file /usr/lib/libc.a(opt_data.o)); ld: fatal: File processing errors. No output written to date *** Error code 1 One patch might be to modify tz's getopt.c to statically initialize optopt and optarg to 0 (I haven't tested this). Another patch, which I've taken below, is to use the system getopt if it is available. Here is a patch that embodies the above two suggestions. =================================================================== RCS file: Makefile,v retrieving revision 1994.5.1.1 retrieving revision 1994.5.1.2 diff -c -r1994.5.1.1 -r1994.5.1.2 *** Makefile 1994/04/03 02:54:41 1994.5.1.1 --- Makefile 1994/04/03 19:47:59 1994.5.1.2 *************** *** 280,292 **** if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \ then ranlib $@ ; fi ! # We use the system's logwtmp and strftime in preference to ours if available. date: $(DATEOBJS) ! ar r ,lib.a logwtmp.o strftime.o if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \ then ranlib ,lib.a ; fi ! $(CC) $(CFLAGS) date.o localtime.o asctime.o getopt.o \ -lc ,lib.a -o $@ rm -f ,lib.a --- 280,292 ---- if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \ then ranlib $@ ; fi ! # We use the system's getopt and logwtmp in preference to ours if available. date: $(DATEOBJS) ! ar r ,lib.a getopt.o logwtmp.o if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \ then ranlib ,lib.a ; fi ! $(CC) $(CFLAGS) date.o localtime.o asctime.o strftime.o \ -lc ,lib.a -o $@ rm -f ,lib.a
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.
participants (2)
-
eggert@lotl.twinsun.com -
guy@netapp.com