factor/native/win32/file.c

114 lines
2.2 KiB
C

#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
{
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_bignum(s48_long_long_to_bignum(
(int64_t)st.nFileSizeLow | (int64_t)st.nFileSizeHigh << 32));
CELL mtime = tag_integer((int)
((*(int64_t*)&st.ftLastWriteTime - EPOCH_OFFSET) / 10000000));
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());
}