1998-05-14 13:25  Ulrich Drepper  <drepper@cygnus.com>

	* inet/netinet/in.h: Add defines for multicast.
	Reported by Jeremy Hall <jhall@UU.NET>.

	* stdlib/stdlib.h: Add prototypes for __setenv and __unsetenv.
	* sysdeps/generic/putenv.c: Use __setenv and __unsetenv, not setenv
	and unsetenv.  Optimize _LIBC case.
	* sysdeps/generic/setenv.c: Prevent unnecessary memory leaks.
	Define functions with leading __.

	* time/tzfile.c: Correct handling of global variables daylight,
	timezone, and tzname.
	* time/tzset.c: Likewise.
	* timezone/Makefile (tests): Add tst-timezone.
	* timezone/tst-timezone.c: New file.

1998-05-14 10:35  Ulrich Drepper  <drepper@cygnus.com>

	* timezone/asia: Update from tzdata1998d.
	* timezone/australasia: Likewise.
	* timezone/europe: Likewise.
This commit is contained in:
Ulrich Drepper 1998-05-14 19:14:48 +00:00
parent 847a35a07b
commit ff152e3fc8
13 changed files with 326 additions and 84 deletions

View File

@ -1,3 +1,26 @@
1998-05-14 13:25 Ulrich Drepper <drepper@cygnus.com>
* inet/netinet/in.h: Add defines for multicast.
Reported by Jeremy Hall <jhall@UU.NET>.
* stdlib/stdlib.h: Add prototypes for __setenv and __unsetenv.
* sysdeps/generic/putenv.c: Use __setenv and __unsetenv, not setenv
and unsetenv. Optimize _LIBC case.
* sysdeps/generic/setenv.c: Prevent unnecessary memory leaks.
Define functions with leading __.
* time/tzfile.c: Correct handling of global variables daylight,
timezone, and tzname.
* time/tzset.c: Likewise.
* timezone/Makefile (tests): Add tst-timezone.
* timezone/tst-timezone.c: New file.
1998-05-14 10:35 Ulrich Drepper <drepper@cygnus.com>
* timezone/asia: Update from tzdata1998d.
* timezone/australasia: Likewise.
* timezone/europe: Likewise.
1998-05-13 Ulrich Drepper <drepper@cygnus.com>
* string/string.h: Don't use the optimized versions for the string

View File

@ -1,6 +1,6 @@
Open jobs for finishing GNU libc:
---------------------------------
Status: April 1998
Status: May 1998
If you have time and talent to take over any of the jobs below please
contact <bug-glibc@gnu.org>.
@ -112,3 +112,25 @@ contact <bug-glibc@gnu.org>.
correct form so it would be possible to enlarge it always according
to the page size and install the correct length only for fclose() and
fflush() calls.
[17] The sprof program to analyze the profiling data generated by ld.so
must be finished. It should have the same functionality as gprof
(as far as this is possible).
[18] Based on the sprof program we need tools to analyze the output. The
result should be a link map which specifies in which order the .o
files are placed in the shared object. This should help to improve
code locality and result in a smaller foorprint (in code and data
memory) since less pages are only used in small parts.
[19] A user-level STREAMS implementation should be available if the
kernel does not provide the support.
[20] More conversion modules for iconv(3). Existing modules should be
extended to do things like transliteration if this is wanted.
For often used conversion a direct conversion function should be
available.
[21] The nscd program and the stubs in the libc should be changed so
that each program uses only one socket connect. Take a look at
http://www.cygnus.com/~drepper/nscd.html

View File

@ -143,6 +143,12 @@ struct in_addr
# define INADDR_LOOPBACK ((uint32_t) 0x7f000001) /* Inet 127.0.0.1. */
#endif
/* Defines for Multicast INADDR. */
#define INADDR_UNSPEC_GROUP ((uint32_t) 0xe0000000) /* 224.0.0.0 */
#define INADDR_ALLHOSTS_GROUP ((uint32_t) 0xe0000001) /* 224.0.0.1 */
#define INADDR_ALLRTRS_GROUP ((uint32_t) 0xe0000002) /* 224.0.0.2 */
#define INADDR_MAX_LOCAL_GROUP ((uint32_t) 0xe00000ff) /* 224.0.0.255 */
/* IPv6 address */
struct in6_addr

View File

@ -533,10 +533,13 @@ extern int putenv __P ((__const char *__string));
#ifdef __USE_BSD
/* Set NAME to VALUE in the environment.
If REPLACE is nonzero, overwrite an existing value. */
extern int __setenv __P ((__const char *__name, __const char *__value,
int __replace));
extern int setenv __P ((__const char *__name, __const char *__value,
int __replace));
/* Remove the variable NAME from the environment. */
extern void __unsetenv __P ((__const char *__name));
extern void unsetenv __P ((__const char *__name));
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
/* Copyright (C) 1991, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -16,7 +16,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if defined (_AIX) && !defined (__GNUC__)
#if defined _AIX && !defined __GNUC__
#pragma alloca
#endif
@ -45,6 +45,9 @@
extern char *alloca ();
# endif /* __GNUC__ */
# endif /* HAVE_ALLOCA_H */
# define setenv __setenv
# define unsetenv __unsetenv
#endif /* _LIBC */
@ -57,10 +60,10 @@ putenv (string)
if (name_end != NULL)
{
char *name = alloca (name_end - string + 1);
#ifdef _LIBC
*((char *) __mempcpy (name, string, name_end - string)) = '\0';
char *name = strndupa (string, name_end - string);
#else
char *name = alloca (name_end - string + 1);
memcpy (name, string, name_end - string);
name[name_end - string] = '\0';
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -22,7 +22,7 @@
#include <errno.h>
#if !_LIBC
# if !defined(errno) && !defined(HAVE_ERRNO_DECL)
# if !defined errno && !defined HAVE_ERRNO_DECL
extern int errno;
# endif
# define __set_errno(ev) ((errno) = (ev))
@ -58,9 +58,34 @@ __libc_lock_define_initialized (static, envlock)
/* In the GNU C library we must keep the namespace clean. */
#ifdef _LIBC
# define setenv __setenv
# define unsetenv __unsetenv
# define clearenv __clearenv
#endif
/* In the GNU C library implementation we try to be more clever and
allow arbitrary many changes of the environment given that the used
values are from a small set. Outside glibc this will eat up all
memory after a while. */
#if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH)
# define USE_TSEARCH 1
# include <search.h>
/* This is a pointer to the root of the search tree with the known
values. */
static void *known_values;
# define KNOWN_VALUE(Str) tfind (Str, &known_values, (__compar_fn_t) strcmp)
# define STORE_VALUE(Str) tsearch (Str, &known_values, (__compar_fn_t) strcmp)
#else
# undef USE_TSEARCH
# define KNOWN_VALUE(Str) NULL
# define STORE_VALUE(Str) do { } while (0)
#endif
/* If this variable is not a null pointer we allocated the current
environment. */
@ -91,45 +116,56 @@ setenv (name, value, replace)
if (__environ == NULL || *ep == NULL)
{
char **new_environ;
#ifdef USE_TSEARCH
char *new_value;
#endif
if (__environ == last_environ && __environ != NULL)
/* We allocated this space; we can extend it. */
new_environ = (char **) realloc (last_environ,
(size + 2) * sizeof (char *));
else
new_environ = (char **) malloc ((size + 2) * sizeof (char *));
/* We allocated this space; we can extend it. */
new_environ = (char **) realloc (last_environ,
(size + 2) * sizeof (char *));
if (new_environ == NULL)
{
UNLOCK;
return -1;
}
new_environ[size] = malloc (namelen + 1 + vallen);
/* See whether the value is already known. */
#ifdef USE_TSEARCH
new_value = alloca (namelen + 1 + vallen);
# ifdef _LIBC
__mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
value, vallen);
# else
memcpy (new_value, name, namelen);
new_value[namelen] = '=';
memcpy (&new_value[namelen + 1], value, vallen);
# endif
new_environ[size] = KNOWN_VALUE (new_value);
if (new_environ[size] == NULL)
#endif
{
free ((char *) new_environ);
__set_errno (ENOMEM);
UNLOCK;
return -1;
new_environ[size] = malloc (namelen + 1 + vallen);
if (new_environ[size] == NULL)
{
__set_errno (ENOMEM);
UNLOCK;
return -1;
}
#ifdef USE_TSEARCH
memcpy (new_environ[size], new_value, namelen + 1 + vallen);
#else
memcpy (new_environ[size], name, namelen);
new_environ[size][namelen] = '=';
memcpy (&new_environ[size][namelen + 1], value, vallen);
#endif
}
if (__environ != last_environ)
memcpy ((char *) new_environ, (char *) __environ,
size * sizeof (char *));
#ifdef _LIBC
{
char *tmp = __mempcpy (new_environ[size], name, namelen);
*tmp++ = '=';
__mempcpy (tmp, value, vallen);
}
#else
memcpy (new_environ[size], name, namelen);
new_environ[size][namelen] = '=';
memcpy (&new_environ[size][namelen + 1], value, vallen);
#endif
new_environ[size + 1] = NULL;
last_environ = __environ = new_environ;
@ -139,22 +175,48 @@ setenv (name, value, replace)
size_t len = strlen (*ep);
if (len + 1 < namelen + 1 + vallen)
{
char *new_value;
char *np;
/* The existing string is too short; malloc a new one. */
char *new = malloc (namelen + 1 + vallen);
if (new == NULL)
{
UNLOCK;
return -1;
}
*ep = new;
#ifdef _LIBC
*((char *) __mempcpy (*ep, name, namelen)) = '=';
#else
memcpy (*ep, name, namelen);
(*ep)[namelen] = '=';
#ifdef USE_TSEARCH
new_value = alloca (namelen + 1 + vallen);
# ifdef _LIBC
__mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
value, vallen);
# else
memcpy (new_value, name, namelen);
new_value[namelen] = '=';
memcpy (&new_value[namelen + 1], value, vallen);
# endif
np = KNOWN_VALUE (new_value);
if (np == NULL)
#endif
{
np = malloc (namelen + 1 + vallen);
if (np == NULL)
{
UNLOCK;
return -1;
}
#ifdef USE_TSEARCH
memcpy (np, new_value, namelen + 1 + vallen);
#else
memcpy (np, name, namelen);
np[namelen] = '=';
memcpy (&np[namelen + 1], value, vallen);
#endif
}
/* Keep the old value around. */
STORE_VALUE (*ep);
*ep = np;
}
memcpy (&(*ep)[namelen + 1], value, vallen);
else
/* Overwrite the value part of the old value. */
memcpy (&(*ep)[namelen + 1], value, vallen);
}
UNLOCK;
@ -171,11 +233,15 @@ unsetenv (name)
LOCK;
for (ep = __environ; *ep; ++ep)
for (ep = __environ; *ep != NULL; ++ep)
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
{
/* Found it. Remove this pointer by moving later ones back. */
char **dp = ep;
/* Store the value so that we can reuse it later. */
STORE_VALUE (ep);
do
dp[0] = dp[1];
while (*dp++);
@ -195,7 +261,12 @@ clearenv ()
if (__environ == last_environ && __environ != NULL)
{
/* We allocated this environment so we can free it. */
/* We allocated this environment so we can free it. Store all the
strings. */
char **ep = __environ;
while (*ep != NULL)
STORE_VALUE (*ep++);
free (__environ);
last_environ = NULL;
}
@ -208,6 +279,10 @@ clearenv ()
return 0;
}
#ifdef _LIBC
# undef setenv
# undef unsetenv
# undef clearenv
weak_alias (__setenv, setenv)
weak_alias (__unsetenv, unsetenv)
weak_alias (__clearenv, clearenv)
#endif

View File

@ -54,6 +54,8 @@ static unsigned char *type_idxs = NULL;
static size_t num_types;
static struct ttinfo *types = NULL;
static char *zone_names = NULL;
static long int rule_stdoff;
static long int rule_dstoff;
static size_t num_leaps;
static struct leap *leaps = NULL;
@ -266,15 +268,32 @@ __tzfile_read (const char *file)
fclose (f);
info = find_transition (0);
/* Find the standard and daylight time offsets used by the rule file.
We choose the offsets in the types of each flavor that are
transitioned to earliest in time. */
__tzname[1] = NULL;
for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]);
++i)
__tzname[types[i].isdst] = __tzstring (&zone_names[types[i].idx]);
if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0]))
__tzname[info->isdst] = __tzstring (&zone_names[info->idx]);
if (__tzname[1] == NULL)
__tzname[1] = __tzname[0];
compute_tzname_max (chars);
rule_stdoff = rule_dstoff = 0;
for (i = 0; i < num_transitions; ++i)
{
if (!rule_stdoff && !types[type_idxs[i]].isdst)
rule_stdoff = types[type_idxs[i]].offset;
if (!rule_dstoff && types[type_idxs[i]].isdst)
rule_dstoff = types[type_idxs[i]].offset;
if (rule_stdoff && rule_dstoff)
break;
}
__daylight = rule_stdoff != rule_dstoff;
__timezone = -rule_stdoff;
__use_tzfile = 1;
return;
@ -291,7 +310,6 @@ __tzfile_default (const char *std, const char *dst,
long int stdoff, long int dstoff)
{
size_t stdlen, dstlen, i;
long int rule_offset, rule_stdoff, rule_dstoff;
int isdst;
__tzfile_read (TZDEFRULES);
@ -318,24 +336,9 @@ __tzfile_default (const char *std, const char *dst,
}
__mempcpy (__mempcpy (zone_names, std, stdlen), dst, dstlen);
/* Find the standard and daylight time offsets used by the rule file.
We choose the offsets in the types of each flavor that are
transitioned to earliest in time. */
rule_stdoff = rule_dstoff = 0;
for (i = 0; i < num_transitions; ++i)
{
if (!rule_stdoff && !types[type_idxs[i]].isdst)
rule_stdoff = types[type_idxs[i]].offset;
if (!rule_dstoff && types[type_idxs[i]].isdst)
rule_dstoff = types[type_idxs[i]].offset;
if (rule_stdoff && rule_dstoff)
break;
}
/* Now correct the transition times for the user-specified standard and
daylight offsets from GMT. */
isdst = 0;
rule_offset = rule_offset;
for (i = 0; i < num_transitions; ++i)
{
struct ttinfo *trans_type = &types[type_idxs[i]];
@ -419,14 +422,16 @@ __tzfile_compute (time_t timer, int use_localtime,
if (use_localtime)
{
struct ttinfo *info = find_transition (timer);
__daylight = info->isdst;
__timezone = -info->offset;
__daylight = rule_stdoff != rule_dstoff;
__timezone = -rule_stdoff;
__tzname[1] = NULL;
for (i = 0;
i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]);
++i)
__tzname[types[i].isdst] = &zone_names[types[i].idx];
if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0]))
__tzname[info->isdst] = &zone_names[info->idx];
if (__tzname[1] == NULL)
/* There is no daylight saving time. */
__tzname[1] = __tzname[0];
}
*leap_correct = 0L;

View File

@ -333,6 +333,7 @@ tzset_internal (always)
{
/* There is no DST. */
tz_rules[1].name = tz_rules[0].name;
tz_rules[1].offset = tz_rules[0].offset;
free (tzbuf);
return;
}
@ -547,8 +548,8 @@ tz_compute (timer, tm)
! compute_change (&tz_rules[1], 1900 + tm->tm_year))
return 0;
__daylight = timer >= tz_rules[0].change && timer < tz_rules[1].change;
__timezone = -tz_rules[__daylight].offset;
__daylight = tz_rules[0].offset != tz_rules[1].offset;
__timezone = -tz_rules[0].offset;
__tzname[0] = (char *) tz_rules[0].name;
__tzname[1] = (char *) tz_rules[1].name;
@ -626,9 +627,10 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
{
if (use_localtime)
{
tp->tm_isdst = __daylight;
tp->tm_zone = __tzname[__daylight];
tp->tm_gmtoff = -__timezone;
tp->tm_isdst = (*timer >= tz_rules[0].change
&& *timer < tz_rules[1].change);
tp->tm_zone = __tzname[tp->tm_isdst];
tp->tm_gmtoff = tz_rules[tp->tm_isdst].offset;
}
else
{

View File

@ -28,7 +28,7 @@ distribute := tzfile.h private.h scheck.c ialloc.c yearistype \
extra-objs := scheck.o ialloc.o
others := zdump zic
tests := test-tz
tests := test-tz tst-timezone
tzbases := africa antarctica asia australasia europe northamerica \
southamerica etcetera factory systemv \

View File

@ -1,4 +1,4 @@
# @(#)asia 7.36
# @(#)asia 7.38
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
@ -507,7 +507,7 @@ Rule Zion 1988 only - Apr 9 0:00 1:00 D
Rule Zion 1988 only - Sep 3 0:00 0 S
# From Ephraim Silverberg <ephraim@cs.huji.ac.il>
# (1997-03-04 and 1997-12-31):
# (1997-03-04 and 1998-03-16):
# According to the Office of the Secretary General of the Ministry of
# Interior, there is NO set rule for Daylight-Savings/Standard time changes.
@ -557,9 +557,9 @@ Rule Zion 1995 only - Sep 3 0:00 0 S
#
# ftp://ftp.huji.ac.il/pub/tz/announcements/1997.ps.gz
#
# According to the Office of the Spokeswoman for the Ministry of Interior,
# the dates for 1998 are tentative and are still subject to final approval
# (probably in late February/early March of 1998).
# The official announcement for the year 1998 can be viewed at:
#
# ftp://ftp.huji.ac.il/pub/tz/announcements/1998.ps.gz
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Zion 1996 only - Mar 15 0:00 1:00 D
@ -780,7 +780,6 @@ Zone Indian/Maldives 4:54:00 - LMT 1880 # Male
# Mongolia
# Shanks says that Mongolia has three time zones, but usno1995 and the CIA map
# <a href="http://www.odci.gov/cia/publications/nsolo/rmap-pdf/802483.pdf">
# Standard Time Zones of the World (1997-01)
# </a>
# both say that it has just one.

View File

@ -1,4 +1,4 @@
# @(#)australasia 7.40
# @(#)australasia 7.41
# This file also includes Pacific islands.
# Notes are at the end of this file
@ -804,7 +804,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# # YANCOWINNA.. [ Confirmation courtesy of Broken Hill Postmaster ]
# # [ Dec 1990 ]
# ...
# # Yancowinna uses Central Standard Time, despite it's location on the
# # Yancowinna uses Central Standard Time, despite [its] location on the
# # New South Wales side of the S.A. border. Most business and social dealings
# # are with CST zones, therefore CST is legislated by local government
# # although the switch to Summer Time occurs in line with N.S.W. There have

View File

@ -1,4 +1,4 @@
# @(#)europe 7.53
# %W%
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to

104
timezone/tst-timezone.c Normal file
View File

@ -0,0 +1,104 @@
/* Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int failed = 0;
struct test_times
{
const char *name;
int daylight;
int timezone;
};
static const struct test_times tests[] =
{
{ "Europe/Berlin", 1, -3600 },
{ "Universal", 0, 0 },
{ "Australia/Melbourne", 1, -36000 },
{ "America/Sao_Paulo", 1, 10800 },
{ NULL, 0, 0 }
};
void
print_tzvars (void)
{
printf ("tzname[0]: %s\n", tzname[0]);
printf ("tzname[1]: %s\n", tzname[1]);
printf ("daylight: %d\n", daylight);
printf ("timezone: %ld\n", timezone);
}
void
check_tzvars (const char *name, int dayl, int timez)
{
if (daylight != dayl)
{
printf ("Timezone: %s, daylight is: %d but should be: %d\n",
name, daylight, dayl);
++failed;
}
if (timezone != timez)
{
printf ("Timezone: %s, timezone is: %ld but should be: %d\n",
name, timezone, timez);
++failed;
}
}
int
main (int argc, char ** argv)
{
time_t t;
const struct test_times *pt;
char buf[BUFSIZ];
/* This should be: Thu May 14 18:02:16 1998. */
t = 895194136;
printf ("We use this date: %s\n", ctime (&t));
for (pt = tests; pt->name != NULL; ++pt)
{
/* Start with a known state */
printf ("Checking timezone %s\n", pt->name);
sprintf (buf, "TZ=%s", pt->name);
if (putenv (buf))
{
puts ("putenv failed.");
failed = 1;
}
tzset ();
print_tzvars ();
check_tzvars (pt->name, pt->daylight, pt->timezone);
/* calling localtime shouldn't make a difference */
localtime (&t);
print_tzvars ();
check_tzvars (pt->name, pt->daylight, pt->timezone);
}
return failed ? EXIT_FAILURE : EXIT_SUCCESS;
}