#define _CRT_RAND_S // rand_s #define _GNU_SOURCE // vasprintf #include #include #include #include #include #include #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); }