diff --git a/native/factor.c b/native/factor.c index 027a2a87c7..66c5cd83c3 100644 --- a/native/factor.c +++ b/native/factor.c @@ -6,7 +6,11 @@ void init_factor(char* image) load_image(image); init_stacks(); init_io(); + +#ifdef WIN32 init_signals(); +#endif + init_compiler(); init_errors(); gc_time = 0; diff --git a/native/file.c b/native/unix/file.c similarity index 98% rename from native/file.c rename to native/unix/file.c index 9f7f58579a..52183e24c1 100644 --- a/native/file.c +++ b/native/unix/file.c @@ -1,4 +1,4 @@ -#include "factor.h" +#include "../factor.h" void primitive_open_file(void) { @@ -97,3 +97,4 @@ void primitive_cd(void) maybe_garbage_collection(); chdir(unbox_c_string()); } + diff --git a/native/win32/file.c b/native/win32/file.c new file mode 100644 index 0000000000..13ee48d561 --- /dev/null +++ b/native/win32/file.c @@ -0,0 +1,114 @@ +#include "../factor.h" + +void primitive_open_file(void) +{ + bool write = unbox_boolean(); + bool read = unbox_boolean(); + char *path; + DWORD mode = 0, create = 0; + HANDLE fp; + SECURITY_ATTRIBUTES sa; + + path = unbox_c_string(); + + mode |= write ? GENERIC_WRITE : 0; + mode |= read ? GENERIC_READ : 0; + + if (read && write) + create = OPEN_ALWAYS; + else if (read) + create = OPEN_EXISTING; + else if (write) + create = CREATE_ALWAYS; + + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = true; + + fp = CreateFile( + path, + mode, + FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, + create, + /* FILE_FLAG_OVERLAPPED TODO */0, + NULL); + + if (fp == INVALID_HANDLE_VALUE) + { + io_error(__FUNCTION__); + } + else + { + CreateIoCompletionPort(fp, completion_port, 0, 0); + dpush(read ? tag_object(port(PORT_READ, (CELL)fp)) : F); + dpush(write ? tag_object(port(PORT_WRITE, (CELL)fp)) : F); + } +} + +void primitive_stat(void) +{ + F_STRING *path; + WIN32_FILE_ATTRIBUTE_DATA st; + + maybe_garbage_collection(); + path = untag_string(dpop()); + + if(!GetFileAttributesEx(to_c_string(path), GetFileExInfoStandard, &st)) + { + dpush(F); + } + else + { + CELL dirp = tag_boolean(st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); + CELL size = tag_object(s48_long_long_to_bignum( + (int64_t)st.nFileSizeLow | (int64_t)st.nFileSizeHigh << 32)); + CELL mtime = tag_integer((int)(*(int64_t*)&st.ftLastWriteTime / 100000000 - 172456224)); + dpush( + cons(dirp, + cons(tag_fixnum(0), + cons(size, + cons(mtime, F))))); + } +} + +void primitive_read_dir(void) +{ + F_STRING *path; + HANDLE dir; + WIN32_FIND_DATA find_data; + CELL result = F; + + maybe_garbage_collection(); + + path = untag_string(dpop()); + if (INVALID_HANDLE_VALUE != (dir = FindFirstFile(".\\*", &find_data))) + { + do + { + CELL name = tag_object(from_c_string(find_data.cFileName)); + result = cons(name, result); + } + while (FindNextFile(dir, &find_data)); + CloseHandle(dir); + } + + dpush(result); +} + +void primitive_cwd(void) +{ + char buf[MAX_PATH]; + + maybe_garbage_collection(); + if(!GetCurrentDirectory(MAX_PATH, buf)) + io_error(__FUNCTION__); + + box_c_string(buf); +} + +void primitive_cd(void) +{ + maybe_garbage_collection(); + SetCurrentDirectory(unbox_c_string()); +} \ No newline at end of file