/* Low Level Interface Library Copyright 1983-2013 Green Hills Software,Inc. * This program is the property of Green Hills Software, Inc, * its contents are proprietary information and no part of it * is to be disclosed to anyone except employees of Green Hills * Software, Inc., or as agreed in writing signed by the President * of Green Hills Software, Inc. * * On Unix, times are always kept in Universal Coordinated Time * and adjusted according to the local timezone when displayed. * * Entry points are: * tzset() * __gh_timezone() */ /* ind_tmzn.c: ANSI time zone facilities, and internal library primitive. */ #include "indos.h" #include "ind_thrd.h" #if defined(__INTEGRITY_SHARED_LIBS) long __ghs_timezone; #endif /* __INTEGRITY_SHARED_LIBS */ /* Added the following code for better System V compatibility */ /* Actually, most systems provide tzset() in libc.a and that one should */ /* be used, but I wanted to add the global variables to */ /* and it seemed reasonable that if the Green Hills Software */ /* had the System V style timezone variables, we should also provide */ /* the appropriate library routine which sets them. There are 2 */ /* problems with this implementation. The global variable 'timezone' */ /* conflicts with the BSD type 'struct timezone', therefore it is not */ /* convenient to use gettimeofday() on BSD to set timezone. Further, */ /* getenv() is needed here, and that is defined in libansi.a., which */ /* always preceeds libind.a. For now getenv() is coded inline. */ #if (defined(ANYSYSV) && defined(CROSSUNIX)) || \ defined(SIMULATE) || defined(EMBEDDED) || defined(MSW) #define NEEDTZSET #endif #if defined(ANYSYSV) long timezone, altzone; int daylight; #elif defined(NEEDTZSET) /* Disable warning for defining an internal timezone variable */ #pragma ghs nowarning 172 static long timezone; #pragma ghs endnowarning 172 #endif #if defined(NEEDTZSET) /******************************************************************************/ /* void tzset(void); */ /* System V compatible method of setting the current timezone and daylight */ /* savings status. Requires that the external variable, environ, be set to */ /* a list of environment strings, including one of the form TZ=PST8PDT */ /* Explanation needed for the timezone, altzone, daylight and tzname variables*/ /******************************************************************************/ #define IsAlpha(c) ((c>='A'&&c<='Z')||(c>='a'&&c<='z')) #define IsDigit(c) (c>='0'&&c<='9') #ifdef __ghs_pid char *tzname[2]; #else static char tzname_default[] = "GMT\0 "; char *tzname[2] = { tzname_default, tzname_default+4 } ; #endif void tzset(void) { #if defined(ANYUNIX)||defined(UNIXSYSCALLS)||defined(MSW) static char tzname_default[] = "GMT\0 "; /* Ugly. An inline copy of getenv() to avoid conflicts with C libraries. */ /* should be tz = getenv("TZ"); */ char *tz = NULL; extern char **environ; char **envp = environ, *e; if (envp) while (e = *envp++) if (e[0] == 'T' && e[1] == 'Z' && e[2] == '=') { tz = e + 3; break; } /* Outside of Unix, don't know how to get the environment, so TZ will be NULL */ if (tz != NULL) { int hour = 0, minute = 0, second = 0,sign = 1; char *zone; int ahour = 0, aminute = 0, asecond = 0,asign = 1; char *azone = NULL; /* 3 letter timezone required */ if (!IsAlpha(tz[0]) || !IsAlpha(tz[1]) || !IsAlpha(tz[2])) return; zone = tz; tz += 3; /* the rest is optional */ if ( *tz ) { /* signed hour:min:sec difference from GMT */ if ( *tz == '+' || *tz == '-' ) { if (*tz == '-') sign = -1; tz++; } if (!IsDigit(tz[0])) return; hour = *tz++ - '0'; if (IsDigit(tz[0])) hour = hour * 10 + *tz++ - '0'; hour *= sign; if (tz[0] == ':' && IsDigit(tz[1]) && IsDigit(tz[2])) { minute = ((tz[1] - '0') * 10 + tz[2] - '0') * sign; tz += 3; if (tz[0] == ':' && IsDigit(tz[1]) && IsDigit(tz[2])) { second = ((tz[1] - '0') * 10 + tz[2] - '0') * sign; tz += 3; } } /* the rest is optional */ if ( *tz && IsAlpha(tz[0]) && IsAlpha(tz[1]) && IsAlpha(tz[2])) { /* 3 letter daylight timezone */ azone = tz; tz += 3; /* signed hour:min:sec difference from GMT (may be skipped) */ if ( *tz == '+' || *tz == '-' ) { if (*tz == '-') asign = -1; tz++; } if (IsDigit(tz[0])) { ahour = *tz++ - '0'; if (IsDigit(tz[0])) ahour = ahour * 10 + *tz++ - '0'; ahour *= asign; if (tz[0] == ':' && IsDigit(tz[1]) && IsDigit(tz[2])) { aminute = ((tz[1] - '0') * 10 + tz[2] - '0') * asign; tz += 3; if (tz[0] == ':' && IsDigit(tz[1]) && IsDigit(tz[2])) { asecond = ((tz[1] - '0') * 10 + tz[2] - '0')*asign; tz += 3; } } } else if (*tz == '\0') ahour = hour - 1; } } /* the rest of TZ is ignored by this implementation */ timezone = hour * 60 * 60 + minute * 60 + second; #if defined(ANYSYSV) daylight = 0; #endif #ifdef __ghs_pid tzname[0] = tzname_default; tzname[1] = tzname_default+4; #endif tzname[0][0] = zone[0]; tzname[0][1] = zone[1]; tzname[0][2] = zone[2]; tzname[0][3] = '\0'; if (azone) { tzname[1][0] = azone[0]; tzname[1][1] = azone[1]; tzname[1][2] = azone[2]; tzname[1][3] = '\0'; #if defined(ANYSYSV) altzone = ahour * 60 * 60 + aminute * 60 + asecond; daylight = 1; #endif } return; } #endif } #endif /* NEEDTZSET */ /******************************************************************************/ /* int __gh_timezone(void); */ /* Return the number of minutes west of Greenwich Mean Time of the current */ /* time zone. If the time() functions return the local time rather than */ /* Greenwich Mean Time then return 0 from __gh_timezone(). */ /* See also tzset() and localtime() */ /******************************************************************************/ int __gh_timezone(void) { #if defined(ANYSYSV) || defined(NEEDTZSET) tzset(); return(timezone/60); #elif defined(ANYBSD) struct timeval ignore; struct timezone tz; gettimeofday(&ignore,&tz); return(tz.tz_minuteswest); #elif defined(ANYUNIX)|| defined(UNIXSYSCALLS)|| defined(SIMULATE) # if defined(TIMEZONE) return(TIMEZONE*60); # else return(8*60); # endif /* TIMEZONE */ #else return 0; #endif }