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) { ...@@ -44,6 +44,11 @@ Error KernelHandle::Init(int open_flags) {
return EACCES; return EACCES;
} }
// Directories can only be opened read-only.
if ((open_flags & 3) != O_RDONLY && node_->IsaDir()) {
return EISDIR;
}
if (open_flags & O_APPEND) { if (open_flags & O_APPEND) {
Error error = node_->GetSize(&handle_attr_.offs); Error error = node_->GetSize(&handle_attr_.offs);
if (error) if (error)
......
...@@ -792,6 +792,11 @@ int KernelProxy::truncate(const char* path, off_t len) { ...@@ -792,6 +792,11 @@ int KernelProxy::truncate(const char* path, off_t len) {
return -1; return -1;
} }
// Directories cannot be truncated.
if (node->IsaDir()) {
return EISDIR;
}
if (!node->CanOpen(O_WRONLY)) { if (!node->CanOpen(O_WRONLY)) {
errno = EACCES; errno = EACCES;
return -1; return -1;
......
...@@ -105,10 +105,6 @@ Error MemFs::OpenWithMode(const Path& path, int open_flags, mode_t mode, ...@@ -105,10 +105,6 @@ Error MemFs::OpenWithMode(const Path& path, int open_flags, mode_t mode,
} else { } else {
// Opening an existing file. // 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 we were expected to create it exclusively, fail
if (open_flags & O_EXCL) if (open_flags & O_EXCL)
return EEXIST; return EEXIST;
......
...@@ -77,9 +77,6 @@ TEST(FilesystemTest, Sanity) { ...@@ -77,9 +77,6 @@ TEST(FilesystemTest, Sanity) {
EXPECT_EQ(0, fs.Open(Path("/"), O_RDONLY, &root)); EXPECT_EQ(0, fs.Open(Path("/"), O_RDONLY, &root));
ASSERT_EQ(0, root->GetStat(&buf)); ASSERT_EQ(0, root->GetStat(&buf));
ASSERT_EQ(S_IRWXU, buf.st_mode & S_IRWXU); 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 // Open the root directory, should not create a new file
EXPECT_EQ(0, fs.Open(Path("/"), O_RDONLY, &root)); EXPECT_EQ(0, fs.Open(Path("/"), O_RDONLY, &root));
......
...@@ -549,6 +549,18 @@ TEST_F(KernelProxyTest, Lstat) { ...@@ -549,6 +549,18 @@ TEST_F(KernelProxyTest, Lstat) {
EXPECT_EQ(0, ki_lstat("/foo", &buf)); 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) { TEST_F(KernelProxyTest, OpenWithMode) {
int fd = ki_open("/foo", O_CREAT | O_RDWR, 0723); int fd = ki_open("/foo", O_CREAT | O_RDWR, 0723);
ASSERT_GT(fd, -1); ASSERT_GT(fd, -1);
...@@ -586,6 +598,9 @@ TEST_F(KernelProxyTest, Utimes) { ...@@ -586,6 +598,9 @@ TEST_F(KernelProxyTest, Utimes) {
// utime should work if the file is write-only. // utime should work if the file is write-only.
EXPECT_EQ(0, ki_utimes("/dummy", times)); 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. // or if the file is read-only.
EXPECT_EQ(0, ki_chmod("/dummy", 0444)); EXPECT_EQ(0, ki_chmod("/dummy", 0444));
EXPECT_EQ(0, ki_utimes("/dummy", times)); 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