update from main archive 961215

Mon Dec 16 02:15:42 1996  Ulrich Drepper  <drepper@cygnus.com>

	Make sure tzset() sets always tzname[].
	* time/tzfile.c: De-ANSI-declfy.
	(find_transition): New function.  Set tzname according to given time.
	(__tzread_file): Use find_transition to set tzname.
	(__tzfile_compute): Use find_transition instead of doing the work
	self.
	* time/tzset.c (tzset): Set tzname[] directly only if !__use_tzfile.

Sun Dec 15 16:52:34 1996  Ulrich Drepper  <drepper@cygnus.com>

	* login/utmp-file.c (pututline_file): Open file if closed.
	Reported by Roma Ekzhanov <ekzhanov@paragraph.com>.
	Use fcntl instead of flock.

Sun Dec 15 14:20:51 1996  Ulrich Drepper  <drepper@cygnus.com>

	* manual/time.texi: Update documentation of strftime function.
This commit is contained in:
Ulrich Drepper 1996-12-16 01:40:21 +00:00
parent 68dbb3a69e
commit 860d372986
5 changed files with 123 additions and 69 deletions

View File

@ -1,3 +1,23 @@
Mon Dec 16 02:15:42 1996 Ulrich Drepper <drepper@cygnus.com>
Make sure tzset() sets always tzname[].
* time/tzfile.c: De-ANSI-declfy.
(find_transition): New function. Set tzname according to given time.
(__tzread_file): Use find_transition to set tzname.
(__tzfile_compute): Use find_transition instead of doing the work
self.
* time/tzset.c (tzset): Set tzname[] directly only if !__use_tzfile.
Sun Dec 15 16:52:34 1996 Ulrich Drepper <drepper@cygnus.com>
* login/utmp-file.c (pututline_file): Open file if closed.
Reported by Roma Ekzhanov <ekzhanov@paragraph.com>.
Use fcntl instead of flock.
Sun Dec 15 14:20:51 1996 Ulrich Drepper <drepper@cygnus.com>
* manual/time.texi: Update documentation of strftime function.
Sun Dec 15 01:53:20 1996 Ulrich Drepper <drepper@cygnus.com> Sun Dec 15 01:53:20 1996 Ulrich Drepper <drepper@cygnus.com>
* Makefile (subdirs): Change crypt to md5-crypt. * Makefile (subdirs): Change crypt to md5-crypt.

View File

@ -140,14 +140,14 @@ getutent_r_file (struct utmp *buffer, struct utmp **result)
memset (&fl, '\0', sizeof (struct flock)); memset (&fl, '\0', sizeof (struct flock));
fl.l_type = F_WRLCK; fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET; fl.l_whence = SEEK_SET;
result = fcntl (file_fd, F_SETLKW, &fl); fcntl (file_fd, F_SETLKW, &fl);
/* Read the next entry. */ /* Read the next entry. */
nbytes = read (file_fd, &last_entry, sizeof (struct utmp)); nbytes = read (file_fd, &last_entry, sizeof (struct utmp));
/* And unlock the file. */ /* And unlock the file. */
fl.l_type = F_UNLCK; fl.l_type = F_UNLCK;
result = fcntl (file_fd, F_SETLKW, &fl); fcntl (file_fd, F_SETLKW, &fl);
if (nbytes != sizeof (struct utmp)) if (nbytes != sizeof (struct utmp))
{ {
@ -292,6 +292,7 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer,
static struct utmp * static struct utmp *
pututline_file (const struct utmp *data) pututline_file (const struct utmp *data)
{ {
struct flock fl; /* Information struct for locking. */
struct utmp buffer; struct utmp buffer;
struct utmp *pbuf; struct utmp *pbuf;
int found; int found;
@ -300,6 +301,10 @@ pututline_file (const struct utmp *data)
/* Something went wrong. */ /* Something went wrong. */
return NULL; return NULL;
if (file_fd == INT_MIN)
/* The file is closed. Open it again. */
setutent_file (0);
/* Find the correct place to insert the data. */ /* Find the correct place to insert the data. */
if (file_offset > 0) if (file_offset > 0)
found = 0; found = 0;
@ -318,14 +323,10 @@ pututline_file (const struct utmp *data)
found = internal_getutid_r (data, &buffer); found = internal_getutid_r (data, &buffer);
/* Try to lock the file. */ /* Try to lock the file. */
if (flock (file_fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS) memset (&fl, '\0', sizeof (struct flock));
{ fl.l_type = F_WRLCK;
/* Oh, oh. The file is already locked. Wait a bit and try again. */ fl.l_whence = SEEK_SET;
sleep (1); fcntl (file_fd, F_SETLKW, &fl);
/* This time we ignore the error. */
(void) flock (file_fd, LOCK_EX | LOCK_NB);
}
if (found < 0) if (found < 0)
{ {
@ -338,8 +339,8 @@ pututline_file (const struct utmp *data)
if (lseek (file_fd, 0, SEEK_END) < 0) if (lseek (file_fd, 0, SEEK_END) < 0)
{ {
(void) flock (file_fd, LOCK_UN); pbuf = NULL;
return NULL; goto unlock_return;
} }
} }
} }
@ -365,8 +366,10 @@ pututline_file (const struct utmp *data)
pbuf = (struct utmp *) data; pbuf = (struct utmp *) data;
} }
unlock_return:
/* And unlock the file. */ /* And unlock the file. */
(void) flock (file_fd, LOCK_UN); fl.l_type = F_UNLCK;
fcntl (file_fd, F_SETLKW, &fl);
return pbuf; return pbuf;
} }

View File

@ -638,14 +638,24 @@ The number is padded with spaces.
@item - @item -
The number is not padded at all. The number is not padded at all.
@item 0
The number is padded with zeros even if the format spefies padding
with spaces.
@end table @end table
The default action is to pad the number with zeros to keep it a constant The default action is to pad the number with zeros to keep it a constant
width. Numbers that do not have a range indicated below are never width. Numbers that do not have a range indicated below are never
padded, since there is no natural width for them. padded, since there is no natural width for them.
An optional modifier can follow the optional flag. The modifiers, which Following the flag an optional specification of the width is possible.
are POSIX.2 extensions, are: This is specified in decimal notation. If the natural size of the
output is of the field has less than the specifed number of character,
the result is written right adjusted and space padded to the given
size.
An optional modifier can follow the optional flag and width
specification. The modifiers, which are POSIX.2 extensions, are:
@table @code @table @code
@item E @item E
@ -660,7 +670,8 @@ Use the locale's alternate numeric symbols for numbers. This modifier
applies only to numeric format specifiers. applies only to numeric format specifiers.
@end table @end table
A modifier is ignored if no alternate representation is available. If the format supports the modifier but no alternate representation
is available, it is ignored.
The conversion specifier ends with a format specifier taken from the The conversion specifier ends with a format specifier taken from the
following list. The whole @samp{%} sequence is replaced in the output following list. The whole @samp{%} sequence is replaced in the output
@ -868,6 +879,10 @@ repeat the call, providing a bigger array.
If @var{s} is a null pointer, @code{strftime} does not actually write If @var{s} is a null pointer, @code{strftime} does not actually write
anything, but instead returns the number of characters it would have written. anything, but instead returns the number of characters it would have written.
According to POSIX.1 every call to @code{strftime} implies a call to
@code{tzset}. So the contents of the environment variable @code{TZ}
is examined before any output is produced.
For an example of @code{strftime}, see @ref{Time Functions Example}. For an example of @code{strftime}, see @ref{Time Functions Example}.
@end deftypefun @end deftypefun

View File

@ -1,22 +1,21 @@
/* Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc. /* Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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 modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful, The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Library General Public 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 License along with the GNU C Library; see the file COPYING.LIB. If not,
not, write to the Free Software Foundation, Inc., 675 Mass Ave, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Cambridge, MA 02139, USA. */ Boston, MA 02111-1307, USA. */
#include <ansidecl.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
@ -43,7 +42,8 @@ struct leap
long int change; /* Seconds of correction to apply. */ long int change; /* Seconds of correction to apply. */
}; };
static void compute_tzname_max __P ((size_t)); static struct ttinfo *find_transition (time_t timer);
static void compute_tzname_max (size_t);
static size_t num_transitions; static size_t num_transitions;
static time_t *transitions = NULL; static time_t *transitions = NULL;
@ -77,30 +77,31 @@ decode (const void *ptr)
} }
void void
DEFUN(__tzfile_read, (file), CONST char *file) __tzfile_read (const char *file)
{ {
size_t num_isstd, num_isgmt; size_t num_isstd, num_isgmt;
register FILE *f; register FILE *f;
struct tzhead tzhead; struct tzhead tzhead;
size_t chars; size_t chars;
register size_t i; register size_t i;
struct ttinfo *info;
__use_tzfile = 0; __use_tzfile = 0;
if (transitions != NULL) if (transitions != NULL)
free((PTR) transitions); free ((void *) transitions);
transitions = NULL; transitions = NULL;
if (type_idxs != NULL) if (type_idxs != NULL)
free((PTR) type_idxs); free ((void *) type_idxs);
type_idxs = NULL; type_idxs = NULL;
if (types != NULL) if (types != NULL)
free((PTR) types); free ((void *) types);
types = NULL; types = NULL;
if (zone_names != NULL) if (zone_names != NULL)
free((PTR) zone_names); free ((void *) zone_names);
zone_names = NULL; zone_names = NULL;
if (leaps != NULL) if (leaps != NULL)
free((PTR) leaps); free ((void *) leaps);
leaps = NULL; leaps = NULL;
if (file == NULL) if (file == NULL)
@ -112,12 +113,12 @@ DEFUN(__tzfile_read, (file), CONST char *file)
if (*file != '/') if (*file != '/')
{ {
static CONST char tzdir[] = TZDIR; static const char tzdir[] = TZDIR;
register CONST unsigned int len = strlen(file) + 1; register const unsigned int len = strlen (file) + 1;
char *new = (char *) __alloca(sizeof(tzdir) + len); char *new = (char *) __alloca (sizeof (tzdir) + len);
memcpy(new, tzdir, sizeof(tzdir) - 1); memcpy (new, tzdir, sizeof(tzdir) - 1);
new[sizeof(tzdir) - 1] = '/'; new[sizeof (tzdir) - 1] = '/';
memcpy(&new[sizeof(tzdir)], file, len); memcpy (&new[sizeof (tzdir)], file, len);
file = new; file = new;
} }
@ -125,7 +126,7 @@ DEFUN(__tzfile_read, (file), CONST char *file)
if (f == NULL) if (f == NULL)
return; return;
if (fread((PTR) &tzhead, sizeof(tzhead), 1, f) != 1) if (fread ((void *) &tzhead, sizeof (tzhead), 1, f) != 1)
goto lose; goto lose;
num_transitions = (size_t) decode (tzhead.tzh_timecnt); num_transitions = (size_t) decode (tzhead.tzh_timecnt);
@ -166,8 +167,8 @@ DEFUN(__tzfile_read, (file), CONST char *file)
if (sizeof (time_t) < 4) if (sizeof (time_t) < 4)
abort (); abort ();
if (fread((PTR) transitions, 4, num_transitions, f) != num_transitions || if (fread(transitions, 4, num_transitions, f) != num_transitions ||
fread((PTR) type_idxs, 1, num_transitions, f) != num_transitions) fread(type_idxs, 1, num_transitions, f) != num_transitions)
goto lose; goto lose;
if (BYTE_ORDER != BIG_ENDIAN || sizeof (time_t) != 4) if (BYTE_ORDER != BIG_ENDIAN || sizeof (time_t) != 4)
@ -184,30 +185,30 @@ DEFUN(__tzfile_read, (file), CONST char *file)
for (i = 0; i < num_types; ++i) for (i = 0; i < num_types; ++i)
{ {
unsigned char x[4]; unsigned char x[4];
if (fread((PTR) x, 1, 4, f) != 4 || if (fread (x, 1, 4, f) != 4 ||
fread((PTR) &types[i].isdst, 1, 1, f) != 1 || fread (&types[i].isdst, 1, 1, f) != 1 ||
fread((PTR) &types[i].idx, 1, 1, f) != 1) fread (&types[i].idx, 1, 1, f) != 1)
goto lose; goto lose;
types[i].offset = (long int) decode (x); types[i].offset = (long int) decode (x);
} }
if (fread((PTR) zone_names, 1, chars, f) != chars) if (fread (zone_names, 1, chars, f) != chars)
goto lose; goto lose;
for (i = 0; i < num_leaps; ++i) for (i = 0; i < num_leaps; ++i)
{ {
unsigned char x[4]; unsigned char x[4];
if (fread((PTR) x, 1, sizeof(x), f) != sizeof(x)) if (fread (x, 1, sizeof (x), f) != sizeof (x))
goto lose; goto lose;
leaps[i].transition = (time_t) decode (x); leaps[i].transition = (time_t) decode (x);
if (fread((PTR) x, 1, sizeof(x), f) != sizeof(x)) if (fread (x, 1, sizeof (x), f) != sizeof (x))
goto lose; goto lose;
leaps[i].change = (long int) decode (x); leaps[i].change = (long int) decode (x);
} }
for (i = 0; i < num_isstd; ++i) for (i = 0; i < num_isstd; ++i)
{ {
char c = getc(f); char c = getc (f);
if (c == EOF) if (c == EOF)
goto lose; goto lose;
types[i].isstd = c != 0; types[i].isstd = c != 0;
@ -217,7 +218,7 @@ DEFUN(__tzfile_read, (file), CONST char *file)
for (i = 0; i < num_isgmt; ++i) for (i = 0; i < num_isgmt; ++i)
{ {
char c = getc(f); char c = getc (f);
if (c == EOF) if (c == EOF)
goto lose; goto lose;
types[i].isgmt = c != 0; types[i].isgmt = c != 0;
@ -225,7 +226,14 @@ DEFUN(__tzfile_read, (file), CONST char *file)
while (i < num_types) while (i < num_types)
types[i++].isgmt = 0; types[i++].isgmt = 0;
(void) fclose(f); fclose (f);
info = find_transition (0);
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];
compute_tzname_max (chars); compute_tzname_max (chars);
@ -233,7 +241,7 @@ DEFUN(__tzfile_read, (file), CONST char *file)
return; return;
lose:; lose:;
(void) fclose(f); fclose(f);
} }
/* The user specified a hand-made timezone, but not its DST rules. /* The user specified a hand-made timezone, but not its DST rules.
@ -241,9 +249,7 @@ DEFUN(__tzfile_read, (file), CONST char *file)
from the TZDEFRULES file. */ from the TZDEFRULES file. */
void void
DEFUN(__tzfile_default, (std, dst, stdoff, dstoff), __tzfile_default (char *std, char *dst, long int stdoff, long int dstoff)
char *std AND char *dst AND
long int stdoff AND long int dstoff)
{ {
size_t stdlen, dstlen, i; size_t stdlen, dstlen, i;
long int rule_offset, rule_stdoff, rule_dstoff; long int rule_offset, rule_stdoff, rule_dstoff;
@ -332,12 +338,10 @@ DEFUN(__tzfile_default, (std, dst, stdoff, dstoff),
compute_tzname_max (stdlen + dstlen); compute_tzname_max (stdlen + dstlen);
} }
int static struct ttinfo *
DEFUN(__tzfile_compute, (timer, leap_correct, leap_hit), find_transition (time_t timer)
time_t timer AND long int *leap_correct AND int *leap_hit)
{ {
struct ttinfo *info; size_t i;
register size_t i;
if (num_transitions == 0 || timer < transitions[0]) if (num_transitions == 0 || timer < transitions[0])
{ {
@ -360,7 +364,16 @@ DEFUN(__tzfile_compute, (timer, leap_correct, leap_hit),
i = type_idxs[i - 1]; i = type_idxs[i - 1];
} }
info = &types[i]; return &types[i];
}
int
__tzfile_compute (time_t timer, long int *leap_correct, int *leap_hit)
{
struct ttinfo *info;
register size_t i;
info = find_transition (timer);
__daylight = info->isdst; __daylight = info->isdst;
__timezone = info->offset; __timezone = info->offset;
for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]); for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]);
@ -400,7 +413,7 @@ DEFUN(__tzfile_compute, (timer, leap_correct, leap_hit),
} }
void void
DEFUN(compute_tzname_max, (chars), size_t chars) compute_tzname_max (size_t chars)
{ {
extern size_t __tzname_cur_max; /* Defined in __tzset.c. */ extern size_t __tzname_cur_max; /* Defined in __tzset.c. */

View File

@ -514,9 +514,12 @@ tzset (void)
__tzset (); __tzset ();
/* Set `tzname'. */ if (!__use_tzfile)
__tzname[0] = (char *) tz_rules[0].name; {
__tzname[1] = (char *) tz_rules[1].name; /* Set `tzname'. */
__tzname[0] = (char *) tz_rules[0].name;
__tzname[1] = (char *) tz_rules[1].name;
}
__libc_lock_unlock (__tzset_lock); __libc_lock_unlock (__tzset_lock);
} }