From f2505b15830415f341ae4d6d18815d481f41b921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 26 Nov 2009 14:19:01 +0000 Subject: [PATCH] * Implemented O_DIRECTORY in BFS. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34280 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 25 ++++++++++--------- .../file_systems/bfs/kernel_interface.cpp | 4 ++- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index cdc9fc548c..d8d83428f6 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -2514,7 +2514,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, if (tree->Find((uint8*)name, (uint16)strlen(name), &offset) == B_OK) { // Return if the file should be a directory/link or opened in // exclusive mode - if (S_ISDIR(mode) || S_ISLNK(mode) || openMode & O_EXCL) + if (S_ISDIR(mode) || S_ISLNK(mode) || (openMode & O_EXCL) != 0) return B_FILE_EXISTS; Vnode vnode(volume, offset); @@ -2525,28 +2525,25 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, return B_ENTRY_NOT_FOUND; } - // if it's a directory, bail out! - if (inode->IsDirectory()) + if (inode->IsDirectory() && (openMode & O_RWMASK) != O_RDONLY) return B_IS_A_DIRECTORY; + if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory()) + return B_NOT_A_DIRECTORY; // we want to open the file, so we should have the rights to do so - if (inode->CheckPermissions(open_mode_to_access(openMode)) != B_OK) + if (inode->CheckPermissions(open_mode_to_access(openMode) + | ((openMode & O_TRUNC) != 0 ? W_OK : 0)) != B_OK) return B_NOT_ALLOWED; if ((openMode & O_TRUNC) != 0) { - // we need write access in order to truncate the file - status = inode->CheckPermissions(W_OK); - if (status != B_OK) - return status; - // truncate the existing file inode->WriteLockInTransaction(transaction); status_t status = inode->SetFileSize(transaction, 0); - if (status >= B_OK) + if (status == B_OK) status = inode->WriteBack(transaction); - if (status < B_OK) + if (status != B_OK) return status; } @@ -2564,8 +2561,12 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, return B_OK; } - } else if (parent != NULL && (mode & S_ATTR_DIR) == 0) + } else if (parent != NULL && (mode & S_ATTR_DIR) == 0) { return B_BAD_VALUE; + } else if ((openMode & O_DIRECTORY) != 0) { + // TODO: we might need to return B_NOT_A_DIRECTORY here + return B_ENTRY_NOT_FOUND; + } status_t status; diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index c9d3b69630..856459d8ca 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -1229,9 +1229,11 @@ bfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie) // any data from it. if (inode->IsDirectory() && (openMode & O_RWMASK) != O_RDONLY) return B_IS_A_DIRECTORY; + if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory()) + return B_NOT_A_DIRECTORY; status_t status = inode->CheckPermissions(open_mode_to_access(openMode) - | (openMode & O_TRUNC ? W_OK : 0)); + | ((openMode & O_TRUNC) != 0 ? W_OK : 0)); if (status != B_OK) RETURN_ERROR(status);