From 2af6058585a93f47f4c2bfa98929fc9893174f41 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 10 Feb 2003 00:19:53 +0000 Subject: [PATCH] Added two open() versions to our kernel_interface, that re-try opening read-only, if desired. They are now used in BDirectory and BNode, which formerly failed on read-only devices. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2677 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/storage/kernel_interface.h | 16 +++++++++++- src/kits/storage/Directory.cpp | 2 +- src/kits/storage/Node.cpp | 6 +++-- src/kits/storage/kernel_interface.POSIX.cpp | 27 +++++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/headers/private/storage/kernel_interface.h b/headers/private/storage/kernel_interface.h index 91088f9505..6418f10625 100644 --- a/headers/private/storage/kernel_interface.h +++ b/headers/private/storage/kernel_interface.h @@ -68,11 +68,25 @@ status_t stat_dev(dev_t dev, fs_info* info); it doesn't already exist). */ status_t open(const char *path, OpenFlags flags, FileDescriptor &result); -/*! \brief Same as the other version of open() except the file is created with the +/*! \brief Same as the first version, but tries to open read-only, if + first the attempt failed with B_READ_ONLY_DEVICE or + B_PERMISSION_DENIED and \a fallBackToReadOnly is \c true. +*/ +status_t open(const char *path, OpenFlags flags, FileDescriptor &result, + bool fallBackToReadOnly); + +/*! \brief Same as the first version of open() except the file is created with the permissions given by creationFlags if it doesn't exist. */ status_t open(const char *path, OpenFlags flags, CreationFlags creationFlags, FileDescriptor &result); +/*! \brief Same as the third version, but tries to open read-only, if + first the attempt failed with B_READ_ONLY_DEVICE or + B_PERMISSION_DENIED and \a fallBackToReadOnly is \c true. +*/ +status_t open(const char *path, OpenFlags flags, CreationFlags creationFlags, + FileDescriptor &result, bool fallBackToReadOnly); + /*! \brief Closes a previously open()ed file. */ status_t close( FileDescriptor file ); diff --git a/src/kits/storage/Directory.cpp b/src/kits/storage/Directory.cpp index 0a47eed191..8735abe5a6 100644 --- a/src/kits/storage/Directory.cpp +++ b/src/kits/storage/Directory.cpp @@ -249,7 +249,7 @@ BDirectory::SetTo(const char *path) // open_dir() does always traverse those. Therefore we open the FD for // BNode (without the O_NOTRAVERSE flag). BPrivate::Storage::FileDescriptor fd = BPrivate::Storage::NullFd; - result = BPrivate::Storage::open(path, O_RDWR, fd); + result = BPrivate::Storage::open(path, O_RDWR, fd, true); if (result == B_OK) { result = set_fd(fd); if (result != B_OK) diff --git a/src/kits/storage/Node.cpp b/src/kits/storage/Node.cpp index dd8ba25240..30f2b0c1fe 100644 --- a/src/kits/storage/Node.cpp +++ b/src/kits/storage/Node.cpp @@ -247,8 +247,10 @@ status_t BNode::SetTo(const char *path) { Unset(); - if (path != NULL) - fCStatus = BPrivate::Storage::open(path, O_RDWR | O_NOTRAVERSE, fFd); + if (path != NULL) { + fCStatus = BPrivate::Storage::open(path, O_RDWR | O_NOTRAVERSE, fFd, + true); + } return fCStatus; } diff --git a/src/kits/storage/kernel_interface.POSIX.cpp b/src/kits/storage/kernel_interface.POSIX.cpp index 3ba16744c4..9baccdef97 100644 --- a/src/kits/storage/kernel_interface.POSIX.cpp +++ b/src/kits/storage/kernel_interface.POSIX.cpp @@ -67,6 +67,19 @@ BPrivate::Storage::open( const char *path, OpenFlags flags, FileDescriptor &resu return (result == -1) ? errno : B_OK ; } +status_t +BPrivate::Storage::open( const char *path, OpenFlags flags, + FileDescriptor &result, bool fallBackToReadOnly ) +{ + status_t error = open(path, flags, result); + if (error == B_READ_ONLY_DEVICE || error == B_PERMISSION_DENIED + && fallBackToReadOnly && (flags & O_RWMASK == O_RDWR)) { + flags = flags & ~O_RWMASK | O_RDONLY; + error = open(path, flags, result); + } + return error; +} + /*! Same as the other version of open() except the file is created with the permissions given by creationFlags if it doesn't exist. */ status_t @@ -83,6 +96,20 @@ BPrivate::Storage::open( const char *path, OpenFlags flags, return (result == -1) ? errno : B_OK ; } +status_t +BPrivate::Storage::open( const char *path, OpenFlags flags, + CreationFlags creationFlags, FileDescriptor &result, + bool fallBackToReadOnly ) +{ + status_t error = open(path, flags, creationFlags, result); + if (error == B_READ_ONLY_DEVICE || error == B_PERMISSION_DENIED + && fallBackToReadOnly && (flags & O_RWMASK == O_RDWR)) { + flags = flags & ~O_RWMASK | O_RDONLY; + error = open(path, flags, creationFlags, result); + } + return error; +} + status_t BPrivate::Storage::close(BPrivate::Storage::FileDescriptor file) {