623 lines
16 KiB
Plaintext
623 lines
16 KiB
Plaintext
/*
|
|
* Copyright 2011-2014 Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Tyler Dauwalder
|
|
* Simon Cusack, scusack@users.sf.net
|
|
* John Scipione, jscipione@gmail.com
|
|
*
|
|
* Corresponds to:
|
|
* headers/os/storage/Entry.h hrev47402
|
|
* src/kits/storage/Entry.cpp hrev47402
|
|
*/
|
|
|
|
|
|
/*!
|
|
\file Entry.h
|
|
\ingroup storage
|
|
\ingroup libbe
|
|
\brief Provides the BEntry class and entry_ref implementations.
|
|
*/
|
|
|
|
|
|
/*!
|
|
\struct entry_ref
|
|
\ingroup storage
|
|
\ingroup libbe
|
|
\brief A filesystem entry represented as a name in a concrete directory.
|
|
|
|
entry_refs may refer to pre-existing (concrete) files, as well as
|
|
non-existing (abstract) files. However, the parent directory of the file
|
|
\b must exist.
|
|
|
|
The result of this dichotomy is a blending of the persistence gained by
|
|
referring to entries with a reference to their internal filesystem node and
|
|
the flexibility gained by referring to entries by name.
|
|
|
|
For example, if the directory in which the entry resides (or a directory
|
|
further up in the hierarchy) is moved or renamed, the entry_ref will still
|
|
refer to the correct file (whereas a pathname to the previous location of
|
|
the file would now be invalid).
|
|
|
|
On the other hand, say that the entry_ref refers to a concrete file. If the
|
|
file itself is renamed, the entry_ref now refers to an abstract file with
|
|
the old name (the upside in this case is that abstract entries may be
|
|
represented by entry_refs without preallocating an internal filesystem node
|
|
for them).
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn entry_ref::entry_ref()
|
|
\brief Creates an uninitialized entry_ref object.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn entry_ref::entry_ref(dev_t dev, ino_t dir, const char* name)
|
|
\brief Creates an entry_ref object initialized to the given file name in
|
|
the given directory on the given device.
|
|
|
|
\a name may refer to either a pre-existing file in the given directory, or
|
|
a non-existent file. No explicit checking is done to verify validity of the
|
|
given arguments, but later use of the entry_ref will fail if \p dev is not
|
|
a valid device or \a dir is a not a directory on \p dev.
|
|
|
|
\param dev The \a device on which the entry's parent directory resides.
|
|
\param dir The directory in which the entry resides.
|
|
\param name The leaf name of the entry, which is not required to exist.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn entry_ref::entry_ref(const entry_ref& ref)
|
|
\brief Returns a copy of the passed in entry_ref object.
|
|
|
|
\param ref A reference to an entry_ref to copy.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn entry_ref::~entry_ref()
|
|
\brief Destroys the object and frees the storage allocated for the leaf
|
|
name, if necessary.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t entry_ref::set_name(const char* name)
|
|
\brief Set the entry_ref's leaf name, freeing the storage allocated for any
|
|
previous name and then making a copy of the new name.
|
|
|
|
\param name Pointer to a null-terminated string containing the new name for
|
|
the entry. May be \c NULL.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn bool entry_ref::operator==(const entry_ref& ref) const
|
|
\brief Compares the entry_ref object with the passed in entry_ref,
|
|
returning \c true if they are equal.
|
|
|
|
\returns \c true if he entry_refs are equal, \c false otherwise.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn bool entry_ref::operator!=(const entry_ref& ref) const
|
|
\brief Compares the entry_ref object with the passed in entry_ref,
|
|
returning \c true if they are NOT equal.
|
|
|
|
\returns \c true if the entry_refs are NOT equal, \c false otherwise.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn entry_ref& entry_ref::operator=(const entry_ref& ref)
|
|
\brief Makes the entry_ref object a copy of the passed in entry_ref.
|
|
|
|
\param ref The entry_ref to copy.
|
|
|
|
\returns A pointer to the resulting entry_ref copy.
|
|
|
|
\since BeOS R5
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var dev_t entry_ref::device
|
|
|
|
The device id of the storage device on which the entry resides.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var ino_t entry_ref::directory
|
|
|
|
The inode number of the directory in which the entry resides.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var char *entry_ref::name
|
|
|
|
The leaf name of the entry
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\class BEntry
|
|
\ingroup storage
|
|
\ingroup libbe
|
|
\brief A location in the filesystem.
|
|
|
|
The BEntry class defines objects that represent "locations" in the file
|
|
system hierarchy. Each location (or entry) is given as a name within a
|
|
directory. For example, if you create a BEntry like this:
|
|
|
|
\code
|
|
BEntry entry("/boot/home/fido");
|
|
\endcode
|
|
|
|
the resulting BEntry object represents the location of the file \c fido
|
|
within the <tt>/boot/home</tt> directory.
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BEntry::BEntry()
|
|
\brief Creates an uninitialized BEntry object.
|
|
|
|
Should be followed by a call to one of the SetTo() methods, or an
|
|
assignment.
|
|
|
|
\sa SetTo(const BDirectory*, const char*, bool)
|
|
\sa SetTo(const entry_ref*, bool)
|
|
\sa SetTo(const char*, bool)
|
|
\sa operator=(const BEntry&)
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BEntry::BEntry(const BDirectory* dir, const char* path, bool traverse)
|
|
\brief Creates a BEntry initialized to the given directory and path
|
|
combination.
|
|
|
|
If traverse is \c true and \a path refers to a symlink, the BEntry will
|
|
refer to the linked file; if \c false, the BEntry will refer to the
|
|
symlink itself.
|
|
|
|
\param dir The base directory in which the \a path resides.
|
|
\param path Relative path based off of \a dir.
|
|
\param traverse Whether or not to traverse symbolic links.
|
|
|
|
\see BEntry::SetTo(const BDirectory*, const char *, bool)
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BEntry::BEntry(const entry_ref* ref, bool traverse)
|
|
\brief Creates a BEntry for the file referred to by the passed in
|
|
entry_ref.
|
|
|
|
If traverse is \c true and \a ref refers to a symlink, the BEntry
|
|
will refer to the linked file; if \c false, the BEntry will refer
|
|
to the symlink itself.
|
|
|
|
\param ref The entry_ref referring to the given file.
|
|
\param traverse Whether or not symlinks are to be traversed.
|
|
|
|
\sa BEntry::SetTo(const entry_ref*, bool)
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BEntry::BEntry(const char* path, bool traverse)
|
|
\brief Creates a BEntry initialized to the given path.
|
|
|
|
If \a path is relative, it will be reckoned off the current working
|
|
directory. If \a path refers to a symlink and traverse is \c true, the
|
|
BEntry will refer to the linked file. If traverse is \c false, the
|
|
BEntry will refer to the symlink itself.
|
|
|
|
\param path The path of the file.
|
|
\param traverse Whether or not symlinks are to be traversed.
|
|
|
|
\sa BEntry::SetTo(const char*, bool)
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BEntry::BEntry(const BEntry& entry)
|
|
\brief Creates a copy of the given BEntry.
|
|
|
|
\param entry the entry to be copied
|
|
|
|
\sa operator=(const BEntry&)
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BEntry::~BEntry()
|
|
\brief Frees all of the allocated resources of the BEntry.
|
|
|
|
\sa Unset()
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::InitCheck() const
|
|
\brief Returns the result of the most recent construction or SetTo() call.
|
|
|
|
\returns A status code.
|
|
\retval B_OK Success
|
|
\retval B_NO_INIT The object has been Unset() or is uninitialized.
|
|
|
|
\since BeOS R3
|
|
|
|
|
|
|
|
/*!
|
|
\fn bool BEntry::Exists() const
|
|
\brief Returns whether or not the entry exists in the filesystem.
|
|
|
|
\returns \c true if the entry exists, \c false if not.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::GetStat(struct stat *result) const
|
|
\brief Fills in a stat structure for the entry.
|
|
|
|
The information is copied into the \c stat structure pointed to
|
|
by \a result.
|
|
|
|
\note The BStatable object does not cache the stat structure -- each time
|
|
you call GetStat() fresh stat information is retrieved.
|
|
|
|
\param result A pointer to a pre-allocated structure into which the stat
|
|
information is copied.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::SetTo(const BDirectory* dir, const char* path,
|
|
bool traverse)
|
|
\brief Reinitializes the BEntry to the path or directory path combination,
|
|
resolving symlinks if traverse is \c true.
|
|
|
|
\param dir The base directory in which the \a path resides.
|
|
\param path Relative path based off of \a dir.
|
|
\param traverse Whether or not to traverse symbolic links.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::SetTo(const entry_ref* ref, bool traverse)
|
|
\brief Reinitializes the BEntry to the passed in entry_ref object
|
|
resolving symlinks if traverse is \c true.
|
|
|
|
\param ref The entry_ref referring to the given file.
|
|
\param traverse Whether or not symlinks are to be traversed.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\sa BEntry::BEntry(const entry_ref* ref, bool traverse)
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::SetTo(const char* path, bool traverse)
|
|
\brief Reinitializes the BEntry object to the path, resolving symlinks if
|
|
traverse is \c true.
|
|
|
|
\param path The path of the file.
|
|
\param traverse Whether or not symlinks are to be traversed.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\sa BEntry::BEntry(const char* path, bool traverse)
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn void BEntry::Unset()
|
|
\brief Reset the BEntry to the uninitialized state
|
|
|
|
The BEntry forgets any information about the entry it was referencing.
|
|
Any attempt to get information from it after this will return B_NO_INIT.
|
|
The BEntry can later be pointed to another entry using SetTo().
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::GetRef(entry_ref* ref) const
|
|
\brief Gets an entry_ref structure for the BEntry.
|
|
|
|
\param ref A pointer to a preallocated entry_ref object into which the
|
|
result is copied.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::GetPath(BPath* path) const
|
|
\brief Gets the path for the BEntry.
|
|
|
|
\param path A pointer to a pre-allocated BPath object into which the
|
|
result is copied.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::GetParent(BEntry* entry) const
|
|
\brief Gets the parent of the BEntry as a BEntry.
|
|
|
|
If the function fails, the argument is Unset(). Destructive calls to
|
|
GetParent() are allowed, i.e.:
|
|
|
|
\code
|
|
BEntry entry("/boot/home/fido");
|
|
status_t err;
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
// Spit out the path components backwards, one at a time.
|
|
do {
|
|
entry.GetName(name);
|
|
printf("> %s\n", name);
|
|
} while ((err=entry.GetParent(&entry)) == B_OK);
|
|
|
|
// Complain for reasons other than reaching the top.
|
|
if (err != B_ENTRY_NOT_FOUND)
|
|
printf(">> Error: %s\n", strerror(err));
|
|
\endcode
|
|
|
|
will output:
|
|
|
|
\code
|
|
> fido
|
|
> home
|
|
> boot
|
|
> .
|
|
\endcode
|
|
|
|
\param entry A pointer to a pre-allocated BEntry object into which the
|
|
result is stored.
|
|
|
|
\returns A status code.
|
|
\retval B_OK Success
|
|
\retval B_ENTRY_NOT_FOUND Attempted to get the parent of the root
|
|
directory.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::GetParent(BDirectory* dir) const
|
|
\brief Gets the parent of the BEntry as a BDirectory.
|
|
|
|
If the function fails, the argument is Unset().
|
|
|
|
\param dir A pointer to a pre-allocated BDirectory object into which the
|
|
result is copied.
|
|
|
|
\returns A status code.
|
|
\retval B_OK Success
|
|
\retval B_ENTRY_NOT_FOUND Attempted to get the parent of the root
|
|
directory.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::GetName(char* buffer) const
|
|
\brief Gets the name of the leaf of the BEntry object.
|
|
|
|
\c buffer must be pre-allocated and of sufficient length to hold the
|
|
entire string. A length of \c B_FILE_NAME_LENGTH is recommended.
|
|
|
|
\param buffer A pointer to a pre-allocated string into which the result
|
|
is copied.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::Rename(const char* path, bool clobber)
|
|
\brief Renames the BEntry to \a path replacing an existing entry
|
|
if \a clobber is \c true.
|
|
|
|
\note The BEntry object must refer to an existing file, if it is abstract,
|
|
this method will fail.
|
|
|
|
\param path A pointer to a string containing the new name for the entry.
|
|
It may be an absolute or relative path. If it is a relative path
|
|
the entry is renamed within its current directory.
|
|
\param clobber If \c false and a file with the name given by \c path
|
|
already exists, the method will fail. If \c true and such a file
|
|
exists, it will be overwritten.
|
|
|
|
\returns A status code.
|
|
\retval B_OK Success
|
|
\retval B_ENTRY_EXISTS The new location already exists and \c clobber
|
|
is \c false.
|
|
\retval B_ENTRY_NOT_FOUND Attempted to rename an abstract entry.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::MoveTo(BDirectory* dir, const char* path,
|
|
bool clobber)
|
|
\brief Moves the BEntry to directory or directory and path combination,
|
|
replacing an existing entry if clobber is true.
|
|
|
|
\note The BEntry object must refer to an existing file, if it is abstract,
|
|
this method will fail.
|
|
|
|
\param dir A pointer to a pre-allocated BDirectory into which the entry
|
|
should be moved.
|
|
\param path (optional) new leaf name for the entry. May be a simple leaf
|
|
or a relative path; either way, \c path is reckoned off of \c dir.
|
|
If \c NULL, the entry retains its previous leaf name.
|
|
\param clobber If \c false and an entry already exists at the specified
|
|
Spdestination, the method will fail. If \c true and such an entry
|
|
exists, it will be overwritten.
|
|
|
|
\returns A status code.
|
|
\retval B_OK Success
|
|
\retval B_ENTRY_EXISTS The new location already exists and \c clobber
|
|
is \c false.
|
|
\retval B_ENTRY_NOT_FOUND Attempted to rename an abstract entry.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t BEntry::Remove()
|
|
\brief Removes the entry from the file system.
|
|
|
|
\note If any file descriptors are open on the file when Remove() is called
|
|
the chunk of data they refer to will continue to exist until all such file
|
|
descriptors are closed. The BEntry object, however, becomes abstract and
|
|
no longer refers to any actual data in the filesystem.
|
|
|
|
\returns \c B_OK on success, or an error code on failure.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn bool BEntry::operator==(const BEntry& item) const
|
|
\brief Returns \c true if the BEntry and \a item refer to the same entry
|
|
or if they are both uninitialized.
|
|
|
|
\returns Whether or not the items refer to the same entry.
|
|
\retval true Both BEntry objects refer to the same entry or they are
|
|
both uninitialized.
|
|
\retval false The BEntry objects refer to different entries.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn bool BEntry::operator!=(const BEntry& item) const
|
|
\brief Returns false if the BEntry and \c item refer to the same entry or
|
|
if they are both uninitialized.
|
|
|
|
\returns Whether or not the items do NOT refer to the same entry.
|
|
\retval true The BEntry objects refer to different entries.
|
|
\retval false Both BEntry objects refer to the same entry or they are
|
|
both uninitialized.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BEntry& BEntry::operator=(const BEntry& item)
|
|
\brief Reinitializes the BEntry to be a copy of \a item.
|
|
|
|
\returns A pointer to the copy.
|
|
|
|
\since BeOS R3
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn status_t get_ref_for_path(const char* path, entry_ref* ref)
|
|
\brief Returns an entry_ref for a given path.
|
|
|
|
\param path The path name referring to the entry.
|
|
\param ref The entry_ref structure to be filled in.
|
|
|
|
\returns A status code.
|
|
\retval B_OK Everything went fine.
|
|
\retval B_BAD_VALUE \c NULL \a path or \a ref.
|
|
\retval B_ENTRY_NOT_FOUND A (non-leaf) path component does not exist.
|
|
\retval B_NO_MEMORY Insufficient memory for successful completion.
|
|
|
|
\since BeOS R4
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn bool operator<(const entry_ref& a, const entry_ref& b)
|
|
\brief Returns whether an entry is less than another.
|
|
|
|
The components are compared in order \c device, \c directory, \c name.
|
|
A \c NULL \c name is less than any non-<tt>NULL</tt> name.
|
|
|
|
\retval true a < b
|
|
\retval false a >= b
|
|
|
|
\since Haiku R1
|
|
*/
|