Commit 9664c614 authored by sbc's avatar sbc Committed by Commit bot

[NaCl SDK] nacl_io: Fix utime() on directories.

It was previously failing with EISDIR. This is because
utime() internally acquires the node as O_WRONLY in
order to call the Futimens method.  This was failing
because the check for opening a directory for write
was done in Open() rather than CanOpen().

Review URL: https://codereview.chromium.org/660353003

Cr-Commit-Position: refs/heads/master@{#300313}
parent 1124df6b
......@@ -44,6 +44,11 @@ Error KernelHandle::Init(int open_flags) {
return EACCES;
}
// Directories can only be opened read-only.
if ((open_flags & 3) != O_RDONLY && node_->IsaDir()) {
return EISDIR;
}
if (open_flags & O_APPEND) {
Error error = node_->GetSize(&handle_attr_.offs);
if (error)
......
......@@ -792,6 +792,11 @@ int KernelProxy::truncate(const char* path, off_t len) {
return -1;
}
// Directories cannot be truncated.
if (node->IsaDir()) {
return EISDIR;
}
if (!node->CanOpen(O_WRONLY)) {
errno = EACCES;
return -1;
......
......@@ -105,10 +105,6 @@ Error MemFs::OpenWithMode(const Path& path, int open_flags, mode_t mode,
} else {
// Opening an existing file.
// Directories can only be opened read-only.
if (node->IsaDir() && (open_flags & 3) != O_RDONLY)
return EISDIR;
// If we were expected to create it exclusively, fail
if (open_flags & O_EXCL)
return EEXIST;
......
......@@ -77,9 +77,6 @@ TEST(FilesystemTest, Sanity) {
EXPECT_EQ(0, fs.Open(Path("/"), O_RDONLY, &root));
ASSERT_EQ(0, root->GetStat(&buf));
ASSERT_EQ(S_IRWXU, buf.st_mode & S_IRWXU);
// Opening a directory for write should fail.
EXPECT_EQ(EISDIR, fs.Open(Path("/"), O_RDWR, &root));
EXPECT_EQ(2, fs.num_nodes());
// Open the root directory, should not create a new file
EXPECT_EQ(0, fs.Open(Path("/"), O_RDONLY, &root));
......
......@@ -549,6 +549,18 @@ TEST_F(KernelProxyTest, Lstat) {
EXPECT_EQ(0, ki_lstat("/foo", &buf));
}
TEST_F(KernelProxyTest, OpenDirectory) {
// Opening a directory for read should succeed.
int fd = ki_open("/", O_RDONLY, 0);
ASSERT_GT(fd, -1);
// Opening a directory for write should fail.
EXPECT_EQ(-1, ki_open("/", O_RDWR, 0));
EXPECT_EQ(errno, EISDIR);
EXPECT_EQ(-1, ki_open("/", O_WRONLY, 0));
EXPECT_EQ(errno, EISDIR);
}
TEST_F(KernelProxyTest, OpenWithMode) {
int fd = ki_open("/foo", O_CREAT | O_RDWR, 0723);
ASSERT_GT(fd, -1);
......@@ -586,6 +598,9 @@ TEST_F(KernelProxyTest, Utimes) {
// utime should work if the file is write-only.
EXPECT_EQ(0, ki_utimes("/dummy", times));
// utime should work on directories (which can never be opened for write)
EXPECT_EQ(0, ki_utimes("/", times));
// or if the file is read-only.
EXPECT_EQ(0, ki_chmod("/dummy", 0444));
EXPECT_EQ(0, ki_utimes("/dummy", times));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment