mirror of
https://github.com/fluencelabs/musl
synced 2025-06-25 20:51:53 +00:00
initial check-in, version 0.5.0
This commit is contained in:
27
src/time/__asctime.c
Normal file
27
src/time/__asctime.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <langinfo.h>
|
||||
|
||||
const char *__langinfo(nl_item);
|
||||
|
||||
char *__asctime(const struct tm *tm, char *buf)
|
||||
{
|
||||
/* FIXME: change __langinfo to __C_langinfo once we have locales */
|
||||
if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
|
||||
__langinfo(ABDAY_1+tm->tm_wday),
|
||||
__langinfo(ABMON_1+tm->tm_mon),
|
||||
tm->tm_mday, tm->tm_hour,
|
||||
tm->tm_min, tm->tm_sec,
|
||||
1900 + tm->tm_year) >= 26)
|
||||
{
|
||||
/* ISO C requires us to use the above format string,
|
||||
* even if it will not fit in the buffer. Thus asctime_r
|
||||
* is _supposed_ to crash if the fields in tm are too large.
|
||||
* We follow this behavior and crash "gracefully" to warn
|
||||
* application developers that they may not be so lucky
|
||||
* on other implementations (e.g. stack smashing..).
|
||||
*/
|
||||
*(int*)0 = 0;
|
||||
}
|
||||
return buf;
|
||||
}
|
9
src/time/__time.h
Normal file
9
src/time/__time.h
Normal file
@ -0,0 +1,9 @@
|
||||
time_t __tm_to_time(struct tm *);
|
||||
struct tm *__time_to_tm(time_t, struct tm *);
|
||||
void __tzset(void);
|
||||
struct tm *__dst_adjust(struct tm *tm);
|
||||
|
||||
extern long __timezone;
|
||||
extern int __daylight;
|
||||
extern int __dst_offset;
|
||||
extern char *__tzname[2];
|
81
src/time/__time_to_tm.c
Normal file
81
src/time/__time_to_tm.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include <time.h>
|
||||
|
||||
/* C defines the rounding for division in a nonsensical way */
|
||||
#define Q(a,b) ((a)>0 ? (a)/(b) : -(((b)-(a)-1)/(b)))
|
||||
|
||||
#define DAYS_PER_400Y (365*400 + 97)
|
||||
#define DAYS_PER_100Y (365*100 + 24)
|
||||
#define DAYS_PER_4Y (365*4 + 1)
|
||||
|
||||
/* FIXME: use lldiv once it's fixed to compute quot,rem together */
|
||||
struct tm *__time_to_tm(time_t t, struct tm *tm)
|
||||
{
|
||||
/* months are march-based */
|
||||
static const int days_thru_month[] = {31,61,92,122,153,184,214,245,275,306,337,366};
|
||||
long long bigday;
|
||||
unsigned int day, year4, year100;
|
||||
int year, year400;
|
||||
int month;
|
||||
int leap;
|
||||
int hour, min, sec;
|
||||
int wday, mday, yday;
|
||||
|
||||
/* start from 2000-03-01 (multiple of 400 years) */
|
||||
t += -946684800 - 86400*(31+29);
|
||||
|
||||
bigday = Q(t, 86400);
|
||||
sec = t-bigday*86400;
|
||||
|
||||
hour = sec/3600;
|
||||
sec -= hour*3600;
|
||||
min = sec/60;
|
||||
sec -= min*60;
|
||||
|
||||
/* 2000-03-01 was a wednesday */
|
||||
wday = (3+bigday)%7;
|
||||
if (wday < 0) wday += 7;
|
||||
|
||||
t = -946684800LL - 86400*(31+29) + 9000000;
|
||||
|
||||
year400 = Q(bigday, DAYS_PER_400Y);
|
||||
day = bigday-year400*DAYS_PER_400Y;
|
||||
|
||||
year100 = day/DAYS_PER_100Y;
|
||||
if (year100 == 4) year100--;
|
||||
day -= year100*DAYS_PER_100Y;
|
||||
|
||||
year4 = day/DAYS_PER_4Y;
|
||||
if (year4 == 25) year4--;
|
||||
day -= year4*DAYS_PER_4Y;
|
||||
|
||||
year = day/365;
|
||||
if (year == 4) year--;
|
||||
day -= year*365;
|
||||
|
||||
leap = !year && (year4 || !year100);
|
||||
yday = day + 31+28 + leap;
|
||||
if (yday >= 365+leap) yday -= 365+leap;
|
||||
|
||||
year += 4*year4 + 100*year100 + 400*year400 + 2000-1900;
|
||||
|
||||
for (month=0; days_thru_month[month] <= day; month++);
|
||||
if (month) day -= days_thru_month[month-1];
|
||||
month += 2;
|
||||
if (month >= 12) {
|
||||
month -= 12;
|
||||
year++;
|
||||
}
|
||||
|
||||
mday = day+1;
|
||||
|
||||
tm->tm_sec = sec;
|
||||
tm->tm_min = min;
|
||||
tm->tm_hour= hour;
|
||||
tm->tm_mday= mday;
|
||||
tm->tm_mon = month;
|
||||
tm->tm_year= year;
|
||||
tm->tm_wday= wday;
|
||||
tm->tm_yday= yday;
|
||||
|
||||
return tm;
|
||||
}
|
33
src/time/__tm_to_time.c
Normal file
33
src/time/__tm_to_time.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <time.h>
|
||||
|
||||
/* C defines the rounding for division in a nonsensical way */
|
||||
#define Q(a,b) ((a)>0 ? (a)/(b) : -(((b)-(a)-1)/(b)))
|
||||
|
||||
time_t __tm_to_time(struct tm *tm)
|
||||
{
|
||||
time_t year = tm->tm_year + -100;
|
||||
int month = tm->tm_mon;
|
||||
int day = tm->tm_mday;
|
||||
int z4, z100, z400;
|
||||
|
||||
/* normalize month */
|
||||
if (month >= 12) {
|
||||
year += month/12;
|
||||
month %= 12;
|
||||
} else if (month < 0) {
|
||||
year += month/12;
|
||||
month %= 12;
|
||||
if (month) {
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
}
|
||||
z4 = Q(year - (month < 2), 4);
|
||||
z100 = Q(z4, 25);
|
||||
z400 = Q(z100, 4);
|
||||
day += year*365 + z4 - z100 + z400 +
|
||||
month[(int []){0,31,59,90,120,151,181,212,243,273,304,335}];
|
||||
return (long long)day*86400
|
||||
+ tm->tm_hour*3600 + tm->tm_min*60 + tm->tm_sec
|
||||
- -946684800; /* the dawn of time :) */
|
||||
}
|
9
src/time/asctime.c
Normal file
9
src/time/asctime.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <time.h>
|
||||
|
||||
char *__asctime(const struct tm *, char *);
|
||||
|
||||
char *asctime(const struct tm *tm)
|
||||
{
|
||||
static char buf[26];
|
||||
return __asctime(tm, buf);
|
||||
}
|
8
src/time/asctime_r.c
Normal file
8
src/time/asctime_r.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <time.h>
|
||||
|
||||
char *__asctime(const struct tm *, char *);
|
||||
|
||||
char *asctime_r(const struct tm *tm, char *buf)
|
||||
{
|
||||
return __asctime(tm, buf);
|
||||
}
|
9
src/time/clock.c
Normal file
9
src/time/clock.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
/* this function assumes 100 hz linux and corrects for it */
|
||||
clock_t clock()
|
||||
{
|
||||
struct tms tms;
|
||||
return (unsigned long)times(&tms)*10000;
|
||||
}
|
7
src/time/clock_gettime.c
Normal file
7
src/time/clock_gettime.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <time.h>
|
||||
#include "syscall.h"
|
||||
|
||||
int clock_gettime(clockid_t clk, struct timespec *ts)
|
||||
{
|
||||
return syscall2(__NR_clock_gettime, clk, (long)ts);
|
||||
}
|
6
src/time/ctime.c
Normal file
6
src/time/ctime.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <time.h>
|
||||
|
||||
char *ctime(const time_t *t)
|
||||
{
|
||||
return asctime(localtime(t));
|
||||
}
|
8
src/time/ctime_r.c
Normal file
8
src/time/ctime_r.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <time.h>
|
||||
|
||||
char *ctime_r(const time_t *t, char *buf)
|
||||
{
|
||||
struct tm tm;
|
||||
localtime_r(t, &tm);
|
||||
return asctime_r(&tm, buf);
|
||||
}
|
6
src/time/difftime.c
Normal file
6
src/time/difftime.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <time.h>
|
||||
|
||||
double difftime(time_t t1, time_t t0)
|
||||
{
|
||||
return t1-t0;
|
||||
}
|
9
src/time/gettimeofday.c
Normal file
9
src/time/gettimeofday.c
Normal file
@ -0,0 +1,9 @@
|
||||
#define SYSCALL_RETURN_ERRNO
|
||||
#include <sys/time.h>
|
||||
#include "syscall.h"
|
||||
|
||||
int gettimeofday(struct timeval *tv, void *tz)
|
||||
{
|
||||
syscall2(__NR_gettimeofday, (long)tv, 0);
|
||||
return 0;
|
||||
}
|
11
src/time/gmtime.c
Normal file
11
src/time/gmtime.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "__time.h"
|
||||
|
||||
struct tm *gmtime(const time_t *t)
|
||||
{
|
||||
static struct tm tm;
|
||||
__time_to_tm(*t, &tm);
|
||||
tm.tm_isdst = 0;
|
||||
return &tm;
|
||||
}
|
10
src/time/gmtime_r.c
Normal file
10
src/time/gmtime_r.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "__time.h"
|
||||
|
||||
struct tm *gmtime_r(const time_t *t, struct tm *result)
|
||||
{
|
||||
__time_to_tm(*t, result);
|
||||
result->tm_isdst = 0;
|
||||
return result;
|
||||
}
|
12
src/time/localtime.c
Normal file
12
src/time/localtime.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "__time.h"
|
||||
|
||||
struct tm *localtime(const time_t *t)
|
||||
{
|
||||
static struct tm tm;
|
||||
__tzset();
|
||||
__time_to_tm(*t - __timezone, &tm);
|
||||
tm.tm_isdst = -1;
|
||||
return __dst_adjust(&tm);
|
||||
}
|
11
src/time/localtime_r.c
Normal file
11
src/time/localtime_r.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "__time.h"
|
||||
|
||||
struct tm *localtime_r(const time_t *t, struct tm *result)
|
||||
{
|
||||
__tzset();
|
||||
__time_to_tm(*t - __timezone, result);
|
||||
result->tm_isdst = -1;
|
||||
return __dst_adjust(result);
|
||||
}
|
24
src/time/mktime.c
Normal file
24
src/time/mktime.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "__time.h"
|
||||
|
||||
time_t mktime(struct tm *tm)
|
||||
{
|
||||
int isdst = tm->tm_isdst;
|
||||
time_t t, lt;
|
||||
|
||||
__tzset();
|
||||
|
||||
tm->tm_sec += __timezone;
|
||||
if (isdst > 0) tm->tm_sec += __dst_offset;
|
||||
|
||||
t = __tm_to_time(tm);
|
||||
|
||||
lt = t - __timezone;
|
||||
if (isdst > 0) lt -= __dst_offset;
|
||||
__time_to_tm(lt, tm);
|
||||
|
||||
__dst_adjust(tm);
|
||||
|
||||
return t;
|
||||
}
|
13
src/time/nanosleep.c
Normal file
13
src/time/nanosleep.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "syscall.h"
|
||||
#include "libc.h"
|
||||
|
||||
int nanosleep(const struct timespec *req, struct timespec *rem)
|
||||
{
|
||||
int ret;
|
||||
CANCELPT_BEGIN;
|
||||
ret = syscall2(__NR_nanosleep, (long)req, (long)rem);
|
||||
CANCELPT_END;
|
||||
return ret;
|
||||
}
|
172
src/time/strftime.c
Normal file
172
src/time/strftime.c
Normal file
@ -0,0 +1,172 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <langinfo.h>
|
||||
#include <time.h>
|
||||
#include "__time.h"
|
||||
|
||||
// FIXME: integer overflows
|
||||
|
||||
const char *__langinfo(nl_item);
|
||||
|
||||
size_t strftime(char *s, size_t n, const char *f, const struct tm *tm)
|
||||
{
|
||||
nl_item item;
|
||||
int val;
|
||||
const char *fmt;
|
||||
size_t l;
|
||||
for (l=0; *f && l<n; f++) {
|
||||
if (*f == '%') {
|
||||
do_fmt:
|
||||
switch (*++f) {
|
||||
case '%':
|
||||
goto literal;
|
||||
case 'E':
|
||||
case 'O':
|
||||
goto do_fmt;
|
||||
case 'a':
|
||||
item = ABDAY_1 + tm->tm_wday;
|
||||
goto nl_strcat;
|
||||
case 'A':
|
||||
item = DAY_1 + tm->tm_wday;
|
||||
goto nl_strcat;
|
||||
case 'h':
|
||||
case 'b':
|
||||
item = ABMON_1 + tm->tm_mon;
|
||||
goto nl_strcat;
|
||||
case 'B':
|
||||
item = MON_1 + tm->tm_mon;
|
||||
goto nl_strcat;
|
||||
case 'c':
|
||||
item = D_T_FMT;
|
||||
goto nl_strftime;
|
||||
case 'C':
|
||||
val = (1900+tm->tm_year) / 100;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'd':
|
||||
val = tm->tm_mday;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'D':
|
||||
fmt = "%m/%d/%y";
|
||||
goto recu_strftime;
|
||||
case 'e':
|
||||
val = tm->tm_mday;
|
||||
fmt = "%2d";
|
||||
goto number;
|
||||
case 'F':
|
||||
fmt = "%Y-%m-%d";
|
||||
goto recu_strftime;
|
||||
case 'g':
|
||||
// FIXME
|
||||
val = 0; //week_based_year(tm)%100;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'G':
|
||||
// FIXME
|
||||
val = 0; //week_based_year(tm);
|
||||
fmt = "%04d";
|
||||
goto number;
|
||||
case 'H':
|
||||
val = tm->tm_hour;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'I':
|
||||
val = tm->tm_hour;
|
||||
if (!val) val = 12;
|
||||
else if (val > 12) val -= 12;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'j':
|
||||
val = tm->tm_yday+1;
|
||||
fmt = "%03d";
|
||||
goto number;
|
||||
case 'm':
|
||||
val = tm->tm_mon+1;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'M':
|
||||
val = tm->tm_min;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'n':
|
||||
s[l++] = '\n';
|
||||
continue;
|
||||
case 'p':
|
||||
item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
|
||||
goto nl_strcat;
|
||||
case 'r':
|
||||
item = T_FMT_AMPM;
|
||||
goto nl_strftime;
|
||||
case 'R':
|
||||
fmt = "%H:%M";
|
||||
goto recu_strftime;
|
||||
case 'S':
|
||||
val = tm->tm_sec;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 't':
|
||||
s[l++] = '\t';
|
||||
continue;
|
||||
case 'T':
|
||||
fmt = "%H:%M:%S";
|
||||
goto recu_strftime;
|
||||
case 'u':
|
||||
val = tm->tm_wday ? tm->tm_wday : 7;
|
||||
fmt = "%d";
|
||||
goto number;
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
// FIXME: week number mess..
|
||||
continue;
|
||||
case 'w':
|
||||
val = tm->tm_wday;
|
||||
fmt = "%d";
|
||||
goto number;
|
||||
case 'x':
|
||||
item = D_FMT;
|
||||
goto nl_strftime;
|
||||
case 'X':
|
||||
item = T_FMT;
|
||||
goto nl_strftime;
|
||||
case 'y':
|
||||
val = tm->tm_year % 100;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'Y':
|
||||
val = tm->tm_year + 1900;
|
||||
fmt = "%04d";
|
||||
goto number;
|
||||
case 'z':
|
||||
if (tm->tm_isdst < 0) continue;
|
||||
val = -__timezone - (tm->tm_isdst ? __dst_offset : 0);
|
||||
l += snprintf(s+l, n-l, "%+.2d%.2d", val/3600, abs(val%3600)/60);
|
||||
continue;
|
||||
case 'Z':
|
||||
if (tm->tm_isdst < 0 || !__tzname[0] || !__tzname[0][0])
|
||||
continue;
|
||||
l += snprintf(s+l, n-l, "%s", __tzname[!!tm->tm_isdst]);
|
||||
continue;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
literal:
|
||||
s[l++] = *f;
|
||||
continue;
|
||||
number:
|
||||
l += snprintf(s+l, n-l, fmt, val);
|
||||
continue;
|
||||
nl_strcat:
|
||||
l += snprintf(s+l, n-l, "%s", __langinfo(item));
|
||||
continue;
|
||||
nl_strftime:
|
||||
fmt = __langinfo(item);
|
||||
recu_strftime:
|
||||
l += strftime(s+l, n-l, fmt, tm);
|
||||
}
|
||||
if (l >= n) return 0;
|
||||
s[l] = 0;
|
||||
return l;
|
||||
}
|
178
src/time/strptime.c
Normal file
178
src/time/strptime.c
Normal file
@ -0,0 +1,178 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <langinfo.h>
|
||||
#include <time.h>
|
||||
|
||||
const char *__langinfo(nl_item);
|
||||
|
||||
char *strptime(const char *s, const char *f, struct tm *tm)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
char *strptime(const char *s, const char *f, struct tm *tm)
|
||||
{
|
||||
nl_item item;
|
||||
int *dest;
|
||||
const char *fmt;
|
||||
for (; *f; f++) {
|
||||
if (isspace(*f)) goto whitespace;
|
||||
if (*f == '%') {
|
||||
do_fmt:
|
||||
switch (*++f) {
|
||||
case '%':
|
||||
goto literal;
|
||||
case 'E':
|
||||
case 'O':
|
||||
goto do_fmt;
|
||||
case 'a':
|
||||
item = ABDAY_1 + tm->tm_wday;
|
||||
goto nl_strcat;
|
||||
case 'A':
|
||||
item = DAY_1 + tm->tm_wday;
|
||||
goto nl_strcat;
|
||||
case 'h':
|
||||
case 'b':
|
||||
item = ABMON_1 + tm->tm_mon;
|
||||
goto nl_strcat;
|
||||
case 'B':
|
||||
item = MON_1 + tm->tm_mon;
|
||||
goto nl_strcat;
|
||||
case 'c':
|
||||
item = D_T_FMT;
|
||||
goto nl_strftime;
|
||||
case 'C':
|
||||
val = (1900+tm->tm_year) / 100;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'd':
|
||||
val = tm->tm_mday;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'D':
|
||||
fmt = "%m/%d/%y";
|
||||
goto recu_strftime;
|
||||
case 'e':
|
||||
val = tm->tm_mday;
|
||||
fmt = "%2d";
|
||||
goto number;
|
||||
case 'F':
|
||||
fmt = "%Y-%m-%d";
|
||||
goto recu_strftime;
|
||||
case 'g':
|
||||
// FIXME
|
||||
val = 0; //week_based_year(tm)%100;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'G':
|
||||
// FIXME
|
||||
val = 0; //week_based_year(tm);
|
||||
fmt = "%04d";
|
||||
goto number;
|
||||
case 'H':
|
||||
val = tm->tm_hour;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'I':
|
||||
val = tm->tm_hour;
|
||||
if (!val) val = 12;
|
||||
else if (val > 12) val -= 12;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'j':
|
||||
val = tm->tm_yday+1;
|
||||
fmt = "%03d";
|
||||
goto number;
|
||||
case 'm':
|
||||
val = tm->tm_mon+1;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'M':
|
||||
val = tm->tm_min;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'n':
|
||||
case 't':
|
||||
goto whitespace;
|
||||
case 'p':
|
||||
item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
|
||||
goto nl_strcat;
|
||||
case 'r':
|
||||
item = T_FMT_AMPM;
|
||||
goto nl_strftime;
|
||||
case 'R':
|
||||
fmt = "%H:%M";
|
||||
goto recu_strftime;
|
||||
case 'S':
|
||||
val = tm->tm_sec;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'T':
|
||||
fmt = "%H:%M:%S";
|
||||
goto recu_strftime;
|
||||
case 'u':
|
||||
val = tm->tm_wday ? tm->tm_wday : 7;
|
||||
fmt = "%d";
|
||||
goto number;
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
// FIXME: week number mess..
|
||||
continue;
|
||||
case 'w':
|
||||
val = tm->tm_wday;
|
||||
fmt = "%d";
|
||||
goto number;
|
||||
case 'x':
|
||||
item = D_FMT;
|
||||
goto nl_strftime;
|
||||
case 'X':
|
||||
item = T_FMT;
|
||||
goto nl_strftime;
|
||||
case 'y':
|
||||
val = tm->tm_year % 100;
|
||||
fmt = "%02d";
|
||||
goto number;
|
||||
case 'Y':
|
||||
val = tm->tm_year + 1900;
|
||||
fmt = "%04d";
|
||||
goto number;
|
||||
case 'z':
|
||||
if (tm->tm_isdst < 0) continue;
|
||||
val = timezone + (tm->tm_isdst) ? __dst_offset : 0;
|
||||
l += snprintf(s+l, n-l, "%+02d%02d", val/60, abs(val%60));
|
||||
continue;
|
||||
case 'Z':
|
||||
if (tm->tm_isdst < 0 || !tzname[0] || !tzname[0][0])
|
||||
continue;
|
||||
l += snprintf(s+l, n-l, "%s", tzname[!!tm->tm_isdst]);
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
literal:
|
||||
if (*s++ != *f) return NULL;
|
||||
continue;
|
||||
whitespace:
|
||||
while(isspace(*s)) s++;
|
||||
continue;
|
||||
number:
|
||||
l += snprintf(s+l, n-l, fmt, val);
|
||||
continue;
|
||||
nl_strcat:
|
||||
l += snprintf(s+l, n-l, "%s", __langinfo(item));
|
||||
continue;
|
||||
nl_strftime:
|
||||
fmt = __langinfo(item);
|
||||
recu_strftime:
|
||||
l += strftime(s+l, n-l, fmt, tm);
|
||||
}
|
||||
if (l >= n) return 0;
|
||||
s[l] = 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
#endif
|
12
src/time/time.c
Normal file
12
src/time/time.c
Normal file
@ -0,0 +1,12 @@
|
||||
#define SYSCALL_RETURN_ERRNO
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "syscall.h"
|
||||
|
||||
time_t time(time_t *t)
|
||||
{
|
||||
struct timeval tv;
|
||||
syscall2(__NR_gettimeofday, (long)&tv, 0);
|
||||
if (t) *t = tv.tv_sec;
|
||||
return tv.tv_sec;
|
||||
}
|
7
src/time/times.c
Normal file
7
src/time/times.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <sys/times.h>
|
||||
#include "syscall.h"
|
||||
|
||||
clock_t times(struct tms *tms)
|
||||
{
|
||||
return syscall1(__NR_times, (long)&tms);
|
||||
}
|
27
src/time/timezone.s
Normal file
27
src/time/timezone.s
Normal file
@ -0,0 +1,27 @@
|
||||
.data
|
||||
|
||||
.global timezone
|
||||
.global __timezone
|
||||
.global daylight
|
||||
.global __daylight
|
||||
.global tzname
|
||||
.global __tzname
|
||||
|
||||
__timezone:
|
||||
timezone:
|
||||
.long 0
|
||||
.size timezone,.-timezone
|
||||
.size __timezone,.-__timezone
|
||||
|
||||
__daylight:
|
||||
daylight:
|
||||
.long 0
|
||||
.size daylight,.-daylight
|
||||
.size __daylight,.-__daylight
|
||||
|
||||
__tzname:
|
||||
tzname:
|
||||
.long 0
|
||||
.long 0
|
||||
.size tzname,.-tzname
|
||||
.size __tzname,.-__tzname
|
173
src/time/tzset.c
Normal file
173
src/time/tzset.c
Normal file
@ -0,0 +1,173 @@
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libc.h"
|
||||
|
||||
#include "__time.h"
|
||||
|
||||
long __timezone = 0;
|
||||
int __daylight = 0;
|
||||
char *__tzname[2] = { 0, 0 };
|
||||
int __dst_offset = 0;
|
||||
|
||||
weak_alias(__timezone, timezone);
|
||||
weak_alias(__daylight, daylight);
|
||||
weak_alias(__tzname, tzname);
|
||||
weak_alias(__dst_offset, dst_offset);
|
||||
|
||||
static char std_name[TZNAME_MAX+1];
|
||||
static char dst_name[TZNAME_MAX+1];
|
||||
|
||||
/* all elements are zero-based */
|
||||
static struct rule {
|
||||
char month;
|
||||
char week;
|
||||
short day;
|
||||
int time;
|
||||
} __dst_start, __dst_end;
|
||||
|
||||
static void zname(char *d, char **s)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<TZNAME_MAX && isalpha(d[i]=**s); i++, (*s)++);
|
||||
d[i] = 0;
|
||||
}
|
||||
|
||||
static int hhmmss(char **s)
|
||||
{
|
||||
int ofs = strtol(*s, s, 10)*3600;
|
||||
if (ofs >= 0) {
|
||||
if (**s == ':') ofs += strtol(*s+1, s, 10)*60;
|
||||
if (**s == ':') ofs += strtol(*s+1, s, 10);
|
||||
} else {
|
||||
if (**s == ':') ofs -= strtol(*s+1, s, 10)*60;
|
||||
if (**s == ':') ofs -= strtol(*s+1, s, 10);
|
||||
}
|
||||
return ofs;
|
||||
}
|
||||
|
||||
static int dstrule(struct rule *rule, char **s)
|
||||
{
|
||||
if (**s != ',') return -1;
|
||||
switch (*++*s) {
|
||||
case 'J':
|
||||
rule->month = 'J';
|
||||
rule->day = strtol(*s+1, s, 10)-1;
|
||||
break;
|
||||
case 'M':
|
||||
rule->month = strtol(*s+1, s, 10)-1;
|
||||
if (**s != '.' || rule->month < 0 || rule->month > 11)
|
||||
return -1;
|
||||
rule->week = strtol(*s+1, s, 10)-1;
|
||||
if (**s != '.' || rule->week < 0 || rule->week > 4)
|
||||
return -1;
|
||||
rule->day = strtol(*s+1, s, 10);
|
||||
if (rule->day < 0 || rule->day > 6)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
rule->month = 'L';
|
||||
rule->day = strtol(*s+1, s, 10);
|
||||
break;
|
||||
}
|
||||
if (**s == '/') {
|
||||
(*s)++;
|
||||
rule->time = hhmmss(s);
|
||||
} else rule->time = 7200;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tzset(void)
|
||||
{
|
||||
char *z, *a;
|
||||
|
||||
strcpy(std_name, "GMT");
|
||||
strcpy(dst_name, "GMT");
|
||||
__tzname[0] = std_name;
|
||||
__tzname[1] = dst_name;
|
||||
__timezone = 0;
|
||||
__daylight = 0;
|
||||
|
||||
if (!(z = getenv("TZ")) || !isalpha(*z)) return;
|
||||
|
||||
zname(std_name, &z);
|
||||
__timezone = hhmmss(&z);
|
||||
|
||||
zname(dst_name, &z);
|
||||
if (dst_name[0]) __daylight=1;
|
||||
a = z;
|
||||
__dst_offset = hhmmss(&z) - __timezone;
|
||||
if (z==a) __dst_offset = -3600;
|
||||
|
||||
if (dstrule(&__dst_start, &z) || dstrule(&__dst_end, &z))
|
||||
__daylight = 0;
|
||||
}
|
||||
|
||||
void __tzset(void)
|
||||
{
|
||||
static int lock, init;
|
||||
if (init) return;
|
||||
LOCK(&lock);
|
||||
if (!init) tzset();
|
||||
init=1;
|
||||
UNLOCK(&lock);
|
||||
}
|
||||
|
||||
static int is_leap(int year)
|
||||
{
|
||||
year -= 100;
|
||||
return !(year&3) && ((year%100) || !(year%400));
|
||||
}
|
||||
|
||||
static int cutoff_yday(struct tm *tm, struct rule *rule)
|
||||
{
|
||||
static const char days_in_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static const int first_day[] = {0,31,59,90,120,151,181,212,243,273,304,335};
|
||||
int yday, mday, leap;
|
||||
|
||||
switch (rule->month) {
|
||||
case 'J':
|
||||
return rule->day + (tm->tm_mon > 1 && is_leap(tm->tm_year));
|
||||
case 'L':
|
||||
return rule->day;
|
||||
default:
|
||||
yday = first_day[rule->month];
|
||||
leap = is_leap(tm->tm_year);
|
||||
if (rule->month > 1 && leap) yday++;
|
||||
mday = (rule->day - (yday + tm->tm_wday - tm->tm_yday) + 1400)%7 + 7*rule->week;
|
||||
if (mday >= days_in_month[rule->month] + (leap && rule->month == 1))
|
||||
mday -= 7;
|
||||
return mday + yday;
|
||||
}
|
||||
}
|
||||
|
||||
struct tm *__dst_adjust(struct tm *tm)
|
||||
{
|
||||
time_t t;
|
||||
int start, end, secs;
|
||||
int after_start, before_end;
|
||||
|
||||
if (tm->tm_isdst >= 0) return tm;
|
||||
if (!__daylight) {
|
||||
tm->tm_isdst = 0;
|
||||
return tm;
|
||||
}
|
||||
|
||||
secs = tm->tm_hour*3600 + tm->tm_min*60 + tm->tm_sec;
|
||||
start = cutoff_yday(tm, &__dst_start);
|
||||
end = cutoff_yday(tm, &__dst_end);
|
||||
|
||||
after_start = (tm->tm_yday > start || (tm->tm_yday == start && secs >= __dst_start.time));
|
||||
before_end = (tm->tm_yday < end || (tm->tm_yday == end && secs < __dst_end.time));
|
||||
|
||||
if ((after_start && before_end) || ((end < start) && (after_start || before_end))) {
|
||||
tm->tm_sec -= __dst_offset;
|
||||
tm->tm_isdst = 1;
|
||||
t = __tm_to_time(tm);
|
||||
return __time_to_tm(t, tm);
|
||||
} else tm->tm_isdst = 0;
|
||||
|
||||
return tm;
|
||||
}
|
12
src/time/utime.c
Normal file
12
src/time/utime.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <utime.h>
|
||||
#include "syscall.h"
|
||||
|
||||
int utime(const char *path, const struct utimbuf *times)
|
||||
{
|
||||
long ktimes[2];
|
||||
if (times) {
|
||||
ktimes[0] = times->actime;
|
||||
ktimes[1] = times->modtime;
|
||||
}
|
||||
return syscall2(__NR_utime, (long)path, times ? (long)ktimes : 0);
|
||||
}
|
Reference in New Issue
Block a user