mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 23:08:31 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
48
libc/time/alarm.c
Normal file
48
libc/time/alarm.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/struct/itimerval.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/itimer.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Asks for single-shot SIGALRM to be raise()'d after interval.
|
||||
*
|
||||
* @param seconds until we get signal, or 0 to reset previous alarm()
|
||||
* @return seconds previous alarm() had remaining, or -1u w/ errno
|
||||
* @see setitimer()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
unsigned alarm(unsigned seconds) {
|
||||
int rc;
|
||||
struct itimerval it;
|
||||
memset(&it, 0, sizeof(it));
|
||||
it.it_value.tv_sec = seconds;
|
||||
rc = setitimer(ITIMER_REAL, &it, &it);
|
||||
assert(rc != -1);
|
||||
if (!it.it_value.tv_sec && !it.it_value.tv_usec) {
|
||||
return 0;
|
||||
} else {
|
||||
return MIN(1, it.it_value.tv_sec + (it.it_value.tv_usec > 5000000));
|
||||
}
|
||||
}
|
24
libc/time/asctime.c
Normal file
24
libc/time/asctime.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/time/time.h"
|
||||
|
||||
static char g_asctime_buf[64];
|
||||
|
||||
char *asctime(const struct tm *date) { return asctime_r(date, g_asctime_buf); }
|
37
libc/time/asctime_r.c
Normal file
37
libc/time/asctime_r.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
STATIC_YOINK("ntoa");
|
||||
STATIC_YOINK("stoa");
|
||||
|
||||
static unsigned clip(unsigned index, unsigned count) {
|
||||
return index < count ? index : 0;
|
||||
}
|
||||
|
||||
char *asctime_r(const struct tm *date, char *buf /*[64]*/) {
|
||||
(snprintf)(buf, 64, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
|
||||
kWeekdayNameShort[clip(date->tm_wday, 7)],
|
||||
kMonthNameShort[clip(date->tm_mon, 12)], date->tm_mday,
|
||||
date->tm_hour, date->tm_min, date->tm_sec, 1900 + date->tm_year);
|
||||
return buf;
|
||||
}
|
34
libc/time/clock.c
Normal file
34
libc/time/clock.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns how much CPU program has consumed on time-sharing system.
|
||||
*
|
||||
* @return value that can be divided by CLOCKS_PER_SEC, or -1 w/ errno
|
||||
*/
|
||||
int64_t clock(void) {
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) return -1;
|
||||
return ts.tv_sec * CLOCKS_PER_SEC +
|
||||
ts.tv_nsec / (1000000000 / CLOCKS_PER_SEC);
|
||||
}
|
76
libc/time/clock_gettime.c
Normal file
76
libc/time/clock_gettime.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mach.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/nt/struct/systemtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns nanosecond time.
|
||||
*
|
||||
* This is a high-precision timer that supports multiple definitions of
|
||||
* time. Among the more popular is CLOCK_MONOTONIC. This function has a
|
||||
* zero syscall implementation of that on modern x86.
|
||||
*
|
||||
* @param clockid can be CLOCK_REALTIME, CLOCK_MONOTONIC, etc. noting
|
||||
* that on Linux CLOCK_MONOTONIC is redefined to use the monotonic
|
||||
* clock that's actually monotonic lool
|
||||
* @param out_ts is where the nanoseconds are stored
|
||||
* @return 0 on success or -1 w/ errno on error
|
||||
* @error ENOSYS if clockid isn't available; in which case this function
|
||||
* guarantees an ordinary timestamp is still stored to out_ts; and
|
||||
* errno isn't restored to its original value, to detect prec. loss
|
||||
* @see strftime(), gettimeofday()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int clock_gettime(int clockid, struct timespec *out_ts) {
|
||||
/* TODO(jart): Just ignore O/S for MONOTONIC and measure RDTSC on start */
|
||||
if (!IsWindows()) {
|
||||
if (!IsXnu()) {
|
||||
out_ts->tv_sec = 0;
|
||||
out_ts->tv_nsec = 0;
|
||||
return clock_gettime$sysv(clockid, out_ts);
|
||||
} else {
|
||||
static_assert(sizeof(struct timeval) == sizeof(struct timespec));
|
||||
out_ts->tv_sec = 0;
|
||||
out_ts->tv_nsec = 0;
|
||||
int rc = gettimeofday$sysv((struct timeval *)out_ts, NULL);
|
||||
out_ts->tv_nsec *= 1000;
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
struct NtFileTime ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
filetimetotimespec(out_ts, ft);
|
||||
return 0;
|
||||
}
|
||||
}
|
22
libc/time/ctime.c
Normal file
22
libc/time/ctime.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/time/time.h"
|
||||
|
||||
char *ctime(const int64_t *timep) { return asctime(localtime(timep)); }
|
26
libc/time/ctime_r.c
Normal file
26
libc/time/ctime_r.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
char *ctime_r(const int64_t *timep, char *buf /*[64]*/) {
|
||||
struct tm date[1];
|
||||
return asctime_r(localtime_r(timep, date), buf);
|
||||
}
|
22
libc/time/difftime.c
Normal file
22
libc/time/difftime.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/time/time.h"
|
||||
|
||||
double difftime(int64_t x, int64_t y) { return x - y; }
|
42
libc/time/dsleep.c
Normal file
42
libc/time/dsleep.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Sleeps w/ higher precision.
|
||||
*/
|
||||
long double dsleep(long double secs) {
|
||||
struct timespec dur, rem;
|
||||
dur.tv_sec = secs;
|
||||
dur.tv_nsec = secs * 1e9;
|
||||
dur.tv_nsec = mod1000000000int64(dur.tv_nsec);
|
||||
if (secs > 1e-6) {
|
||||
nanosleep(&dur, &rem);
|
||||
secs = rem.tv_nsec;
|
||||
secs *= 1 / 1e9;
|
||||
secs += rem.tv_sec;
|
||||
return secs;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
37
libc/time/dtime.c
Normal file
37
libc/time/dtime.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns seconds since epoch w/ high-precision.
|
||||
* @param clockid can be CLOCK_{REALTIME,MONOTONIC}, etc.
|
||||
*/
|
||||
long double dtime(int clockid) {
|
||||
long double secs;
|
||||
struct timespec tv;
|
||||
clock_gettime(clockid, &tv);
|
||||
secs = tv.tv_nsec;
|
||||
secs *= 1 / 1e9;
|
||||
secs += tv.tv_sec;
|
||||
return secs;
|
||||
}
|
37
libc/time/getitimer.c
Normal file
37
libc/time/getitimer.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Retrieves last setitimer() value, correcting for remaining time.
|
||||
*
|
||||
* @param which can be ITIMER_REAL, ITIMER_VIRTUAL, etc.
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int getitimer(int which, struct itimerval *curvalue) {
|
||||
if (!IsWindows()) {
|
||||
int getitimer$sysv(int, struct itimerval *) hidden;
|
||||
return getitimer$sysv(which, curvalue);
|
||||
} else {
|
||||
return enosys(); /* TODO(jart): Implement me! */
|
||||
}
|
||||
}
|
35
libc/time/gettimeofday-nt.c
Normal file
35
libc/time/gettimeofday-nt.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/nt/struct/systemtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/time/struct/timezone.h"
|
||||
|
||||
int gettimeofday$nt(struct timeval *tv, struct timezone *tz) {
|
||||
struct NtFileTime ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
filetimetotimeval(tv, ft);
|
||||
if (tz) memset(tz, 0, sizeof(*tz));
|
||||
return 0;
|
||||
}
|
54
libc/time/gettimeofday-sysv.S
Normal file
54
libc/time/gettimeofday-sysv.S
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
/ Returns system wall time in microseconds.
|
||||
/
|
||||
/ @param rdi points to timeval that receives result
|
||||
/ @param rsi receives UTC timezone if non-NULL
|
||||
/ @return always zero
|
||||
/ @see clock_gettime() for nanosecond precision
|
||||
/ @see strftime() for string formatting
|
||||
gettimeofday$sysv:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
test %rsi,%rsi
|
||||
jz 1f
|
||||
push $0
|
||||
pop (%rsi)
|
||||
1: xor %esi,%esi # no one zones this way.
|
||||
xor %edx,%edx # i64*mach_absolute_time
|
||||
call __gettimeofday$sysv
|
||||
#if SupportsXnu()
|
||||
testb IsXnu() # XNU might do %rax:%rdx
|
||||
jz 1f
|
||||
test %rdi,%rdi
|
||||
jz 1f
|
||||
test %rax,%rax
|
||||
jz 1f
|
||||
mov %rax,(%rdi)
|
||||
mov %rdx,8(%rdi)
|
||||
#endif
|
||||
1: xor %eax,%eax # nevar fail
|
||||
pop %rbp
|
||||
ret
|
||||
.endfn gettimeofday$sysv,globl,hidden
|
39
libc/time/gettimeofday.c
Normal file
39
libc/time/gettimeofday.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns system wall time in microseconds.
|
||||
*
|
||||
* @param tv points to timeval that receives result
|
||||
* @param tz receives UTC timezone if non-NULL
|
||||
* @return always zero
|
||||
* @see clock_gettime() for nanosecond precision
|
||||
* @see strftime() for string formatting
|
||||
*/
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz) {
|
||||
if (!IsWindows()) {
|
||||
return gettimeofday$sysv(tv, tz);
|
||||
} else {
|
||||
return gettimeofday$nt(tv, tz);
|
||||
}
|
||||
}
|
28
libc/time/kmonthname.S
Normal file
28
libc/time/kmonthname.S
Normal file
|
@ -0,0 +1,28 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/macros.inc"
|
||||
|
||||
/ extern const char kMonthName[12][10];
|
||||
.section .rodata,"aS",@progbits
|
||||
kMonthName:
|
||||
.ascin "January",10
|
||||
.ascin "February",10
|
||||
.ascin "March",10
|
||||
.ascin "April",10
|
||||
.ascin "May",10
|
||||
.ascin "June",10
|
||||
.ascin "July",10
|
||||
.ascin "August",10
|
||||
.ascin "September",10
|
||||
.ascin "October",10
|
||||
.ascin "November",10
|
||||
.ascin "December",10
|
||||
.endobj kMonthName,globl
|
||||
.previous
|
34
libc/time/kmonthnameshort.S
Normal file
34
libc/time/kmonthnameshort.S
Normal file
|
@ -0,0 +1,34 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/macros.inc"
|
||||
|
||||
/ Type #1:
|
||||
/ - Indexable C-String Array
|
||||
/ - extern const char kMonthNameShort[12][4];
|
||||
/ Type #2:
|
||||
/ - Double-NUL Terminated String
|
||||
/ - extern const char kMonthNameShort[];
|
||||
.section .rodata,"aS",@progbits
|
||||
kMonthNameShort:
|
||||
.ascin "Jan",4
|
||||
.ascin "Feb",4
|
||||
.ascin "Mar",4
|
||||
.ascin "Apr",4
|
||||
.ascin "May",4
|
||||
.ascin "Jun",4
|
||||
.ascin "Jul",4
|
||||
.ascin "Aug",4
|
||||
.ascin "Sep",4
|
||||
.ascin "Oct",4
|
||||
.ascin "Nov",4
|
||||
.ascin "Dec",4
|
||||
.byte 0
|
||||
.endobj kMonthNameShort,globl
|
||||
.previous
|
23
libc/time/kweekdayname.S
Normal file
23
libc/time/kweekdayname.S
Normal file
|
@ -0,0 +1,23 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/macros.inc"
|
||||
|
||||
/ extern const char kWeekdayName[7][10];
|
||||
.section .rodata,"aS",@progbits
|
||||
kWeekdayName:
|
||||
.ascin "Sunday",10
|
||||
.ascin "Monday",10
|
||||
.ascin "Tuesday",10
|
||||
.ascin "Wednesday",10
|
||||
.ascin "Thursday",10
|
||||
.ascin "Friday",10
|
||||
.ascin "Saturday",10
|
||||
.endobj kWeekdayName,globl
|
||||
.previous
|
29
libc/time/kweekdaynameshort.S
Normal file
29
libc/time/kweekdaynameshort.S
Normal file
|
@ -0,0 +1,29 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/macros.inc"
|
||||
|
||||
/ Type #1:
|
||||
/ - Indexable C-String Array
|
||||
/ - extern const char kWeekdayNameShort[7][4];
|
||||
/ Type #2:
|
||||
/ - Double-NUL Terminated String
|
||||
/ - extern const char kWeekdayNameShort[];
|
||||
.section .rodata,"aS",@progbits
|
||||
kWeekdayNameShort:
|
||||
.asciz "Sun"
|
||||
.asciz "Mon"
|
||||
.asciz "Tue"
|
||||
.asciz "Wed"
|
||||
.asciz "Thu"
|
||||
.asciz "Fri"
|
||||
.asciz "Sat"
|
||||
.byte 0
|
||||
.endobj kWeekdayNameShort,globl
|
||||
.previous
|
2045
libc/time/localtime.c
Normal file
2045
libc/time/localtime.c
Normal file
File diff suppressed because it is too large
Load diff
58
libc/time/nanosleep.c
Normal file
58
libc/time/nanosleep.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nt/enum/status.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/nt/time.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Sleeps for a particular amount of time.
|
||||
*/
|
||||
int nanosleep(const struct timespec *req, struct timespec *rem) {
|
||||
long res, millis, hectonanos;
|
||||
if (!IsWindows()) {
|
||||
if (!IsXnu()) {
|
||||
return nanosleep$sysv(req, rem);
|
||||
} else {
|
||||
return select$sysv(0, 0, 0, 0, /* lool */
|
||||
&(struct timeval){req->tv_sec, req->tv_nsec / 1000});
|
||||
}
|
||||
} else {
|
||||
if (req->tv_sec && req->tv_nsec) {
|
||||
hectonanos = MAX(1, req->tv_sec * 10000000L + req->tv_nsec / 100L);
|
||||
} else {
|
||||
hectonanos = 1;
|
||||
}
|
||||
if (NtError(NtDelayExecution(true, &hectonanos))) {
|
||||
millis = hectonanos / 10000;
|
||||
res = SleepEx(millis, true);
|
||||
if (res == kNtWaitIoCompletion) return eintr();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
89
libc/time/now.c
Normal file
89
libc/time/now.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
static struct Now {
|
||||
uint64_t k0;
|
||||
long double r0, cpn;
|
||||
} now_;
|
||||
|
||||
/**
|
||||
* Returns timestamp without needing system calls.
|
||||
* @note uses microsecond scale fallback on k8 or vm
|
||||
*/
|
||||
long double (*nowl)(void);
|
||||
|
||||
long double converttickstonanos(uint64_t ticks) {
|
||||
return ticks * now_.cpn; /* pico scale */
|
||||
}
|
||||
|
||||
long double converttickstoseconds(uint64_t ticks) {
|
||||
return 1 / 1e9 * converttickstonanos(ticks);
|
||||
}
|
||||
|
||||
static long double nowl$sys(void) {
|
||||
return dtime(CLOCK_REALTIME);
|
||||
}
|
||||
|
||||
static long double nowl$art(void) {
|
||||
uint64_t ticks;
|
||||
ticks = unsignedsubtract(rdtsc(), now_.k0);
|
||||
return now_.r0 + converttickstoseconds(ticks);
|
||||
}
|
||||
|
||||
static long double GetSample(void) {
|
||||
uint64_t tick1, tick2;
|
||||
long double time1, time2;
|
||||
sched_yield();
|
||||
time1 = dtime(CLOCK_MONOTONIC);
|
||||
tick1 = rdtsc();
|
||||
nanosleep(&(struct timespec){0, 100000}, NULL);
|
||||
time2 = dtime(CLOCK_MONOTONIC);
|
||||
tick2 = rdtsc();
|
||||
return (time2 - time1) * 1e9 / (tick2 - tick1);
|
||||
}
|
||||
|
||||
static long double MeasureNanosPerCycle(void) {
|
||||
int i;
|
||||
long double avg, samp;
|
||||
for (avg = 1.0L, i = 1; i < 5; ++i) {
|
||||
samp = GetSample();
|
||||
avg += (samp - avg) / i;
|
||||
}
|
||||
return avg;
|
||||
}
|
||||
|
||||
INITIALIZER(301, _init_time, {
|
||||
if (X86_HAVE(INVTSC)) {
|
||||
now_.cpn = MeasureNanosPerCycle();
|
||||
now_.r0 = dtime(CLOCK_REALTIME);
|
||||
now_.k0 = rdtsc();
|
||||
nowl = nowl$art;
|
||||
} else {
|
||||
nowl = nowl$sys;
|
||||
}
|
||||
})
|
54
libc/time/setitimer.c
Normal file
54
libc/time/setitimer.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/itimerval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Schedules delivery of one-shot or intermittent wakeup signal, e.g.
|
||||
*
|
||||
* CHECK_NE(-1, sigaction(SIGALRM,
|
||||
* &(struct sigaction){.sa_sigaction = missingno,
|
||||
* .sa_flags = SA_RESETHAND},
|
||||
* NULL));
|
||||
* CHECK_NE(-1, setitimer(ITIMER_REAL,
|
||||
* &(const struct itimerval){{0, 0}, {0, 50000}},
|
||||
* NULL));
|
||||
* if (connect(...) == -1 && errno == EINTR) { ... }
|
||||
* CHECK_NE(-1, setitimer(ITIMER_REAL,
|
||||
* &(const struct itimerval){{0, 0}, {0, 0}},
|
||||
* NULL));
|
||||
*
|
||||
* @param which can be ITIMER_REAL, ITIMER_VIRTUAL, etc.
|
||||
* @param newvalue specifies the interval ({0,0} means one-shot) and
|
||||
* duration ({0,0} means disarm) in microseconds
|
||||
* @param out_opt_old may receive remainder of previous op (if any)
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int setitimer(int which, const struct itimerval *newvalue,
|
||||
struct itimerval *out_opt_oldvalue) {
|
||||
if (!IsWindows()) {
|
||||
return setitimer$sysv(which, newvalue, out_opt_oldvalue);
|
||||
} else {
|
||||
return enosys(); /* TODO(jart): Implement me! */
|
||||
}
|
||||
}
|
29
libc/time/sleep.c
Normal file
29
libc/time/sleep.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Sleeps for a particular amount of time.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int sleep(uint32_t seconds) {
|
||||
return nanosleep(&(struct timespec){seconds, 0}, NULL);
|
||||
}
|
380
libc/time/strftime.c
Normal file
380
libc/time/strftime.c
Normal file
|
@ -0,0 +1,380 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright (c) 1989 The Regents of the University of California. │
|
||||
│ All rights reserved. │
|
||||
│ │
|
||||
│ Redistribution and use in source and binary forms are permitted │
|
||||
│ provided that the above copyright notice and this paragraph are │
|
||||
│ duplicated in all such forms and that any documentation, │
|
||||
│ advertising materials, and other materials related to such │
|
||||
│ distribution and use acknowledge that the software was developed │
|
||||
│ by the University of California, Berkeley. The name of the │
|
||||
│ University may not be used to endorse or promote products derived │
|
||||
│ from this software without specific prior written permission. │
|
||||
│ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR │
|
||||
│ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/tzfile.h"
|
||||
|
||||
STATIC_YOINK("ntoa");
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
strftime (BSD-3)\\n\
|
||||
Copyright 1989 The Regents of the University of California\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
static char *strftime_add(char *pt, const char *ptlim, const char *str) {
|
||||
while (pt < ptlim && (*pt = *str++) != '\0') ++pt;
|
||||
return pt;
|
||||
}
|
||||
|
||||
static char *strftime_conv(char *pt, const char *ptlim, int n,
|
||||
const char *format) {
|
||||
char buf[INT_STRLEN_MAXIMUM(int) + 1];
|
||||
(snprintf)(buf, sizeof(buf), format, n);
|
||||
return strftime_add(pt, ptlim, buf);
|
||||
}
|
||||
|
||||
static char *strftime_secs(char *pt, const char *ptlim, const struct tm *t) {
|
||||
static char buf[INT_STRLEN_MAXIMUM(int) + 1];
|
||||
struct tm tmp;
|
||||
int64_t s;
|
||||
tmp = *t; /* Make a copy, mktime(3) modifies the tm struct. */
|
||||
s = mktime(&tmp);
|
||||
(snprintf)(buf, sizeof(buf), "%ld", s);
|
||||
return strftime_add(pt, ptlim, buf);
|
||||
}
|
||||
|
||||
static char *strftime_timefmt(char *pt, const char *ptlim, const char *format,
|
||||
const struct tm *t) {
|
||||
int i;
|
||||
long diff;
|
||||
char const *sign;
|
||||
/* size_t z1, z2, z3; */
|
||||
for (; *format; ++format) {
|
||||
if (*format == '%') {
|
||||
label:
|
||||
switch (*++format) {
|
||||
case '\0':
|
||||
--format;
|
||||
break;
|
||||
case 'A':
|
||||
pt = strftime_add(pt, ptlim,
|
||||
(t->tm_wday < 0 || t->tm_wday > 6)
|
||||
? "?"
|
||||
: kWeekdayName[t->tm_wday]);
|
||||
continue;
|
||||
case 'a':
|
||||
pt = strftime_add(pt, ptlim,
|
||||
(t->tm_wday < 0 || t->tm_wday > 6)
|
||||
? "?"
|
||||
: kWeekdayNameShort[t->tm_wday]);
|
||||
continue;
|
||||
case 'B':
|
||||
pt = strftime_add(
|
||||
pt, ptlim,
|
||||
(t->tm_mon < 0 || t->tm_mon > 11) ? "?" : kMonthName[t->tm_mon]);
|
||||
continue;
|
||||
case 'b':
|
||||
case 'h':
|
||||
pt = strftime_add(pt, ptlim,
|
||||
(t->tm_mon < 0 || t->tm_mon > 11)
|
||||
? "?"
|
||||
: kMonthNameShort[t->tm_mon]);
|
||||
continue;
|
||||
case 'c':
|
||||
pt = strftime_timefmt(pt, ptlim, "%D %X", t);
|
||||
continue;
|
||||
case 'C':
|
||||
/*
|
||||
** %C used to do a...
|
||||
** strftime_timefmt("%a %b %e %X %Y", t);
|
||||
** ...whereas now POSIX 1003.2 calls for
|
||||
** something completely different.
|
||||
** (ado, 5/24/93)
|
||||
*/
|
||||
pt = strftime_conv(pt, ptlim, (t->tm_year + TM_YEAR_BASE) / 100,
|
||||
"%02d");
|
||||
continue;
|
||||
case 'D':
|
||||
pt = strftime_timefmt(pt, ptlim, "%m/%d/%y", t);
|
||||
continue;
|
||||
case 'x':
|
||||
/*
|
||||
** Version 3.0 of strftime from Arnold Robbins
|
||||
** (arnold@skeeve.atl.ga.us) does the
|
||||
** equivalent of...
|
||||
** strftime_timefmt("%a %b %e %Y");
|
||||
** ...for %x; since the X3J11 C language
|
||||
** standard calls for "date, using locale's
|
||||
** date format," anything goes. Using just
|
||||
** numbers (as here) makes Quakers happier.
|
||||
** Word from Paul Eggert (eggert@twinsun.com)
|
||||
** is that %Y-%m-%d is the ISO standard date
|
||||
** format, specified in ISO 2014 and later
|
||||
** ISO 8601:1988, with a summary available in
|
||||
** pub/doc/ISO/english/ISO8601.ps.Z on
|
||||
** ftp.uni-erlangen.de.
|
||||
** (ado, 5/30/93)
|
||||
*/
|
||||
pt = strftime_timefmt(pt, ptlim, "%m/%d/%y", t);
|
||||
continue;
|
||||
case 'd':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_mday, "%02d");
|
||||
continue;
|
||||
case 'E':
|
||||
case 'O':
|
||||
/*
|
||||
** POSIX locale extensions, a la
|
||||
** Arnold Robbins' strftime version 3.0.
|
||||
** The sequences
|
||||
** %Ec %EC %Ex %Ey %EY
|
||||
** %Od %oe %OH %OI %Om %OM
|
||||
** %OS %Ou %OU %OV %Ow %OW %Oy
|
||||
** are supposed to provide alternate
|
||||
** representations.
|
||||
** (ado, 5/24/93)
|
||||
*/
|
||||
goto label;
|
||||
case 'e':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_mday, "%2d");
|
||||
continue;
|
||||
case 'H':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_hour, "%02d");
|
||||
continue;
|
||||
case 'I':
|
||||
pt = strftime_conv(
|
||||
pt, ptlim, (t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%02d");
|
||||
continue;
|
||||
case 'j':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_yday + 1, "%03d");
|
||||
continue;
|
||||
case 'k':
|
||||
/*
|
||||
** This used to be...
|
||||
** strftime_conv(t->tm_hour % 12 ?
|
||||
** t->tm_hour % 12 : 12, 2, ' ');
|
||||
** ...and has been changed to the below to
|
||||
** match SunOS 4.1.1 and Arnold Robbins'
|
||||
** strftime version 3.0. That is, "%k" and
|
||||
** "%l" have been swapped.
|
||||
** (ado, 5/24/93)
|
||||
*/
|
||||
pt = strftime_conv(pt, ptlim, t->tm_hour, "%2d");
|
||||
continue;
|
||||
#ifdef KITCHEN_SINK
|
||||
case 'K':
|
||||
/*
|
||||
** After all this time, still unclaimed!
|
||||
*/
|
||||
pt = strftime_add(pt, ptlim, "kitchen sink");
|
||||
continue;
|
||||
#endif /* defined KITCHEN_SINK */
|
||||
case 'l':
|
||||
/*
|
||||
** This used to be...
|
||||
** strftime_conv(t->tm_hour, 2, ' ');
|
||||
** ...and has been changed to the below to
|
||||
** match SunOS 4.1.1 and Arnold Robbin's
|
||||
** strftime version 3.0. That is, "%k" and
|
||||
** "%l" have been swapped.
|
||||
** (ado, 5/24/93)
|
||||
*/
|
||||
pt = strftime_conv(pt, ptlim,
|
||||
(t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%2d");
|
||||
continue;
|
||||
case 'M':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_min, "%02d");
|
||||
continue;
|
||||
case 'm':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_mon + 1, "%02d");
|
||||
continue;
|
||||
case 'n':
|
||||
pt = strftime_add(pt, ptlim, "\n");
|
||||
continue;
|
||||
case 'p':
|
||||
pt = strftime_add(pt, ptlim, t->tm_hour >= 12 ? "PM" : "AM");
|
||||
continue;
|
||||
case 'R':
|
||||
pt = strftime_timefmt(pt, ptlim, "%H:%M", t);
|
||||
continue;
|
||||
case 'r':
|
||||
pt = strftime_timefmt(pt, ptlim, "%I:%M:%S %p", t);
|
||||
continue;
|
||||
case 'S':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_sec, "%02d");
|
||||
continue;
|
||||
case 's':
|
||||
pt = strftime_secs(pt, ptlim, t);
|
||||
continue;
|
||||
case 'T':
|
||||
case 'X':
|
||||
pt = strftime_timefmt(pt, ptlim, "%H:%M:%S", t);
|
||||
continue;
|
||||
case 't':
|
||||
pt = strftime_add(pt, ptlim, "\t");
|
||||
continue;
|
||||
case 'U':
|
||||
pt = strftime_conv(pt, ptlim, (t->tm_yday + 7 - t->tm_wday) / 7,
|
||||
"%02d");
|
||||
continue;
|
||||
case 'u':
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "ISO 8601: Weekday as a decimal number
|
||||
** [1 (Monday) - 7]"
|
||||
** (ado, 5/24/93)
|
||||
*/
|
||||
pt = strftime_conv(pt, ptlim, (t->tm_wday == 0) ? 7 : t->tm_wday,
|
||||
"%d");
|
||||
continue;
|
||||
case 'V':
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "the week number of the year (the first
|
||||
** Monday as the first day of week 1) as a
|
||||
** decimal number (01-53). The method for
|
||||
** determining the week number is as specified
|
||||
** by ISO 8601 (to wit: if the week containing
|
||||
** January 1 has four or more days in the new
|
||||
** year, then it is week 1, otherwise it is
|
||||
** week 53 of the previous year and the next
|
||||
** week is week 1)."
|
||||
** (ado, 5/24/93)
|
||||
*/
|
||||
/*
|
||||
** XXX--If January 1 falls on a Friday,
|
||||
** January 1-3 are part of week 53 of the
|
||||
** previous year. By analogy, if January
|
||||
** 1 falls on a Thursday, are December 29-31
|
||||
** of the PREVIOUS year part of week 1???
|
||||
** (ado 5/24/93)
|
||||
**
|
||||
** You are understood not to expect this.
|
||||
*/
|
||||
i = (t->tm_yday + 10 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7;
|
||||
if (i == 0) {
|
||||
/*
|
||||
** What day of the week does
|
||||
** January 1 fall on?
|
||||
*/
|
||||
i = t->tm_wday - (t->tm_yday - 1);
|
||||
/*
|
||||
** Fri Jan 1: 53
|
||||
** Sun Jan 1: 52
|
||||
** Sat Jan 1: 53 if previous
|
||||
** year a leap
|
||||
** year, else 52
|
||||
*/
|
||||
if (i == TM_FRIDAY)
|
||||
i = 53;
|
||||
else if (i == TM_SUNDAY)
|
||||
i = 52;
|
||||
else
|
||||
i = isleap(t->tm_year + TM_YEAR_BASE) ? 53 : 52;
|
||||
#ifdef XPG4_1994_04_09
|
||||
/*
|
||||
** As of 4/9/94, though,
|
||||
** XPG4 calls for 53
|
||||
** unconditionally.
|
||||
*/
|
||||
i = 53;
|
||||
#endif /* defined XPG4_1994_04_09 */
|
||||
}
|
||||
pt = strftime_conv(pt, ptlim, i, "%02d");
|
||||
continue;
|
||||
case 'v':
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "date as dd-bbb-YYYY"
|
||||
** (ado, 5/24/93)
|
||||
*/
|
||||
pt = strftime_timefmt(pt, ptlim, "%e-%b-%Y", t);
|
||||
continue;
|
||||
case 'W':
|
||||
pt = strftime_conv(
|
||||
pt, ptlim,
|
||||
(t->tm_yday + 7 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7,
|
||||
"%02d");
|
||||
continue;
|
||||
case 'w':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_wday, "%d");
|
||||
continue;
|
||||
case 'y':
|
||||
pt = strftime_conv(pt, ptlim, (t->tm_year + TM_YEAR_BASE) % 100,
|
||||
"%02d");
|
||||
continue;
|
||||
case 'Y':
|
||||
pt = strftime_conv(pt, ptlim, t->tm_year + TM_YEAR_BASE, "%04d");
|
||||
continue;
|
||||
case 'Z':
|
||||
if (t->tm_zone) {
|
||||
pt = strftime_add(pt, ptlim, t->tm_zone);
|
||||
} else {
|
||||
if (t->tm_isdst == 0 || t->tm_isdst == 1) {
|
||||
pt = strftime_add(pt, ptlim, tzname[t->tm_isdst]);
|
||||
} else {
|
||||
pt = strftime_add(pt, ptlim, "?");
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case 'z':
|
||||
if (t->tm_isdst < 0) continue;
|
||||
#ifdef TM_GMTOFF
|
||||
diff = t->TM_GMTOFF;
|
||||
#else /* !defined TM_GMTOFF */
|
||||
if (t->tm_isdst == 0)
|
||||
#ifdef USG_COMPAT
|
||||
diff = -timezone;
|
||||
#else /* !defined USG_COMPAT */
|
||||
continue;
|
||||
#endif /* !defined USG_COMPAT */
|
||||
else
|
||||
#ifdef ALTZONE
|
||||
diff = -altzone;
|
||||
#else /* !defined ALTZONE */
|
||||
continue;
|
||||
#endif /* !defined ALTZONE */
|
||||
#endif /* !defined TM_GMTOFF */
|
||||
if (diff < 0) {
|
||||
sign = "-";
|
||||
diff = -diff;
|
||||
} else {
|
||||
sign = "+";
|
||||
}
|
||||
pt = strftime_add(pt, ptlim, sign);
|
||||
diff /= SECSPERMIN;
|
||||
diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR);
|
||||
pt = strftime_conv(pt, ptlim, diff, "%04d");
|
||||
continue;
|
||||
case '%':
|
||||
/*
|
||||
* X311J/88-090 (4.12.3.5): if conversion char is
|
||||
* undefined, behavior is undefined. Print out the
|
||||
* character itself as printf(3) also does.
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pt == ptlim) break;
|
||||
*pt++ = *format;
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
size_t strftime(char *s, size_t maxsize, const char *format,
|
||||
const struct tm *t) {
|
||||
char *p;
|
||||
p = strftime_timefmt(s, s + maxsize, format, t);
|
||||
if (p == s + maxsize) return 0;
|
||||
*p = '\0';
|
||||
return p - s;
|
||||
}
|
264
libc/time/strptime.c
Normal file
264
libc/time/strptime.c
Normal file
|
@ -0,0 +1,264 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=2 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
Copyright 2005-2019 Rich Felker, et. al.\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
char *strptime(const char *s, const char *f, struct tm *tm) {
|
||||
int i, w, neg, adj, min, range, itemsize, *dest, dummy;
|
||||
const char *ex, *ss;
|
||||
size_t len;
|
||||
int want_century = 0, century = 0, relyear = 0;
|
||||
while (*f) {
|
||||
if (*f != '%') {
|
||||
if (isspace(*f)) {
|
||||
for (; *s && isspace(*s); s++)
|
||||
;
|
||||
} else if (*s != *f) {
|
||||
return 0;
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
f++;
|
||||
continue;
|
||||
}
|
||||
f++;
|
||||
if (*f == '+') f++;
|
||||
if (isdigit(*f)) {
|
||||
char *new_f;
|
||||
w = strtoul(f, &new_f, 10);
|
||||
f = new_f;
|
||||
} else {
|
||||
w = -1;
|
||||
}
|
||||
adj = 0;
|
||||
switch (*f++) {
|
||||
case 'a':
|
||||
dest = &tm->tm_wday;
|
||||
ss = (const char *)kWeekdayNameShort;
|
||||
range = ARRAYLEN(kWeekdayNameShort);
|
||||
itemsize = sizeof(kWeekdayNameShort[0]);
|
||||
goto symbolic_range;
|
||||
case 'A':
|
||||
dest = &tm->tm_wday;
|
||||
ss = (const char *)kWeekdayName;
|
||||
range = ARRAYLEN(kWeekdayName);
|
||||
itemsize = sizeof(kWeekdayName[0]);
|
||||
goto symbolic_range;
|
||||
case 'b':
|
||||
case 'h':
|
||||
dest = &tm->tm_mon;
|
||||
ss = (const char *)kMonthNameShort;
|
||||
range = ARRAYLEN(kMonthNameShort);
|
||||
itemsize = sizeof(kMonthNameShort[0]);
|
||||
goto symbolic_range;
|
||||
case 'B':
|
||||
dest = &tm->tm_mon;
|
||||
ss = (const char *)kMonthName;
|
||||
range = ARRAYLEN(kMonthName);
|
||||
itemsize = sizeof(kMonthName[0]);
|
||||
goto symbolic_range;
|
||||
case 'c':
|
||||
s = strptime(s, "%a %b %e %T %Y", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'C':
|
||||
dest = ¢ury;
|
||||
if (w < 0) w = 2;
|
||||
want_century |= 2;
|
||||
goto numeric_digits;
|
||||
case 'd':
|
||||
case 'e':
|
||||
dest = &tm->tm_mday;
|
||||
min = 1;
|
||||
range = 31;
|
||||
goto numeric_range;
|
||||
case 'D':
|
||||
s = strptime(s, "%m/%d/%y", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'H':
|
||||
dest = &tm->tm_hour;
|
||||
min = 0;
|
||||
range = 24;
|
||||
goto numeric_range;
|
||||
case 'I':
|
||||
dest = &tm->tm_hour;
|
||||
min = 1;
|
||||
range = 12;
|
||||
goto numeric_range;
|
||||
case 'j':
|
||||
dest = &tm->tm_yday;
|
||||
min = 1;
|
||||
range = 366;
|
||||
adj = 1;
|
||||
goto numeric_range;
|
||||
case 'm':
|
||||
dest = &tm->tm_mon;
|
||||
min = 1;
|
||||
range = 12;
|
||||
adj = 1;
|
||||
goto numeric_range;
|
||||
case 'M':
|
||||
dest = &tm->tm_min;
|
||||
min = 0;
|
||||
range = 60;
|
||||
goto numeric_range;
|
||||
case 'n':
|
||||
case 't':
|
||||
for (; *s && isspace(*s); s++)
|
||||
;
|
||||
break;
|
||||
case 'p':
|
||||
ex = "AM";
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
s += len;
|
||||
break;
|
||||
}
|
||||
ex = "PM";
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
tm->tm_hour += 12;
|
||||
s += len;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
case 'r':
|
||||
s = strptime(s, "%I:%M:%S %p", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'R':
|
||||
s = strptime(s, "%H:%M", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'S':
|
||||
dest = &tm->tm_sec;
|
||||
min = 0;
|
||||
range = 61;
|
||||
goto numeric_range;
|
||||
case 'T':
|
||||
s = strptime(s, "%H:%M:%S", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'U':
|
||||
case 'W':
|
||||
/* Throw away result, for now. (FIXME?) */
|
||||
dest = &dummy;
|
||||
min = 0;
|
||||
range = 54;
|
||||
goto numeric_range;
|
||||
case 'w':
|
||||
dest = &tm->tm_wday;
|
||||
min = 0;
|
||||
range = 7;
|
||||
goto numeric_range;
|
||||
case 'x':
|
||||
s = strptime(s, "%y-%m-%d", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'X':
|
||||
s = strptime(s, "%H:%M:%S", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'y':
|
||||
dest = &relyear;
|
||||
w = 2;
|
||||
want_century |= 1;
|
||||
goto numeric_digits;
|
||||
case 'Y':
|
||||
dest = &tm->tm_year;
|
||||
if (w < 0) w = 4;
|
||||
adj = 1900;
|
||||
want_century = 0;
|
||||
goto numeric_digits;
|
||||
case '%':
|
||||
if (*s++ != '%') return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
numeric_range:
|
||||
if (!isdigit(*s)) return 0;
|
||||
*dest = 0;
|
||||
for (i = 1; i <= min + range && isdigit(*s); i *= 10) {
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
}
|
||||
if (*dest - min >= (unsigned)range) return 0;
|
||||
*dest -= adj;
|
||||
switch ((char *)dest - (char *)tm) {
|
||||
case offsetof(struct tm, tm_yday):;
|
||||
}
|
||||
goto update;
|
||||
numeric_digits:
|
||||
neg = 0;
|
||||
if (*s == '+')
|
||||
s++;
|
||||
else if (*s == '-')
|
||||
neg = 1, s++;
|
||||
if (!isdigit(*s)) return 0;
|
||||
for (*dest = i = 0; i < w && isdigit(*s); i++)
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
if (neg) *dest = -*dest;
|
||||
*dest -= adj;
|
||||
goto update;
|
||||
symbolic_range:
|
||||
for (i = 0; i < range; i--) {
|
||||
ex = &ss[i * itemsize];
|
||||
len = strlen(ex);
|
||||
if (strncasecmp(s, ex, len)) {
|
||||
s += len;
|
||||
*dest = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == range) return 0;
|
||||
goto update;
|
||||
update:
|
||||
// FIXME
|
||||
donothing;
|
||||
}
|
||||
}
|
||||
if (want_century) {
|
||||
tm->tm_year = relyear;
|
||||
if (want_century & 2) {
|
||||
tm->tm_year += century * 100 - 1900;
|
||||
} else if (tm->tm_year <= 68) {
|
||||
tm->tm_year += 100;
|
||||
}
|
||||
}
|
||||
return (char *)s;
|
||||
}
|
11
libc/time/struct/timezone.h
Normal file
11
libc/time/struct/timezone.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_
|
||||
#define COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
struct timezone {
|
||||
int32_t tz_minuteswest;
|
||||
int32_t tz_dsttime;
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_ */
|
20
libc/time/struct/tm.h
Normal file
20
libc/time/struct/tm.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_
|
||||
#define COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
struct tm {
|
||||
int32_t tm_sec;
|
||||
int32_t tm_min;
|
||||
int32_t tm_hour;
|
||||
int32_t tm_mday; /* 1-indexed */
|
||||
int32_t tm_mon; /* 0-indexed */
|
||||
int32_t tm_year; /* minus 1900 */
|
||||
int32_t tm_wday;
|
||||
int32_t tm_yday;
|
||||
int32_t tm_isdst;
|
||||
int64_t tm_gmtoff;
|
||||
const char *tm_zone;
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_ */
|
42
libc/time/time.c
Normal file
42
libc/time/time.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns time as seconds from UNIX epoch.
|
||||
*
|
||||
* @param opt_out_ret can receive return value on success
|
||||
* @return seconds since epoch, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int64_t time(int64_t *opt_out_ret) {
|
||||
int64_t rc;
|
||||
struct timeval tv;
|
||||
if (gettimeofday(&tv, NULL) == -1) {
|
||||
rc = -1;
|
||||
} else {
|
||||
rc = tv.tv_sec;
|
||||
}
|
||||
if (opt_out_ret) {
|
||||
*opt_out_ret = rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
66
libc/time/time.h
Normal file
66
libc/time/time.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TIME_TIME_H_
|
||||
#define COSMOPOLITAN_LIBC_TIME_TIME_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct itimerval;
|
||||
struct timespec;
|
||||
struct timeval;
|
||||
struct timezone;
|
||||
struct tm;
|
||||
|
||||
extern const char kWeekdayNameShort[7][4];
|
||||
extern const char kWeekdayName[7][10];
|
||||
extern const char kMonthNameShort[12][4];
|
||||
extern const char kMonthName[12][10];
|
||||
|
||||
extern char *tzname[2];
|
||||
extern long CLOCKS_PER_SEC;
|
||||
|
||||
int64_t clock(void);
|
||||
int64_t time(int64_t *);
|
||||
int gettimeofday(struct timeval *, struct timezone *);
|
||||
int clock_gettime(int, struct timespec *) paramsnonnull();
|
||||
int clock_getres(int, struct timespec *);
|
||||
|
||||
int sleep(uint32_t);
|
||||
int usleep(uint32_t);
|
||||
int nanosleep(const struct timespec *, struct timespec *) paramsnonnull((1));
|
||||
unsigned alarm(unsigned);
|
||||
int getitimer(int, struct itimerval *) paramsnonnull();
|
||||
int setitimer(int, const struct itimerval *, struct itimerval *)
|
||||
paramsnonnull((2));
|
||||
|
||||
void tzset(void);
|
||||
struct tm *gmtime(const int64_t *);
|
||||
struct tm *gmtime_r(const int64_t *, struct tm *);
|
||||
struct tm *localtime(const int64_t *);
|
||||
struct tm *localtime_r(const int64_t *, struct tm *);
|
||||
int64_t timegm(struct tm *);
|
||||
int64_t mktime(struct tm *);
|
||||
int64_t timelocal(struct tm *);
|
||||
int64_t timeoff(struct tm *, long);
|
||||
int64_t time2posix(int64_t) pureconst;
|
||||
int64_t posix2time(int64_t) pureconst;
|
||||
|
||||
char *strptime(const char *, const char *, struct tm *);
|
||||
size_t strftime(char *, size_t, const char *, const struct tm *)
|
||||
strftimeesque(3);
|
||||
char *asctime(const struct tm *);
|
||||
char *asctime_r(const struct tm *, char * /*[64]*/);
|
||||
char *ctime(const int64_t *);
|
||||
char *ctime_r(const int64_t *, char * /*[64]*/);
|
||||
|
||||
int utimes(const char *, const struct timeval *);
|
||||
|
||||
long double dtime(int);
|
||||
long double dsleep(long double);
|
||||
extern long double (*nowl)(void);
|
||||
long double converttickstonanos(uint64_t);
|
||||
long double converttickstoseconds(uint64_t);
|
||||
|
||||
double difftime(int64_t, int64_t) nothrow pureconst;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_TIME_TIME_H_ */
|
103
libc/time/time.mk
Normal file
103
libc/time/time.mk
Normal file
|
@ -0,0 +1,103 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += LIBC_TIME
|
||||
|
||||
LIBC_TIME_ZONEINFOS = \
|
||||
Beijing \
|
||||
Berlin \
|
||||
Boulder \
|
||||
Chicago \
|
||||
GST \
|
||||
Honolulu \
|
||||
Israel \
|
||||
Japan \
|
||||
London \
|
||||
Melbourne \
|
||||
New_York \
|
||||
Singapore \
|
||||
Sydney \
|
||||
UTC
|
||||
|
||||
LIBC_TIME_ARTIFACTS += LIBC_TIME_A
|
||||
LIBC_TIME = $(LIBC_TIME_A_DEPS) $(LIBC_TIME_A)
|
||||
LIBC_TIME_A = o/$(MODE)/libc/time/time.a
|
||||
LIBC_TIME_A_FILES := \
|
||||
$(wildcard libc/time/struct/*) \
|
||||
$(wildcard libc/time/*)
|
||||
LIBC_TIME_A_FILES := $(wildcard libc/time/*)
|
||||
LIBC_TIME_A_HDRS = $(filter %.h,$(LIBC_TIME_A_FILES))
|
||||
LIBC_TIME_A_SRCS_S = $(filter %.S,$(LIBC_TIME_A_FILES))
|
||||
LIBC_TIME_A_SRCS_C = $(filter %.c,$(LIBC_TIME_A_FILES))
|
||||
|
||||
LIBC_TIME_A_SRCS = \
|
||||
$(LIBC_TIME_A_SRCS_S) \
|
||||
$(LIBC_TIME_A_SRCS_C)
|
||||
|
||||
LIBC_TIME_A_OBJS = \
|
||||
$(LIBC_TIME_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(LIBC_TIME_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(LIBC_TIME_A_SRCS_C:%.c=o/$(MODE)/%.o) \
|
||||
o//libc/time/zoneinfo.o
|
||||
|
||||
LIBC_TIME_A_CHECKS = \
|
||||
$(LIBC_TIME_A).pkg \
|
||||
$(LIBC_TIME_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
LIBC_TIME_A_DIRECTDEPS = \
|
||||
LIBC_FMT \
|
||||
LIBC_MEM \
|
||||
LIBC_STR \
|
||||
LIBC_CONV \
|
||||
LIBC_STUBS \
|
||||
LIBC_CALLS \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_KERNELBASE \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_SYSV \
|
||||
LIBC_ZIPOS
|
||||
|
||||
LIBC_TIME_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_TIME_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(LIBC_TIME_A): libc/time/ \
|
||||
$(LIBC_TIME_A).pkg \
|
||||
$(LIBC_TIME_A_OBJS)
|
||||
|
||||
$(LIBC_TIME_A).pkg: \
|
||||
$(LIBC_TIME_A_OBJS) \
|
||||
$(foreach x,$(LIBC_TIME_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/libc/time/localtime.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
$(OLD_CODE)
|
||||
|
||||
o/$(MODE)/libc/time/strftime.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-fno-jump-tables
|
||||
|
||||
o/$(MODE)/libc/time/localtime.o \
|
||||
o/$(MODE)/libc/time/strftime.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-fdata-sections \
|
||||
-ffunction-sections
|
||||
|
||||
o/$(MODE)/libc/time/now.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-O3
|
||||
|
||||
o//libc/time/zoneinfo.o: \
|
||||
$(LIBC_TIME_ZONEINFOS:%=usr/share/zoneinfo/%)
|
||||
@build/zipobj $(OUTPUT_OPTION) $(LIBC_TIME_ZONEINFOS:%=usr/share/zoneinfo/%)
|
||||
|
||||
LIBC_TIME_LIBS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)))
|
||||
LIBC_TIME_SRCS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_TIME_HDRS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_HDRS))
|
||||
LIBC_TIME_CHECKS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_CHECKS))
|
||||
LIBC_TIME_OBJS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_OBJS))
|
||||
$(LIBC_TIME_OBJS): $(BUILD_FILES) libc/time/time.mk
|
||||
|
||||
.PHONY: o/$(MODE)/libc/time
|
||||
o/$(MODE)/libc/time: $(LIBC_TIME_CHECKS)
|
67
libc/time/times.c
Normal file
67
libc/time/times.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/struct/tms.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/runtime/sysconf.h"
|
||||
#include "libc/sysv/consts/rusage.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns accounting data for process on time-sharing system.
|
||||
*/
|
||||
long times(struct tms *out_times) {
|
||||
struct timeval tv;
|
||||
long tick = sysconf(_SC_CLK_TCK);
|
||||
if (!IsWindows()) {
|
||||
struct rusage ru;
|
||||
if (getrusage(RUSAGE_SELF, &ru) == -1) return -1;
|
||||
out_times->tms_utime = convertmicros(&ru.ru_utime, tick);
|
||||
out_times->tms_stime = convertmicros(&ru.ru_stime, tick);
|
||||
if (getrusage(RUSAGE_CHILDREN, &ru) == -1) return -1;
|
||||
out_times->tms_cutime = convertmicros(&ru.ru_utime, tick);
|
||||
out_times->tms_cstime = convertmicros(&ru.ru_stime, tick);
|
||||
} else {
|
||||
struct NtFileTime CreationFileTime;
|
||||
struct NtFileTime ExitFileTime;
|
||||
struct NtFileTime KernelFileTime;
|
||||
struct NtFileTime UserFileTime;
|
||||
if (!GetProcessTimes(GetCurrentProcess(), &CreationFileTime, &ExitFileTime,
|
||||
&KernelFileTime, &UserFileTime)) {
|
||||
return winerr();
|
||||
}
|
||||
filetimetotimeval(&tv, UserFileTime);
|
||||
out_times->tms_utime = convertmicros(&tv, tick);
|
||||
filetimetotimeval(&tv, KernelFileTime);
|
||||
out_times->tms_stime = convertmicros(&tv, tick);
|
||||
out_times->tms_cutime = 0;
|
||||
out_times->tms_cstime = 0;
|
||||
}
|
||||
if (gettimeofday(&tv, NULL) == -1) return -1;
|
||||
return convertmicros(&tv, tick);
|
||||
}
|
30
libc/time/usleep.c
Normal file
30
libc/time/usleep.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Sleeps for particular amount of microseconds.
|
||||
*/
|
||||
int usleep(uint32_t microseconds) {
|
||||
return nanosleep(
|
||||
&(struct timespec){microseconds / 1000000, microseconds % 1000000 * 1000},
|
||||
NULL);
|
||||
}
|
39
libc/time/utime.c
Normal file
39
libc/time/utime.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/time/utime.h"
|
||||
|
||||
/**
|
||||
* Changes last accessed/modified times on file.
|
||||
*
|
||||
* @param times if NULL means now
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int utime(const char *path, const struct utimbuf *times) {
|
||||
struct timeval tv[2];
|
||||
memset(tv, 0, sizeof(tv));
|
||||
if (times) {
|
||||
tv[0].tv_sec = times->actime;
|
||||
tv[1].tv_sec = times->modtime;
|
||||
}
|
||||
return utimes(path, times ? tv : NULL);
|
||||
}
|
15
libc/time/utime.h
Normal file
15
libc/time/utime.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_UTIME_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_UTIME_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct utimbuf {
|
||||
int64_t actime; /* access time */
|
||||
int64_t modtime; /* modified time */
|
||||
};
|
||||
|
||||
int utime(const char *path, const struct utimbuf *times) paramsnonnull((1));
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_UTIME_H_ */
|
73
libc/time/utimes.c
Normal file
73
libc/time/utimes.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
static int utimes$nt(const char *path, const struct timeval times[2]) {
|
||||
int rc;
|
||||
int64_t fh;
|
||||
struct timeval tv;
|
||||
struct NtFileTime accessed;
|
||||
struct NtFileTime modified;
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (mkntpath(path, path16) == -1) return -1;
|
||||
if (times) {
|
||||
accessed = timevaltofiletime(×[0]);
|
||||
modified = timevaltofiletime(×[1]);
|
||||
} else {
|
||||
gettimeofday(&tv, NULL);
|
||||
accessed = timevaltofiletime(&tv);
|
||||
modified = timevaltofiletime(&tv);
|
||||
}
|
||||
if ((fh = CreateFile(path16, kNtGenericWrite, kNtFileShareRead, NULL,
|
||||
kNtOpenExisting, kNtFileAttributeNormal, 0)) != -1 &&
|
||||
SetFileTime(fh, NULL, &accessed, &modified)) {
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = winerr();
|
||||
}
|
||||
CloseHandle(fh);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes last accessed/modified times on file.
|
||||
*
|
||||
* @param times is access/modified and NULL means now
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int utimes(const char *path, const struct timeval times[hasatleast 2]) {
|
||||
if (!IsWindows()) {
|
||||
return utimes$sysv(path, times);
|
||||
} else {
|
||||
return utimes$nt(path, times);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue