#define _CRT_RAND_S // rand_s#define _GNU_SOURCE // vasprintf#include <errno.h>#include <fcntl.h>#include <locale.h>#include <windows.h>#include <sys/stat.h>#include <time.h>#undef MEM_FREE#include "inc/priv.h"#include "inc/time.h" static void __stdcall (*get_sys_time)(LPFILETIME); voidsys_seed(void *p, int sz){ u8int *o = p; u32int r; for(int k = 0; k < sz; k++){ rand_s(&r); for(int i = 0; i < 4 && k < sz; i++, k++){ o[k] = r; r >>= 8; } }} intsetenv(const char *name, const char *val, int overwrite){ DWORD r; if((r = GetEnvironmentVariable(name, nil, 0)) > 0){ if(!overwrite) return 0; }else if(GetLastError() != ERROR_ENVVAR_NOT_FOUND) return -1; return SetEnvironmentVariable(name, val) == 0 ? -1 : 0;} intvdprintf(int fd, const char *fmt, va_list args){ char *s; int n = vasprintf(&s, fmt, args); n = write(fd, s, n); free(s); return n;} u64intsec_realtime(void){ FILETIME ft; get_sys_time(&ft); u64int t = ft.dwLowDateTime | (u64int)ft.dwHighDateTime<<32; return (t-116444736000000000ULL)*100ULL;} u64intnanosec_monotonic(void){ static u64int fasthz, xstart; LARGE_INTEGER pf, pc; u64int x; if(fasthz == ~0ULL) return sec_realtime() - xstart; if(fasthz == 0){ if(QueryPerformanceFrequency(&pf) && QueryPerformanceCounter(&pc)){ fasthz = pf.QuadPart; xstart = pc.QuadPart; }else{err: fasthz = ~0ULL; xstart = sec_realtime(); } return 0; } if(!QueryPerformanceCounter(&pc)) goto err; x = pc.QuadPart; x -= xstart; u64int q = x / fasthz; u64int r = x % fasthz; return q*Nsec + r*Nsec/fasthz;} voidtimestr(u64int ns, char *buf, int sz){ time_t tme = ns/Nsec; struct tm *tm; *buf = 0; if((tm = localtime(&tme)) != nil && strftime(buf, sz, "%a %b %d %H:%M:%S %Y", tm) > 8 && buf[8] == '0') buf[8] = ' '; // no %e - use %d and replace the zero manually} u64intparsetime(const char *s){ USED(s); return 0;} voidsleep_ms(int ms){ if(ms != 0) Sleep(ms);} void __attribute__((noinline))sys_setcurrpc(int dummy){ USED(dummy); sys_setcallpc(dummy);} intsys_read(int fd, u8int *buf, usize n, usize *nread){ ssize r; while(1){ r = read(fd, buf, n); if(r > -1){ *nread = (usize)r; break; } return r; } return 0;} intsys_write(int fd, const void *buf, usize n, usize *nwritten){ ssize r = write(fd, buf, n); if(r < 0) return -1; *nwritten = (usize)r; return 0;} intsys_open(const char *fname, ios_flags flags, usize mode){ int of = (flags & IOS_WRITE) ? ((flags & IOS_READ) ? O_RDWR : O_WRONLY) : O_RDONLY; if(flags & IOS_TRUNC) of |= O_TRUNC; if(flags & IOS_CREATE) of |= O_CREAT; if(flags & IOS_APPEND) of |= O_APPEND; if(flags & IOS_EXCL) of |= O_EXCL; return open(fname, of, mode);} voidsys_fd_setup(int fd){ _setmode(fd, _O_BINARY);} intsys_rename(const char *old, const char *new){ return rename(old, new);} soffsetsys_seek(int fd, soffset offset, int whence){ return lseek(fd, offset, whence);} intsys_close(int fd){ return close(fd);} char *sys_getcwd(void){ char tmp[4096]; if(getcwd(tmp, sizeof(tmp)) != nil) return MEM_STRDUP(tmp); return nil;} intsys_chdir(int fd, const char *dir){ USED(fd); return chdir(dir);} intsys_mkdir(const char *path, usize mode){ USED(mode); if(mkdir(path) == 0) return 0; char *p = MEM_STRDUP(path); if(p == nil) return -1; int r = -1; for(char *s = p+1; (s = strchr(s, '\\')) != nil;){ struct stat sb; *s = 0; if(stat(p, &sb) == 0){ if((sb.st_mode & S_IFMT) != S_IFDIR) goto done; }else if(mkdir(p) != 0 && errno != EEXIST) goto done; *s++ = '\\'; while(*s == '\\') s++; } if((r = mkdir(path)) != 0 && errno == EEXIST) r = 0;done: MEM_FREE(p); return r;} voidsys_init(void){} static const u8int boot[] = {#include "sl.boot.h"}; intmain(int argc, char **argv){ setlocale(LC_NUMERIC, "C"); setlocale(LC_CTYPE, ""); SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8); HINSTANCE h = LoadLibrary("kernel32.dll"); if(h != nil){ get_sys_time = (typeof(get_sys_time))(void(*)(void))GetProcAddress(h, "GetSystemTimePreciseAsFileTime"); FreeLibrary(h); } if(get_sys_time == nil) get_sys_time = GetSystemTimeAsFileTime; slmain(boot, sizeof(boot), argc, argv);}
#define _CRT_RAND_S // rand_s
#define _GNU_SOURCE // vasprintf
#include <errno.h>
#include <fcntl.h>
#include <locale.h>
#include <windows.h>
#include <sys/stat.h>
#include <time.h>
#undef MEM_FREE
#include "inc/priv.h"
#include "inc/time.h"
static void __stdcall (*get_sys_time)(LPFILETIME);
void
sys_seed(void *p, int sz)
{
u8int *o = p;
u32int r;
for(int k = 0; k < sz; k++){
rand_s(&r);
for(int i = 0; i < 4 && k < sz; i++, k++){
o[k] = r;
r >>= 8;
}
}
}
int
setenv(const char *name, const char *val, int overwrite)
{
DWORD r;
if((r = GetEnvironmentVariable(name, nil, 0)) > 0){
if(!overwrite)
return 0;
}else if(GetLastError() != ERROR_ENVVAR_NOT_FOUND)
return -1;
return SetEnvironmentVariable(name, val) == 0 ? -1 : 0;
}
int
vdprintf(int fd, const char *fmt, va_list args)
{
char *s;
int n = vasprintf(&s, fmt, args);
n = write(fd, s, n);
free(s);
return n;
}
u64int
sec_realtime(void)
{
FILETIME ft;
get_sys_time(&ft);
u64int t = ft.dwLowDateTime | (u64int)ft.dwHighDateTime<<32;
return (t-116444736000000000ULL)*100ULL;
}
u64int
nanosec_monotonic(void)
{
static u64int fasthz, xstart;
LARGE_INTEGER pf, pc;
u64int x;
if(fasthz == ~0ULL)
return sec_realtime() - xstart;
if(fasthz == 0){
if(QueryPerformanceFrequency(&pf) && QueryPerformanceCounter(&pc)){
fasthz = pf.QuadPart;
xstart = pc.QuadPart;
}else{
err:
fasthz = ~0ULL;
xstart = sec_realtime();
}
return 0;
}
if(!QueryPerformanceCounter(&pc))
goto err;
x = pc.QuadPart;
x -= xstart;
u64int q = x / fasthz;
u64int r = x % fasthz;
return q*Nsec + r*Nsec/fasthz;
}
void
timestr(u64int ns, char *buf, int sz)
{
time_t tme = ns/Nsec;
struct tm *tm;
*buf = 0;
if((tm = localtime(&tme)) != nil && strftime(buf, sz, "%a %b %d %H:%M:%S %Y", tm) > 8 && buf[8] == '0')
buf[8] = ' '; // no %e - use %d and replace the zero manually
}
u64int
parsetime(const char *s)
{
USED(s);
return 0;
}
void
sleep_ms(int ms)
{
if(ms != 0)
Sleep(ms);
}
void __attribute__((noinline))
sys_setcurrpc(int dummy)
{
USED(dummy);
sys_setcallpc(dummy);
}
int
sys_read(int fd, u8int *buf, usize n, usize *nread)
{
ssize r;
while(1){
r = read(fd, buf, n);
if(r > -1){
*nread = (usize)r;
break;
}
return r;
}
return 0;
}
int
sys_write(int fd, const void *buf, usize n, usize *nwritten)
{
ssize r = write(fd, buf, n);
if(r < 0)
return -1;
*nwritten = (usize)r;
return 0;
}
int
sys_open(const char *fname, ios_flags flags, usize mode)
{
int of =
(flags & IOS_WRITE)
? ((flags & IOS_READ) ? O_RDWR : O_WRONLY)
: O_RDONLY;
if(flags & IOS_TRUNC)
of |= O_TRUNC;
if(flags & IOS_CREATE)
of |= O_CREAT;
if(flags & IOS_APPEND)
of |= O_APPEND;
if(flags & IOS_EXCL)
of |= O_EXCL;
return open(fname, of, mode);
}
void
sys_fd_setup(int fd)
{
_setmode(fd, _O_BINARY);
}
int
sys_rename(const char *old, const char *new)
{
return rename(old, new);
}
soffset
sys_seek(int fd, soffset offset, int whence)
{
return lseek(fd, offset, whence);
}
int
sys_close(int fd)
{
return close(fd);
}
char *
sys_getcwd(void)
{
char tmp[4096];
if(getcwd(tmp, sizeof(tmp)) != nil)
return MEM_STRDUP(tmp);
return nil;
}
int
sys_chdir(int fd, const char *dir)
{
USED(fd);
return chdir(dir);
}
int
sys_mkdir(const char *path, usize mode)
{
USED(mode);
if(mkdir(path) == 0)
return 0;
char *p = MEM_STRDUP(path);
if(p == nil)
return -1;
int r = -1;
for(char *s = p+1; (s = strchr(s, '\\')) != nil;){
struct stat sb;
*s = 0;
if(stat(p, &sb) == 0){
if((sb.st_mode & S_IFMT) != S_IFDIR)
goto done;
}else if(mkdir(p) != 0 && errno != EEXIST)
goto done;
*s++ = '\\';
while(*s == '\\')
s++;
}
if((r = mkdir(path)) != 0 && errno == EEXIST)
r = 0;
done:
MEM_FREE(p);
return r;
}
void
sys_init(void)
{
}
static const u8int boot[] = {
#include "sl.boot.h"
};
int
main(int argc, char **argv)
{
setlocale(LC_NUMERIC, "C");
setlocale(LC_CTYPE, "");
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
HINSTANCE h = LoadLibrary("kernel32.dll");
if(h != nil){
get_sys_time = (typeof(get_sys_time))(void(*)(void))GetProcAddress(h, "GetSystemTimePreciseAsFileTime");
FreeLibrary(h);
}
if(get_sys_time == nil)
get_sys_time = GetSystemTimeAsFileTime;
slmain(boot, sizeof(boot), argc, argv);
}