/* -*- mode: c; c-basic-offset: 3 -*- */ /* imported from https://krzysckh.org/prog/owl-winrt.html * originally written by Krzysztof Michałczyk */ case 0: { /* clock_gettime clock_id → nanoseconds */ LARGE_INTEGER frequency, currentTime; QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(¤tTime); double ns = (double)currentTime.QuadPart / (double)frequency.QuadPart * 1e9; return onum(ns, 1); } case 1: { /* open path flags mode → port | #f */ if (stringp(a)) { int fd = _open((const char *)a + W, cnum(b)|_O_BINARY, immval(c)); if (fd != -1) return make_immediate(fd, TPORT); } return IFALSE; } case 2: { return BOOL(w32close(immval(a)) == 0); } case 3: { /* 3 = sopen port 0=tcp|1=udp -> False | fd */ int port = immval(a); int type = immval(b); int s; int opt = 1; /* TRUE */ char udp = (type == 1); struct sockaddr_in myaddr; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(port); myaddr.sin_addr.s_addr = INADDR_ANY; s = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), (udp ? IPPROTO_UDP : 0)); fcntl(s, F_SETFL, O_NONBLOCK); if (s < 0) return IFALSE; if (type != 1) { if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) \ || bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) != 0 \ || listen(s, SOMAXCONN) != 0) { close(s); return IFALSE; } } else { if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) != 0) { close(s); return IFALSE; } } _ADDSOCK(s); return make_immediate(s, TPORT); } case 5: { /* read fd len -> bvec | EOF | #f */ if (is_type(a, TPORT)) { long long int len = memend - fp; const size_t max = len > MAXOBJ ? MAXPAYL : (len - 1) * W; len = cnum(b); len = w32read(immval(a), (void*)(fp + 1), len < max ? len : max); if (len < 0) { wsaerrno = WSAGetLastError(); return IFALSE; } if (len == 0) return IEOF; return mkraw(TBVEC, len); } return IFALSE; } case 9: { /* return process variables */ return onum( a == F(0) ? (wsaerrno >= 0 ? wsaerrno : errno) : a == F(1) ? (uintptr_t)environ : a == F(8) ? nalloc + fp - memstart : /* total allocated objects so far */ a == F(9) ? maxheap : /* maximum heap size in a major gc */ max_heap_mb, 0); } /* using the fork call as a ShellExecute call for MS Windows. * owl (system ...), (exec ...) etc will now decide what interface to use * in accordance to the chosen OS */ case 18: { if (a == IFALSE && b == IFALSE && c == IFALSE) vmfail("fork"); if (!system(cstr(a))) { return IFALSE; } return ITRUE; } case 19: { /* wait _ */ vmfail("wait"); } case 21: { /* kill pid signal → bool */ vmfail("kill"); } case 24: { /* mknod path (type . mode) dev → bool */ if (stringp(a) && pairp(b)) { const char *path = (const char *)a + W; mkdir(path); return ITRUE; } return IFALSE; } case 26: { vmfail("termctl"); } case 28: { if (stringp(a) && (b == IFALSE || stringp(b))) { const char *name = (const char *)a + W; return ((b != IFALSE ? (SetEnvironmentVariable(name, (const char *)b + W) ? ITRUE : IFALSE) : (SetEnvironmentVariable(name, "") ? ITRUE : IFALSE))); } return IFALSE; } case 31: { int fd[2]; CreatePipe((PHANDLE)&fd[0], (PHANDLE)&fd[1], NULL, 0); return cons(make_immediate(fd[0], TPORT), make_immediate(fd[1], TPORT)); } case 32: { /* winapi rename is incompatible with POSIX rename */ return BOOL(MoveFileExA(cstr(a), cstr(b), MOVEFILE_REPLACE_EXISTING) != 0); } case 33: { vmfail("link"); } case 34: { vmfail("symlink"); } case 35: { vmfail("readlink"); } case 38: { /* stat fd|path follow → list */ if (immediatep(a) || stringp(a)) { struct stat st; int fd; if (b != IFALSE) fd = _open((char*)a + W, O_BINARY, O_RDONLY); else fd = immval(a); if (fstat(fd, &st) == 0) { word lst = INULL; lst = cons(onum(0, 1), lst); lst = cons(onum(0, 1), lst); lst = cons(onum(st.st_ctime, 1), lst); lst = cons(onum(st.st_mtime, 1), lst); lst = cons(onum(st.st_atime, 1), lst); lst = cons(onum(st.st_size, 1), lst); lst = cons(onum(st.st_rdev, 0), lst); lst = cons(onum(st.st_gid, 0), lst); lst = cons(onum(st.st_uid, 0), lst); lst = cons(onum(st.st_nlink, 0), lst); lst = cons(onum(st.st_mode, 0), lst); lst = cons(onum(st.st_ino, 0), lst); lst = cons(onum(st.st_dev, 1), lst); if (b != IFALSE) close(fd); return lst; } } return INULL; } case 39: { vmfail("chmod"); } case 40: { vmfail("chown"); } case 42: { /* write fd data len | #f → nbytes | #f */ if (is_type(a, TPORT) && allocp(b)) { long long len, size = payl_len(header(b)); len = c != IFALSE ? cnum(c) : size; if (len <= size) { len = w32write(immval(a), (void*)(((const word *)b) + 1), len); if (len < 0) { wsaerrno = WSAGetLastError(); return IFALSE; } if (len != (size_t)-1) return onum(len, 0); } } return IFALSE; } case 43: { return do_poll(a, b, c); } case 46: { /* catch-signals (4 8 ...) _ _*/ word *lst = (word *)a; while((word)lst != INULL) { signal(immval(lst[1]), catch_signal); lst = (word *)lst[2]; } return ITRUE; }