[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