[win32, io, wip] add fstat operation (type/size/perms for now, TODO: times)
This commit is contained in:
parent
3667ab30e0
commit
a1b3195ddf
|
@ -160,7 +160,7 @@ io_cmp io_open_at(file_slot* atSlot, io_req* req)
|
||||||
|
|
||||||
DWORD accessFlags = 0;
|
DWORD accessFlags = 0;
|
||||||
DWORD createFlags = 0;
|
DWORD createFlags = 0;
|
||||||
DWORD attributesFlags = FILE_ATTRIBUTE_NORMAL;
|
DWORD attributesFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
|
|
||||||
if(req->openFlags & FILE_OPEN_READ)
|
if(req->openFlags & FILE_OPEN_READ)
|
||||||
{
|
{
|
||||||
|
@ -243,53 +243,6 @@ io_cmp io_close(file_slot* slot, io_req* req)
|
||||||
return(cmp);
|
return(cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
file_perm io_convert_perm_from_stat(u16 mode)
|
|
||||||
{
|
|
||||||
file_perm perm = mode & 07777;
|
|
||||||
return(perm);
|
|
||||||
}
|
|
||||||
|
|
||||||
file_type io_convert_type_from_stat(u16 mode)
|
|
||||||
{
|
|
||||||
file_type type;
|
|
||||||
switch(mode & S_IFMT)
|
|
||||||
{
|
|
||||||
case S_IFIFO:
|
|
||||||
type = FILE_FIFO;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_IFCHR:
|
|
||||||
type = FILE_CHARACTER;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_IFDIR:
|
|
||||||
type = FILE_DIRECTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_IFBLK:
|
|
||||||
type = FILE_BLOCK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_IFREG:
|
|
||||||
type = FILE_REGULAR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_IFLNK:
|
|
||||||
type = FILE_SYMLINK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_IFSOCK:
|
|
||||||
type = FILE_SOCKET;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
type = FILE_UNKNOWN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
io_cmp io_fstat(file_slot* slot, io_req* req)
|
io_cmp io_fstat(file_slot* slot, io_req* req)
|
||||||
{
|
{
|
||||||
io_cmp cmp = {0};
|
io_cmp cmp = {0};
|
||||||
|
@ -300,24 +253,72 @@ io_cmp io_fstat(file_slot* slot, io_req* req)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct stat s;
|
BY_HANDLE_FILE_INFORMATION info;
|
||||||
if(fstat(slot->fd, &s))
|
if(!GetFileInformationByHandle(slot->h, &info))
|
||||||
{
|
{
|
||||||
slot->error = io_convert_errno(errno);
|
slot->error = io_convert_win32_error(GetLastError());
|
||||||
cmp.error = slot->error;
|
cmp.error = slot->error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file_status* status = (file_status*)req->buffer;
|
file_status* status = (file_status*)req->buffer;
|
||||||
status->perm = io_convert_perm_from_stat(s.st_mode);
|
|
||||||
status->type = io_convert_type_from_stat(s.st_mode);
|
status->size = (((u64)info.nFileSizeHigh)<<32) | ((u64)info.nFileSizeLow);
|
||||||
status->size = s.st_size;
|
|
||||||
|
DWORD attrRegularSet = FILE_ATTRIBUTE_ARCHIVE
|
||||||
|
| FILE_ATTRIBUTE_COMPRESSED
|
||||||
|
| FILE_ATTRIBUTE_ENCRYPTED
|
||||||
|
| FILE_ATTRIBUTE_HIDDEN
|
||||||
|
| FILE_ATTRIBUTE_NORMAL
|
||||||
|
| FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
|
||||||
|
| FILE_ATTRIBUTE_OFFLINE
|
||||||
|
| FILE_ATTRIBUTE_READONLY
|
||||||
|
| FILE_ATTRIBUTE_SPARSE_FILE
|
||||||
|
| FILE_ATTRIBUTE_SYSTEM
|
||||||
|
| FILE_ATTRIBUTE_TEMPORARY;
|
||||||
|
|
||||||
|
if(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
status->type = MP_FILE_DIRECTORY;
|
||||||
|
}
|
||||||
|
else if((info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
|
||||||
|
{
|
||||||
|
FILE_ATTRIBUTE_TAG_INFO tagInfo;
|
||||||
|
if(!GetFileInformationByHandleEx(slot->h, FileAttributeTagInfo, &tagInfo, sizeof(tagInfo)))
|
||||||
|
{
|
||||||
|
slot->error = io_convert_win32_error(GetLastError());
|
||||||
|
cmp.error = slot->error;
|
||||||
|
}
|
||||||
|
else if(tagInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK)
|
||||||
|
{
|
||||||
|
status->type = MP_FILE_SYMLINK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status->type = MP_FILE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(info.dwFileAttributes & attrRegularSet)
|
||||||
|
{
|
||||||
|
status->type = MP_FILE_REGULAR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//TODO: might want to check for socket/block/character devices? (otoh MS STL impl. doesn't seem to do it)
|
||||||
|
status->type = MP_FILE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
status->perm = MP_FILE_OWNER_READ | MP_FILE_GROUP_READ | MP_FILE_OTHER_READ;
|
||||||
|
if(!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||||
|
{
|
||||||
|
status->perm = MP_FILE_OWNER_WRITE | MP_FILE_GROUP_WRITE | MP_FILE_OTHER_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: times
|
//TODO: times
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(cmp);
|
return(cmp);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
io_cmp io_pos(file_slot* slot, io_req* req)
|
io_cmp io_pos(file_slot* slot, io_req* req)
|
||||||
{
|
{
|
||||||
|
@ -430,7 +431,7 @@ io_cmp io_wait_single_req(io_req* req)
|
||||||
cmp.error = IO_ERR_HANDLE;
|
cmp.error = IO_ERR_HANDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(slot->fatal && req->op != IO_OP_CLOSE)
|
else if(slot->fatal && req->op != IO_OP_CLOSE && req->op != IO_OP_ERROR)
|
||||||
{
|
{
|
||||||
cmp.error = IO_ERR_PREV;
|
cmp.error = IO_ERR_PREV;
|
||||||
}
|
}
|
||||||
|
@ -442,11 +443,11 @@ io_cmp io_wait_single_req(io_req* req)
|
||||||
case IO_OP_OPEN_AT:
|
case IO_OP_OPEN_AT:
|
||||||
cmp = io_open_at(slot, req);
|
cmp = io_open_at(slot, req);
|
||||||
break;
|
break;
|
||||||
/*
|
|
||||||
case IO_OP_FSTAT:
|
case IO_OP_FSTAT:
|
||||||
cmp = io_fstat(slot, req);
|
cmp = io_fstat(slot, req);
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
case IO_OP_CLOSE:
|
case IO_OP_CLOSE:
|
||||||
cmp = io_close(slot, req);
|
cmp = io_close(slot, req);
|
||||||
break;
|
break;
|
||||||
|
@ -458,7 +459,7 @@ io_cmp io_wait_single_req(io_req* req)
|
||||||
case IO_OP_WRITE:
|
case IO_OP_WRITE:
|
||||||
cmp = io_write(slot, req);
|
cmp = io_write(slot, req);
|
||||||
break;
|
break;
|
||||||
/*
|
|
||||||
case IO_OP_POS:
|
case IO_OP_POS:
|
||||||
cmp = io_pos(slot, req);
|
cmp = io_pos(slot, req);
|
||||||
break;
|
break;
|
||||||
|
@ -466,7 +467,7 @@ io_cmp io_wait_single_req(io_req* req)
|
||||||
case IO_OP_SEEK:
|
case IO_OP_SEEK:
|
||||||
cmp = io_seek(slot, req);
|
cmp = io_seek(slot, req);
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
case IO_OP_ERROR:
|
case IO_OP_ERROR:
|
||||||
cmp = io_get_error(slot, req);
|
cmp = io_get_error(slot, req);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
regular.txt
|
|
@ -82,6 +82,12 @@ int test_stat_size(str8 path, u64 size)
|
||||||
log_info("stat size\n");
|
log_info("stat size\n");
|
||||||
|
|
||||||
file_handle f = file_open(path, 0);
|
file_handle f = file_open(path, 0);
|
||||||
|
if(file_last_error(f))
|
||||||
|
{
|
||||||
|
log_error("Can't open file\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
file_status status = file_get_status(f);
|
file_status status = file_get_status(f);
|
||||||
|
|
||||||
if(file_last_error(f))
|
if(file_last_error(f))
|
||||||
|
@ -104,11 +110,22 @@ int test_stat_type(mem_arena* arena, str8 dataDir)
|
||||||
{
|
{
|
||||||
str8 regular = path_append(arena, dataDir, STR8("regular.txt"));
|
str8 regular = path_append(arena, dataDir, STR8("regular.txt"));
|
||||||
str8 dir = path_append(arena, dataDir, STR8("directory"));
|
str8 dir = path_append(arena, dataDir, STR8("directory"));
|
||||||
str8 link = path_append(arena, dataDir, STR8("symlink"));
|
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
str8 link = path_append(arena, dataDir, STR8("win32_symlink"));
|
||||||
|
#else
|
||||||
|
str8 link = path_append(arena, dataDir, STR8("posix_symlink"));
|
||||||
|
#endif
|
||||||
|
|
||||||
log_info("stat type, regular\n");
|
log_info("stat type, regular\n");
|
||||||
|
|
||||||
file_handle f = file_open(regular, 0);
|
file_handle f = file_open(regular, 0);
|
||||||
|
if(file_last_error(f))
|
||||||
|
{
|
||||||
|
log_error("Can't open file\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
file_status status = file_get_status(f);
|
file_status status = file_get_status(f);
|
||||||
if(file_last_error(f))
|
if(file_last_error(f))
|
||||||
{
|
{
|
||||||
|
@ -125,6 +142,12 @@ int test_stat_type(mem_arena* arena, str8 dataDir)
|
||||||
log_info("stat type, directory\n");
|
log_info("stat type, directory\n");
|
||||||
|
|
||||||
f = file_open(dir, 0);
|
f = file_open(dir, 0);
|
||||||
|
if(file_last_error(f))
|
||||||
|
{
|
||||||
|
log_error("Can't open file\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
status = file_get_status(f);
|
status = file_get_status(f);
|
||||||
if(file_last_error(f))
|
if(file_last_error(f))
|
||||||
{
|
{
|
||||||
|
@ -141,6 +164,12 @@ int test_stat_type(mem_arena* arena, str8 dataDir)
|
||||||
log_info("stat type, symlink\n");
|
log_info("stat type, symlink\n");
|
||||||
|
|
||||||
f = file_open(link, FILE_OPEN_SYMLINK);
|
f = file_open(link, FILE_OPEN_SYMLINK);
|
||||||
|
if(file_last_error(f))
|
||||||
|
{
|
||||||
|
log_error("Can't open file\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
status = file_get_status(f);
|
status = file_get_status(f);
|
||||||
if(file_last_error(f))
|
if(file_last_error(f))
|
||||||
{
|
{
|
||||||
|
@ -161,12 +190,8 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
mem_arena* arena = mem_scratch();
|
mem_arena* arena = mem_scratch();
|
||||||
|
|
||||||
str8 exePath = path_executable(arena);
|
str8 dataDir = STR8("./data");
|
||||||
str8 dirPath = path_slice_directory(exePath);
|
str8 path = STR8("./test.txt");
|
||||||
dirPath = path_append(arena, dirPath, STR8(".."));
|
|
||||||
|
|
||||||
str8 dataDir = path_append(arena, dirPath, STR8("data"));
|
|
||||||
str8 path = path_append(arena, dirPath, STR8("test.txt"));
|
|
||||||
|
|
||||||
str8 test_string = STR8("Hello, world!");
|
str8 test_string = STR8("Hello, world!");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue