荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Lg (创造人生的传奇), 信区: Linux
标  题: Linux and the Y2K Bug
发信站: BBS 荔园晨风站 (Sun Jan  2 14:35:01 2000), 转信

Linux and the Y2K Bug

Robert Kiesling


Listing 1
Listing 2


Linux, like other POSIX-compliant operating systems, provides facilities for
coping with the Y2K bug, and software written properly for Linux should be
able
to cope with the end of the millennium. As a systems administrator, however,
you
may want to test both your Linux systems and any applications running on them
for
date compliance.

This article describes the time keeping functions that are available in the
Linux C
libraries, Version 5. The GNU glib2 libraries, which are still in the early
stages of
development, will provide similar functionality and compliance with time
keeping
standards. I also explore how you might go about testing Linux-based
applications
for date compliance.

Linux Time

Linux keeps track of the time using the 32-bit time_t type that maintains the
count
of UTC calendar time, which is the number of seconds since January 1, 1970. It
 is
declared in time.h as the following:

typedef long time_t;

The standard UNIX utilities (or the free software versions distributed by the
GNU
project) that have been ported to Linux, support this data type. Assuming that
 the
hardware clock handles the dates in the next century correctly, time keeping
should be correct until the year 2038, when the 32-bit time_t counter will
overflow. Solving what may become known as the Y2038K bug is beyond the
scope of this article, however.

The Linux libraries include the following functions to provide time and date
information.

time()    /* Returns the value of time_t in seconds.        */
ctime()   /* Returns ASCII formatted output from time_t.    */
stime()   /* Set the date and time using UTC calendar time. */

Functions related to ctime(), such as asctime(), gmtime(), localtime(), and
mktime(), use the value stored in time_t and return hours, minutes, seconds,
day,
date, month, and year in either data structure tm, or in ASCII format.

The tm struct is declared in time.h as:

struct tm {
        int tm_sec;
        int tm_min;
        int tm_hour;
        int tm_mday;
        int tm_mon;
        int tm_year;
        int tm_wday;
        int tm_yday;
        int tm_isdst;
        /* Those are for future use. */
        long int __tm_gmtoff__;
        __const char *__tm_zone__;
};

strftime() provides formatted output using a printf-like format specifier, and
 uses
the system's local data for time zone information. For example, the date
program
uses the strftime() function to output the date in RFC international time
format.

Sat Aug 29 10:34:43 EDT 1998

If the system's hardware clock can handle dates in the next century correctly,
 date
will display the date with the correct day, date, and year.

Sun Aug 29 10:53:07 EDT 1999
Tue Aug 29 10:46:41 EDT 2000
Wed Aug 29 10:49:29 EDT 2001

ANSI-standard time functions do not need to provide the day of the week to be
specified, although POSIX-compliant functions do.

Testing Software

On Intel-architecture machines, the system hardware clock is set from a CMOS,
battery-maintained timer when the system is powered on. On machines that use
the Intel 80286 and later processors, the CMOS time is set using a
hardware-embedded, menu-driven program that is accessible before the system
software boots.

Booting a multi-user system for testing purposes, however, is impractical,
not in
the least because resetting the time can disrupt the operation of users'
programs.
Because Linux uses the memory management facilities of 80386 and later
processors, programs run from user space to set the hardware clock can cause
a
signal 11 segmentation violation. One solution is to use one of the many
utilities
provided for MS-DOS that sets the hardware clock using direct BIOS calls.
These utilities can be run under the MS-DOS emulator that is provided for
Linux.

This solution, however, does not address the problem of the date being reset
for
other users. Ideally, we would like to measure the performance of the software
being tested without disrupting other users' programs. This means we would
like to
substitute our own counter for the system's time_t counter. The program
getutctime, shown in Listing 1, takes its argument in the format
hours:minutes:seconds:month:day:year and returns the calendar time using the
mktime() function. If no argument is given, the program returns the current
calendar time.

> getutctime
904427231.
> getutctime 12:30:00:4:16:2002
1018978200.

The program doesn't do any range checking of the date and time values. The
values are stored in the tm structure as integer representations of the
command line
argument, with the exception that months are counted from 0, and years are
counted from 1900. However, the time_t counter increments correctly after the
year 2000.

Inserting a User-Specified Time into a Routine

With the information given previously, it is possible to substitute the
calendar value
of a given date and time for the actual system time when testing software.
For
example, the GNU date utility takes the time either from the system clock or
from
the command line. It converts the UTC calendar time to a tm struct using local
time information via the localtime() function, which is then formatted using
the
strftime() function into the time and date displayed by the output.

Normally, the system time is taken from the system clock, but it is easy
enough to
substitute a test value. A code fragment that formats a user-supplied time
and date
in a similar manner might look like this:

#include <time.h>

test_time{ time_t user_supplied_time )
{
  struct tm *timestruct;
  char buf[80];
  char fmt[] = "%a %b %e %H:%M:%S %Z %Y";

  timestruct = localtime( &user_supplied_time );
  strftime(&buf, sizeof(buf), fmt, tm);
  printf("%s\n", buf);
}

Checking Y2K Compliance in Perl and awk Programs

Resetting the time in Perl can be done with the localtime() function, which is
similar to the C function. localtime() returns a formatted array of elements
with a
format similar to those of the C-language tm struct. The short program shown
here
returns either the current system time, if no argument is passed to it, or the
formatted user-specified time if one is provided as an argument.

#!/usr/bin/perl

if ( $_ = $ARGV[0], /^-/ )
{
  print scalar localtime($ARGV[0]), "\n";
}
else
{
  print scalar localtime, "\n";
}

The same program written in awk, using the built-in systime() and strftime()
functions, looks like this:

#! /usr/bin/awk -f

BEGIN {
  if ( ARGC == 1 ) {
    print strftime("%a %b %e %H:%M:%S %Z %Y ", systime());
  }
  else {
    print strftime("%a %b %e %H:%M:%S %Z %Y ", ARGV[1]);
  }
}

Testing Software by Setting the System Time

Sometimes, of course, resetting the system time is much easier. If you are
testing a
Perl program for end of the century compliance, setting the system clock
externally
is much simpler than, for example, digging through the internals of
nonstandard
time and date routines if you do not have access to the program source code.

The C stime() function resets the system clock, but you must have superuser
privileges on the system to use it. The simple program shown in setutctime,
resets
the time using a UTC calendar time in long integer format, like those
provided by
getutctime. setutctime does not perform any checking of user input, but does
return an error if the person executing the program does not have permission to
reset the system time.

Conclusion

The article shows how to locate Y2K millenium bugs in programs that do not
follow the timekeeping standards of Linux or other POSIX-compliant operating
systems. The code can provide the building blocks for more complex test suites
written in C, Perl, and awk. The specific actions to correct non-Y2K conforming
programs will vary depending on your site's needs and the availability of Y2K
conformant replacement software. If the source code of a non-conforming
program is available, this article provides a few techniques to re-code the
software
to POSIX standards so dates will be correct after the year 2000.

About the Author

Robert Kiesling is the editor of Linux: The Complete Reference, 6th Edition and
a contributor to Linux Installation and Getting Started. He is also the
maintainer of the Linux Frequently Asked Questions (FAQ) list. Comments should
be directed to kiesling@terracom.net.

--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@210.39.3.71]
※ 修改:·georgehill 於 Jan  2 15:39:40 修改本文·[FROM: 192.168.1.115]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店