timezone: Remove TZNAME_MAX limit from sysconf [BZ #15576]

glibc does not impose a limit, and POSIX does not allow a
sysconf limit which changes during the lifetime of a process.
This commit is contained in:
Florian Weimer 2017-03-07 09:37:46 +01:00
parent 1c1243b6fc
commit 8492c4dd69
7 changed files with 28 additions and 79 deletions

View File

@ -1,3 +1,21 @@
2017-03-07 Florian Weimer <fweimer@redhat.com>
[BZ #15576]
Remove TZNAME_MAX limit from sysconf.
* include/time.h (__tzname_cur_max, __tzname_max): Remove
declaration.
* time/tzfile.c (__tzfile_read, __tzfile_default): Do not call
compute_tzname_max.
(compute_tzname_max): Remove.
* time/tzset.c (__tzname_cur_max, __tzname_max): Remove.
(update_vars): Do not update __tzname_cur_max.
(tzset_internal): Remove argument.
(__tzset): Adjust call to tzset_internal.
(__tz_convert): Likewise.
* posix/sysconf.c (__sysconf): Return -1 for _SC_TZNAME_MAX.
* sysdeps/posix/sysconf.c (__sysconf): Likewise.
* manual/conf.texi (Sysconf Definition): Update comment.
2017-03-07 Siddhesh Poyarekar <siddhesh@sourceware.org> 2017-03-07 Siddhesh Poyarekar <siddhesh@sourceware.org>
[BZ #21209] [BZ #21209]

View File

@ -37,10 +37,6 @@ extern struct tm _tmbuf attribute_hidden;
/* Defined in tzset.c. */ /* Defined in tzset.c. */
extern char *__tzstring (const char *string); extern char *__tzstring (const char *string);
/* Defined in tzset.c. */
extern size_t __tzname_cur_max attribute_hidden;
extern int __use_tzfile attribute_hidden; extern int __use_tzfile attribute_hidden;
extern void __tzfile_read (const char *file, size_t extra, extern void __tzfile_read (const char *file, size_t extra,
@ -82,10 +78,6 @@ extern void __tzset (void);
/* Prototype for the internal function to get information based on TZ. */ /* Prototype for the internal function to get information based on TZ. */
extern struct tm *__tz_convert (const time_t *timer, int use_localtime, struct tm *tp); extern struct tm *__tz_convert (const time_t *timer, int use_localtime, struct tm *tp);
/* Return the maximum length of a timezone name.
This is what `sysconf (_SC_TZNAME_MAX)' does. */
extern long int __tzname_max (void);
extern int __nanosleep (const struct timespec *__requested_time, extern int __nanosleep (const struct timespec *__requested_time,
struct timespec *__remaining); struct timespec *__remaining);
libc_hidden_proto (__nanosleep) libc_hidden_proto (__nanosleep)

View File

@ -291,14 +291,10 @@ constants are declared in the header file @file{unistd.h}.
@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} @safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
@c Some parts of the implementation open /proc and /sys files and dirs @c Some parts of the implementation open /proc and /sys files and dirs
@c to collect system details, using fd and stream I/O depending on the @c to collect system details, using fd and stream I/O depending on the
@c case. _SC_TZNAME_MAX calls __tzname_max, that (while holding a lock) @c case. The returned max value may change over time for NPROCS,
@c calls tzset_internal, that calls getenv if it's called the first @c NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES, NGROUPS_MAX, SIGQUEUE_MAX,
@c time; there are free and strdup calls in there too. The returned max @c depending on variable values read from /proc at each call, and from
@c value may change over time for TZNAME_MAX, depending on selected @c rlimit-obtained values CHILD_MAX, OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
@c timezones; NPROCS, NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES,
@c NGROUPS_MAX, SIGQUEUE_MAX, depending on variable values read from
@c /proc at each call, and from rlimit-obtained values CHILD_MAX,
@c OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
This function is used to inquire about runtime system parameters. The This function is used to inquire about runtime system parameters. The
@var{parameter} argument should be one of the @samp{_SC_} symbols listed @var{parameter} argument should be one of the @samp{_SC_} symbols listed
below. below.

View File

@ -37,7 +37,7 @@ __sysconf (int name)
return -1; return -1;
case _SC_TZNAME_MAX: case _SC_TZNAME_MAX:
return MAX (__tzname_max (), _POSIX_TZNAME_MAX); return -1;
case _SC_CHARCLASS_NAME_MAX: case _SC_CHARCLASS_NAME_MAX:
#ifdef CHARCLASS_NAME_MAX #ifdef CHARCLASS_NAME_MAX

View File

@ -93,7 +93,7 @@ __sysconf (int name)
#endif #endif
case _SC_TZNAME_MAX: case _SC_TZNAME_MAX:
return MAX (__tzname_max (), _POSIX_TZNAME_MAX); return -1;
case _SC_JOB_CONTROL: case _SC_JOB_CONTROL:
#if CONF_IS_DEFINED_SET (_POSIX_JOB_CONTROL) #if CONF_IS_DEFINED_SET (_POSIX_JOB_CONTROL)

View File

@ -48,8 +48,6 @@ struct leap
long int change; /* Seconds of correction to apply. */ long int change; /* Seconds of correction to apply. */
}; };
static void compute_tzname_max (size_t) internal_function;
static size_t num_transitions; static size_t num_transitions;
libc_freeres_ptr (static time_t *transitions); libc_freeres_ptr (static time_t *transitions);
static unsigned char *type_idxs; static unsigned char *type_idxs;
@ -494,8 +492,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (__tzname[1] == NULL) if (__tzname[1] == NULL)
__tzname[1] = __tzname[0]; __tzname[1] = __tzname[0];
compute_tzname_max (chars);
if (num_transitions == 0) if (num_transitions == 0)
/* Use the first rule (which should also be the only one). */ /* Use the first rule (which should also be the only one). */
rule_stdoff = rule_dstoff = types[0].offset; rule_stdoff = rule_dstoff = types[0].offset;
@ -626,8 +622,6 @@ __tzfile_default (const char *std, const char *dst,
/* Set the timezone. */ /* Set the timezone. */
__timezone = -types[0].offset; __timezone = -types[0].offset;
compute_tzname_max (stdlen + dstlen);
/* Invalidate the tzfile attribute cache to force rereading /* Invalidate the tzfile attribute cache to force rereading
TZDEFRULES the next time it is used. */ TZDEFRULES the next time it is used. */
tzfile_dev = 0; tzfile_dev = 0;
@ -836,21 +830,3 @@ __tzfile_compute (time_t timer, int use_localtime,
} }
} }
} }
static void
internal_function
compute_tzname_max (size_t chars)
{
const char *p;
p = zone_names;
do
{
const char *start = p;
while (*p != '\0')
++p;
if ((size_t) (p - start) > __tzname_cur_max)
__tzname_cur_max = p - start;
}
while (++p < &zone_names[chars]);
}

View File

@ -68,8 +68,7 @@ static tz_rule tz_rules[2];
static void compute_change (tz_rule *rule, int year) __THROW internal_function; static void compute_change (tz_rule *rule, int year) __THROW internal_function;
static void tzset_internal (int always, int explicit) static void tzset_internal (int always);
__THROW internal_function;
/* List of buffers containing time zone strings. */ /* List of buffers containing time zone strings. */
struct tzstring_l struct tzstring_l
@ -126,24 +125,7 @@ __tzstring (const char *s)
{ {
return __tzstring_len (s, strlen (s)); return __tzstring_len (s, strlen (s));
} }
/* Maximum length of a timezone name. tzset_internal keeps this up to date
(never decreasing it) when ! __use_tzfile.
tzfile.c keeps it up to date when __use_tzfile. */
size_t __tzname_cur_max;
long int
__tzname_max (void)
{
__libc_lock_lock (tzset_lock);
tzset_internal (0, 0);
__libc_lock_unlock (tzset_lock);
return __tzname_cur_max;
}
static char *old_tz; static char *old_tz;
static void static void
@ -154,14 +136,6 @@ update_vars (void)
__timezone = -tz_rules[0].offset; __timezone = -tz_rules[0].offset;
__tzname[0] = (char *) tz_rules[0].name; __tzname[0] = (char *) tz_rules[0].name;
__tzname[1] = (char *) tz_rules[1].name; __tzname[1] = (char *) tz_rules[1].name;
/* Keep __tzname_cur_max up to date. */
size_t len0 = strlen (__tzname[0]);
size_t len1 = strlen (__tzname[1]);
if (len0 > __tzname_cur_max)
__tzname_cur_max = len0;
if (len1 > __tzname_cur_max)
__tzname_cur_max = len1;
} }
@ -390,8 +364,7 @@ __tzset_parse_tz (const char *tz)
/* Interpret the TZ envariable. */ /* Interpret the TZ envariable. */
static void static void
internal_function tzset_internal (int always)
tzset_internal (int always, int explicit)
{ {
static int is_initialized; static int is_initialized;
const char *tz; const char *tz;
@ -402,12 +375,6 @@ tzset_internal (int always, int explicit)
/* Examine the TZ environment variable. */ /* Examine the TZ environment variable. */
tz = getenv ("TZ"); tz = getenv ("TZ");
if (tz == NULL && !explicit)
/* Use the site-wide default. This is a file name which means we
would not see changes to the file if we compare only the file
name for change. We want to notice file changes if tzset() has
been called explicitly. Leave TZ as NULL in this case. */
tz = TZDEFAULT;
if (tz && *tz == '\0') if (tz && *tz == '\0')
/* User specified the empty string; use UTC explicitly. */ /* User specified the empty string; use UTC explicitly. */
tz = "Universal"; tz = "Universal";
@ -583,7 +550,7 @@ __tzset (void)
{ {
__libc_lock_lock (tzset_lock); __libc_lock_lock (tzset_lock);
tzset_internal (1, 1); tzset_internal (1);
if (!__use_tzfile) if (!__use_tzfile)
{ {
@ -615,7 +582,7 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
/* Update internal database according to current TZ setting. /* Update internal database according to current TZ setting.
POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname. POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
This is a good idea since this allows at least a bit more parallelism. */ This is a good idea since this allows at least a bit more parallelism. */
tzset_internal (tp == &_tmbuf && use_localtime, 1); tzset_internal (tp == &_tmbuf && use_localtime);
if (__use_tzfile) if (__use_tzfile)
__tzfile_compute (*timer, use_localtime, &leap_correction, __tzfile_compute (*timer, use_localtime, &leap_correction,