This proposal tackles a situation where, given some directory handle, the user tries to open a subdirectory as a file, and invokes fd_read on the obtained WASI handle. This way, even though they obtained a valid handle from the path_open call (we don't have a way to tell the runtime to fail if the specified subpath is not a file; we can only fail if the subpath is not a directory and we specified the oflag O_DIRECTORY), the fd_read call will fail with ENOTCAPABLE errno since we don't include FD_READ right on directory handles when spawning them. In general, returning ENOTCAPABLE is fine, however, it doesn't match the common (expected?) behaviour of returning EISDIR in this case. Although, having said that, POSIX prescribes we should return EPERM rather than EISDIR. However, it seems that the Linux way of returning EISDIR is treated as standard. @sunfishcode please feel free to correct me here!
@sunfishcode and I had a discussion offline about this, and we both believe it would be reasonable to return EISDIR in this case in WASI as well. To achieve this, we would need to add FD_READ right to directory handles, and in the fd_read and fd_pread calls always return EISDIR errno. Having FD_READ right on the handle would prevent the implementation from failing with ENOTCAPABLE when verifying required rights on the handle.
I've decided to submit an issue about this first before rolling out a PR so that we can all agree if this is the right approach to the presented problem or not. The proposal if lands will introduce a breaking change to the end-user's code in that the expected errno values will change for the chain of syscalls described above.
cc @kubkon
This issue or pull request has been labeled: "wasi"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.
I should also mention that the alternative could be some post-processing/errno remapping in the libc (or equivalent). @sunfishcode already pointed out that some post-processing in read already happens in wasi-libc.
This seems like a reasonable approach to implementing the current interface. If we could kick this problem up to design changes in the WASI interfaces themselves, I would love some way to distinguish between directory handles and file handles in the type system so that doing file operations on a directory is caught as a type check rather than a capability check.
I agree with @pchickey; we should work towards having directories be a separate type, with separate rights, and make this a type error caught at runtime and translated by libc into EISDIR. But for now, using FD_READ seems a simple and unintrusive way to fix the immediate problem.
OK then, I'll submit a patch to that effect that will fix it as discussed.
Most helpful comment
This seems like a reasonable approach to implementing the current interface. If we could kick this problem up to design changes in the WASI interfaces themselves, I would love some way to distinguish between directory handles and file handles in the type system so that doing file operations on a directory is caught as a type check rather than a capability check.