path_get refactor and implementation of missing path_ hostcalls on Windows (#41)

* Move path_get outside of sys module

* Add implementation of readlinkat

* Clean up path_open; use OpenOptions as much as possible

* Enable close_preopen test

* Implement path_create_directory; fix path_open

* Refactor path concatenation onto a descriptor

* Implement path_remove_directory

* Implement path_unlink_file

* Rewrite path_open using specific access mask

* Fix error mapping when unlinking file

* Fix readlinkat to pass nofollow_errors testcase

* Clean up winerror to WASI conversion

* Spoof creating dangling symlinks on windows (hacky!)

* Add positive testcase for readlink

* Implement path_readlink (for nonzero buffers for now)

* Clean up

* Add Symlink struct immitating *nix symlink

* Fix path_readlink

* Augment interesting_paths testcase with trailing slashes example

* Encapsulate path_get return value as PathGet struct

* Remove dangling symlink emulation

* Extract dangling symlinks into its own testcase

This way, we can re-enable nofollow_errors testcase
on Windows also.

* Return __WASI_ENOTCAPABLE if user lacks perms to symlink
This commit is contained in:
Jakub Konka
2019-08-08 17:06:01 +02:00
committed by GitHub
parent 8ea7a983d8
commit e18175c556
19 changed files with 757 additions and 690 deletions

View File

@@ -23,19 +23,18 @@ pub(crate) fn determine_type_and_access_rights<Handle: AsRawHandle>(
host::__wasi_rights_t,
host::__wasi_rights_t,
)> {
use winx::file::{get_file_access_rights, AccessRight};
use winx::file::{get_file_access_mode, AccessMode};
let (file_type, mut rights_base, rights_inheriting) = determine_type_rights(handle)?;
match file_type {
host::__WASI_FILETYPE_DIRECTORY | host::__WASI_FILETYPE_REGULAR_FILE => {
let rights = get_file_access_rights(handle.as_raw_handle())
.map_err(host_impl::errno_from_win)?;
let rights = AccessRight::from_bits_truncate(rights);
if rights.contains(AccessRight::FILE_GENERIC_READ) {
let mode =
get_file_access_mode(handle.as_raw_handle()).map_err(host_impl::errno_from_win)?;
if mode.contains(AccessMode::FILE_GENERIC_READ) {
rights_base |= host::__WASI_RIGHT_FD_READ;
}
if rights.contains(AccessRight::FILE_GENERIC_WRITE) {
if mode.contains(AccessMode::FILE_GENERIC_WRITE) {
rights_base |= host::__WASI_RIGHT_FD_WRITE;
}
}