ack/plat/msdos86/libsys/gettimeofday.c
2021-03-29 15:15:13 +00:00

93 lines
1.9 KiB
C

/* $Source$
* $State$
* $Revision$
*/
/*
* Derived from dos-gettimeofday.c for newlib-ia16 which was written for the
* gcc-ia16 toolchain.
*
* Copyright (c) 2017--2021 TK Chia
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>
#include "libsys.h"
extern long _timezone;
extern int _daylight;
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
static volatile bool tzinited = false;
struct _dosdate dosdt, olddt;
struct _dostime dostm;
suseconds_t usec;
struct tm tm;
time_t tim;
if (!tzinited)
{
tzset();
tzinited = true;
}
memset(&tm, 0, sizeof tm);
_sys_getdate(&dosdt);
do
{
uint8_t hour;
_sys_gettime(&dostm);
tm.tm_hour = hour = dostm.hour;
tm.tm_min = dostm.minute;
tm.tm_sec = dostm.second;
usec = dostm.hsecond * 10000UL;
/* If the time is close to midnight, read the date again to
* check for midnight crossover. If crossover happens,
* repeat until it stops. */
if (hour)
break;
olddt = dosdt;
_sys_getdate(&dosdt);
} while (dosdt.day != olddt.day);
tm.tm_year = dosdt.year - 1900;
tm.tm_mon = dosdt.month - 1;
tm.tm_mday = dosdt.day;
tm.tm_isdst = -1;
tim = mktime(&tm);
if (tim == -1)
return -1;
if (tv)
{
tv->tv_sec = tim;
tv->tv_usec = usec;
}
if (tz)
{
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}