Fix how O_PATH interacts with other flags
This commit is contained in:
parent
25beca462d
commit
277b5b5c24
|
|
@ -446,7 +446,10 @@ impl Path {
|
|||
);
|
||||
}
|
||||
|
||||
if inode_type.is_regular_file() && creation_flags.contains(CreationFlags::O_TRUNC) {
|
||||
if inode_type.is_regular_file()
|
||||
&& creation_flags.contains(CreationFlags::O_TRUNC)
|
||||
&& !open_args.status_flags.contains(StatusFlags::O_PATH)
|
||||
{
|
||||
self.resize(0)?;
|
||||
}
|
||||
InodeHandle::new(self.clone(), open_args.access_mode, open_args.status_flags)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
file_table::{FdFlags, FileDesc},
|
||||
fs_resolver::{FsPath, FsResolver, LookupResult, AT_FDCWD},
|
||||
inode_handle::InodeHandle,
|
||||
utils::{AccessMode, CreationFlags, InodeMode, InodeType, OpenArgs},
|
||||
utils::{AccessMode, CreationFlags, InodeMode, InodeType, OpenArgs, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
syscall::constants::MAX_FILENAME_LEN,
|
||||
|
|
@ -89,7 +89,9 @@ fn do_open(
|
|||
let inode_handle = match lookup_res {
|
||||
LookupResult::Resolved(target_path) => target_path.open(open_args)?,
|
||||
LookupResult::AtParent(result) => {
|
||||
if !open_args.creation_flags.contains(CreationFlags::O_CREAT) {
|
||||
if !open_args.creation_flags.contains(CreationFlags::O_CREAT)
|
||||
|| open_args.status_flags.contains(StatusFlags::O_PATH)
|
||||
{
|
||||
return_errno_with_message!(Errno::ENOENT, "the file does not exist");
|
||||
}
|
||||
if open_args
|
||||
|
|
|
|||
|
|
@ -232,6 +232,34 @@ FN_TEST(path)
|
|||
}
|
||||
END_TEST()
|
||||
|
||||
FN_TEST(flags)
|
||||
{
|
||||
int fd;
|
||||
char buf[5];
|
||||
|
||||
fd = TEST_SUCC(open(FILENAME, O_WRONLY));
|
||||
TEST_RES(write(fd, "hello", 5), _ret == 5);
|
||||
TEST_SUCC(close(fd));
|
||||
|
||||
// `O_PATH | O_TRUNC` has no effect.
|
||||
fd = TEST_SUCC(open(FILENAME, O_WRONLY | O_PATH | O_TRUNC));
|
||||
TEST_SUCC(close(fd));
|
||||
fd = TEST_SUCC(open(FILENAME, O_RDONLY));
|
||||
TEST_RES(read(fd, buf, sizeof(buf)),
|
||||
_ret == 5 && memcmp(buf, "hello", 5) == 0);
|
||||
TEST_SUCC(close(fd));
|
||||
|
||||
// `O_RDONLY | O_TRUNC` will truncate the file.
|
||||
fd = TEST_SUCC(open(FILENAME, O_RDONLY | O_TRUNC));
|
||||
TEST_RES(read(fd, buf, sizeof(buf)), _ret == 0);
|
||||
TEST_SUCC(close(fd));
|
||||
|
||||
// `O_PATH | O_CREAT` has no effect.
|
||||
TEST_ERRNO(open("/tmp/file_does_not_exist", O_PATH | O_CREAT, 0644),
|
||||
ENOENT);
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
FN_SETUP(unlink)
|
||||
{
|
||||
CHECK(unlink(FILENAME));
|
||||
|
|
|
|||
Loading…
Reference in New Issue