Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1a 12/4/83; site rlgvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!harpo!seismo!rlgvax!guy From: guy@rlgvax.UUCP (Guy Harris) Newsgroups: net.unix-wizards,net.bugs.usg Subject: Re: TZ Rationalization Requested Message-ID: <1795@rlgvax.UUCP> Date: Fri, 9-Mar-84 21:35:26 EST Article-I.D.: rlgvax.1795 Posted: Fri Mar 9 21:35:26 1984 Date-Received: Sat, 10-Mar-84 14:17:12 EST References: <341@dual.UUCP> Distribution: net Organization: CCI Office Systems Group, Reston, VA Lines: 96 The question was "why do USG UNIX systems get the timezone information from an environment variable TZ, which is only read if you remember to call "tzset()", while it comes from a system call in V7 and descendants?" and "has anyone else heard a better reason to do it this way?" Well, the only reason I can think of to do it this way, other than the ability you mentioned to set the time zone on a per-session basis, is the ability to change the time zone without doing a system generation. I don't know that this is a better reason to do it this way; on the other hand, what you've given is a reason to do it a better way. Suggested way - thanks to Microsoft, who did it at least partially this way on their S3-base Xenix, which also keeps around the old V7 system call "ftime" to get it from the kernel. 1) GET RID OF THE REQUIREMENT TO EXPLICITLY CALL "tzset"! If the extra CPU cycles spent asking for the timezone on every call to "ctime" bothers you, set a static flag once you've called "tzset", and only call it from within "ctime" (and "localtime" and the like) if the flag is zero. There's not much point in calling "tzset" twice in a process, anyway, considering it requires a bit of contortion to change the processes' environment from within the process (chase down "environ" for the "TZ=" entry and replace it). "tzset" can still be left around; you may just want the timezone and DST flag values, and you may not want to make a system call (for reasons of portability to S5 and previous USG versions). 2) Have "tzset" make the system call if it doesn't find TZ in the environment, instead of defaulting to EST. Keep the old V7 table of time zone names, and have it search that table after the system call to find the names. In effect, you're merging the V7 and USG code, and keeping the USG call interface (which is downward (upward? whatever) compatible with V6, but not compatible with V7. Too bad they couldn't make up their mind...). If TZ is not set, things don't break, they just get the time zone from a nice central source. TZ is only set if somebody explictly wants to override it. As for the question of doing sysgens, that's a red herring. In USG UNIX, you have to do sysgens *anyway*, in order to set kernel parameters and (this is the key point) *the system's network node name*. So it's not practical to just build one binary and stick it on several machines without change *anyway*. I don't know if anybody builds a common kernel and then patches the "utsname" structure *ex post facto* (we do), but one could patch a timezone information structure in the same way. Or, if that's too kludgy, take a leaf from Berkeley's book - specifically, the book labelled "UNIX Programmer's Manual, 4.2 Berkeley Software Distribution, Virtual VAX-11 Version" and the leaf labelled "GETTIMEOFDAY(2)". The "gettimeofday" system call takes two pointers to structures as arguments, and fills those structures in: a structure containing the time of day (a longword of seconds and a longword of microseconds) and a structure containing the timezone information (offset in minutes west of Greewich and daylight savings time flag). "settimeofday" takes two pointers to similar structures as arguments; the contents of the first structure sets the system time, and if the pointer to the second structure is non-NULL its contents set the timezone information and DST flag (the fact that the latter pointer may be NULL and causes the system to leave the timezone information alone is undocumented - add another one to the long list of undocumented and useful and worthy-of- official-support-and-documentation features in UNIX, both Bell and Berkeley). They did the same thing with the host name, by the way; "gethostname" and "sethostname" system calls exist. The requirement that an environment variable be set in order for the system to understand time zones sucks. The person who made it a requirement obviously never thought that somebody would actually put something in the "shell" field in the password file, so obviously you can set TZ in "/etc/profile" (which gets executed by the USG Bourne shell, when run as a login shell, just before your ".profile" - a good idea, by the way) and it'll be set for everybody except for stuff run from "/etc/rc" - set it there, and you're home free, right? WRONG! We frequently set up people who run our office automation software with that system as their login shell, and the top-level shell of that software doesn't know "/etc/profile" from Adam. There *are* two ways of fixing this: 1) make their "login shell" a shell file (yes, believe it or not, this is supported by the V7, 4.xBSD, S3, and S5 "login program) which sets TZ and runs the program in question. This means, of course, that when you install a system it's *one more place* where you have to remember to change TZ if it's in a different time zone... 2) fix "login" so that it adds things like HOME to the environment passed to it, rather than creating a new environment *ab initio*, and make your lines in "/etc/inittab" look like 2:h0:c:env TERM=vt100 TZ=PST8PDT /etc/getty ttyh0 d which is the solution we chose, as it permits us to put TERM into the environment automatically as well; the authors of a lot of the UNIX code work for an organization that places heavy emphasis on dial-up use of UNIX (the reasons for this should be obvious when you consider the main source of revenue for that organization :-)), where setting TERM automatically is usually useless, but most of us work at sane places with 9600 baud or faster hardwired terminals, and port "/dev/ttyh0" is going to be a VT100 unless and until somebody moves the VT100. Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy