1/* 2 * Copyright 2011 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Tyler Dauwalder 7 * Ingo Weinhold, bonefish@users.sf.net 8 * Axel Dörfler, axeld@pinc-software.de 9 * John Scipione, jscipione@gmail.com 10 * Corresponds to: 11 * headers/os/storage/Directory.h hrev43528 12 * src/kits/storage/Directory.cpp hrev43528 13 */ 14 15 16/*! 17 \file Directory.h 18 \brief Provides the BDirectory class. 19*/ 20 21 22/*! 23 \class BDirectory 24 \ingroup storage 25 \ingroup libbe 26 \brief A directory in the file system. 27*/ 28 29 30/*! 31 \fn BDirectory::BDirectory() 32 \brief Creates an uninitialized BDirectory object. 33*/ 34 35 36/*! 37 \fn BDirectory::BDirectory(const BDirectory& dir) 38 \brief Creates a copy of the supplied BDirectory object. 39 40 \param dir The BDirectory object to be copied. 41*/ 42 43 44/*! 45 \fn BDirectory::BDirectory(const entry_ref* ref) 46 \brief Creates a BDirectory and initializes it to the directory referred 47 to by the supplied entry_ref. 48 49 \param ref The entry_ref that refers to the directory. 50*/ 51 52 53/*! 54 \fn BDirectory::BDirectory(const node_ref* nref) 55 \brief Creates a BDirectory and initializes it to the directory referred 56 to by the supplied node_ref. 57 58 \param nref The node_ref that refers to the directory. 59*/ 60 61 62/*! 63 \fn BDirectory::BDirectory(const BEntry* entry) 64 \brief Creates a BDirectory and initializes it to the directory referred 65 to by the supplied BEntry. 66 67 \param entry The BEntry that refers to the directory. 68*/ 69 70 71/*! 72 \fn BDirectory::BDirectory(const char* path) 73 \brief Creates a BDirectory and initializes it to the directory referred 74 to by the supplied \a path name. 75 76 \param path The \a path name of the directory. 77*/ 78 79 80/*! 81 \fn BDirectory::BDirectory(const BDirectory* dir, const char* path) 82 \brief Creates a BDirectory and initializes it to the directory referred 83 to by the supplied path name relative to the specified BDirectory. 84 85 \param dir The base BDirectory object. 86 \param path The \a path of the directory relative to \a dir 87*/ 88 89 90/*! 91 \fn BDirectory::~BDirectory() 92 \brief Destroys the BDirectory object. 93 94 If the BDirectory is properly initialized, the directory's file descriptor 95 is closed. 96*/ 97 98 99/*! 100 \fn status_t BDirectory::SetTo(const entry_ref* ref) 101 \brief Re-initializes the BDirectory to the directory referred to by the 102 supplied entry_ref. 103 104 \param ref The entry_ref referring to the directory. 105 106 \returns A status code. 107 \retval B_OK Everything went fine. 108 \retval B_BAD_VALUE \c NULL \a ref. 109 \retval B_ENTRY_NOT_FOUND Directory not found. 110 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 111 \retval B_NO_MEMORY Insufficient memory for operation. 112 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 113 \retval B_BUSY A node was busy. 114 \retval B_FILE_ERROR A general file error. 115 \retval B_NO_MORE_FDS The application has run out of file descriptors. 116*/ 117 118 119/*! 120 \fn status_t BDirectory::SetTo(const node_ref* nref) 121 \brief Re-initializes the BDirectory to the directory referred to by the 122 supplied node_ref. 123 124 \param nref The node_ref referring to the directory. 125 126 \returns A status code. 127 \retval B_OK Everything went fine. 128 \retval B_BAD_VALUE \c NULL \a nref. 129 \retval B_ENTRY_NOT_FOUND Directory not found. 130 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 131 \retval B_NO_MEMORY Insufficient memory for operation. 132 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 133 \retval B_BUSY A node was busy. 134 \retval B_FILE_ERROR A general file error. 135 \retval B_NO_MORE_FDS The application has run out of file descriptors. 136*/ 137 138 139/*! 140 \fn status_t BDirectory::SetTo(const BEntry* entry) 141 \brief Re-initializes the BDirectory to the directory referred to by the 142 supplied BEntry. 143 144 \param entry The BEntry referring to the directory. 145 146 \returns A status code. 147 \retval B_OK Everything went fine. 148 \retval B_BAD_VALUE \c NULL \a entry. 149 \retval B_ENTRY_NOT_FOUND Directory not found. 150 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 151 \retval B_NO_MEMORY Insufficient memory for operation. 152 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 153 \retval B_BUSY A node was busy. 154 \retval B_FILE_ERROR A general file error. 155 \retval B_NO_MORE_FDS The application has run out of file descriptors. 156*/ 157 158 159/*! 160 \fn status_t BDirectory::SetTo(const char* path) 161 \brief Re-initializes the BDirectory to the directory referred to by the 162 supplied path name. 163 164 \param path The directory's \a path name. 165 166 \returns A status code. 167 \retval B_OK Everything went fine. 168 \retval B_BAD_VALUE \c NULL \a path. 169 \retval B_ENTRY_NOT_FOUND Directory not found. 170 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 171 \retval B_NO_MEMORY Insufficient memory for operation. 172 \retval B_NAME_TOO_LONG The supplied path name (\a path) is too long. 173 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 174 \retval B_BUSY A node was busy. 175 \retval B_FILE_ERROR A general file error. 176 \retval B_NO_MORE_FDS The application has run out of file descriptors. 177 \retval B_NOT_A_DIRECTORY \a path includes a non-directory. 178*/ 179 180 181/*! 182 \fn status_t BDirectory::SetTo(const BDirectory* dir, const char* path) 183 \brief Re-initializes the BDirectory to the directory referred to by the 184 supplied path name relative to the specified BDirectory. 185 186 \param dir The base directory. 187 \param path The directory path name relative to \a dir. 188 189 \returns A status code. 190 \retval B_OK Everything went fine. 191 \retval B_BAD_VALUE \c NULL \a dir or \a path, or \a path is absolute. 192 \retval B_ENTRY_NOT_FOUND Directory not found. 193 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 194 \retval B_NO_MEMORY Insufficient memory for operation. 195 \retval B_NAME_TOO_LONG The supplied path name (\a path) is too long. 196 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 197 \retval B_BUSY A node was busy. 198 \retval B_FILE_ERROR A general file error. 199 \retval B_NO_MORE_FDS The application has run out of file descriptors. 200 \retval B_NOT_A_DIRECTORY \a path includes a non-directory. 201*/ 202 203 204/*! 205 \fn status_t BDirectory::GetEntry(BEntry* entry) const 206 \brief Gets a BEntry object referring to the directory. If the 207 initialization of \a entry fails, it is Unset(). 208 209 \param entry A pointer to the \a entry that will refer to the directory. 210 211 \returns A status code. 212 \retval B_OK Everything went fine. 213 \retval B_BAD_VALUE \c NULL \a entry. 214 \retval B_ENTRY_NOT_FOUND Directory not found. 215 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 216 \retval B_NO_MEMORY Insufficient memory for operation. 217 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 218 \retval B_BUSY A node was busy. 219 \retval B_FILE_ERROR A general file error. 220 \retval B_NO_MORE_FDS The application has run out of file descriptors. 221*/ 222 223 224/*! 225 \fn bool BDirectory::IsRootDirectory() const 226 \brief Returns whether the directory is the root directory of a volume. 227 228 \returns \c true if the BDirectory is properly initialized and represents 229 a root directory of a volume, \c false otherwise. 230*/ 231 232 233/*! 234 \fn status_t BDirectory::FindEntry(const char* path, BEntry* entry, 235 bool traverse) const 236 \brief Finds an entry referred to by a path relative to the directory 237 represented by this BDirectory. 238 239 \a path may represent an absolute path. If the BDirectory is not properly 240 initialized then the entry is relative to the current directory. If the 241 entry couldn't be found, \a entry is Unset(). 242 243 \note The functionality of this method differs from 244 BEntry::SetTo(BDirectory *, const char *, bool) in that it doesn't 245 require the entry to exist, whereas this method does. 246 247 \param path The entry's \a path name. May be relative to this directory 248 or an absolute path. 249 \param entry A pointer to a BEntry to be initialized with the found entry. 250 \param traverse Whether or not to follow a symbolic link. 251 252 \returns A status code. 253 \retval B_OK Everything went fine. 254 \retval B_BAD_VALUE \c NULL \a path or \a entry. 255 \retval B_ENTRY_NOT_FOUND Entry not found. 256 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 257 \retval B_NO_MEMORY Insufficient memory for operation. 258 \retval B_NAME_TOO_LONG The supplied path name (\a path) is too long. 259 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 260 \retval B_BUSY A node was busy. 261 \retval B_FILE_ERROR A general file error. 262 \retval B_NO_MORE_FDS The application has run out of file descriptors. 263 \retval B_NOT_A_DIRECTORY \a path includes a non-directory. 264 265 \sa BEntry::SetTo(BDirectory *, const char *, bool) 266*/ 267 268 269/*! 270 \fn bool BDirectory::Contains(const char* path, int32 nodeFlags) const 271 \brief Returns whether or not this directory or any of its subdirectories 272 at any level contain the entry referred to by the supplied path name. 273 274 Only entries that match the node flavor specified by \a nodeFlags are 275 considered. 276 277 If the BDirectory is not properly initialized, the method returns \c false. 278 A non-absolute path is considered relative to the current directory. 279 280 \note R5's implementation always returns \c true given an absolute path 281 or an unitialized directory. This implementation is not compatible 282 with that behavior. Instead it converts the path into a BEntry and 283 passes it to the other version of Contains(). 284 285 \param path The entry's \a path name. May be relative to this directory 286 or may be an absolute \a path. 287 \param nodeFlags Any of the following: 288 - \c B_FILE_NODE: The entry must be a file. 289 - \c B_DIRECTORY_NODE: The entry must be a directory. 290 - \c B_SYMLINK_NODE: The entry must be a symbolic link. 291 - \c B_ANY_NODE: The entry may be of any kind. 292 293 \returns \c true if the entry exists and its kind does match \a nodeFlags 294 and the BDirectory is properly initialized and does contain the entry 295 at any level, \c false otherwise. 296*/ 297 298 299/*! 300 \fn bool BDirectory::Contains(const BEntry* entry, int32 nodeFlags) const 301 \brief Returns whether or not this directory or any of its subdirectories 302 at any level contain the entry referred to by the supplied BEntry. 303 304 Only entries that match the node flavor specified by \a nodeFlags are 305 considered. 306 307 \note If the paths are identical, this method returns \c true to stay 308 consistent with BeOS 5. 309 310 \param entry a BEntry referring to the entry 311 \param nodeFlags Any of the following: 312 - \c B_FILE_NODE: The entry must be a file. 313 - \c B_DIRECTORY_NODE: The entry must be a directory. 314 - \c B_SYMLINK_NODE: The entry must be a symbolic link. 315 - \c B_ANY_NODE: The entry may be of any kind. 316 317 \returns \c true if the BDirectory is properly initialized and the 318 entry of the matching kind was found, \c false otherwise. 319*/ 320 321 322/*! 323 \fn status_t BDirectory::GetStatFor(const char* path, struct stat* st) const 324 \brief Returns the stat structure of the entry referred to by the supplied 325 path name. 326 327 \param path The entry's path name. May be relative to this directory or 328 absolute, or \c NULL to get the directories stat info. 329 \param st A pointer to the stat structure to be filled in by this method. 330 331 \returns A status code. 332 \retval B_OK Everything went fine. 333 \retval B_BAD_VALUE \c NULL \a st. 334 \retval B_ENTRY_NOT_FOUND Entry not found. 335 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 336 \retval B_NO_MEMORY Insufficient memory for operation. 337 \retval B_NAME_TOO_LONG The supplied path name (\a path) is too long. 338 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 339 \retval B_BUSY A node was busy. 340 \retval B_FILE_ERROR A general file error. 341 \retval B_NO_MORE_FDS The application has run out of file descriptors. 342 \retval B_NOT_A_DIRECTORY \a path includes a non-directory. 343*/ 344 345 346/*! 347 \fn status_t BDirectory::GetNextEntry(BEntry* entry, bool traverse) 348 \brief Returns the next entry as a BEntry object. 349 350 Unlike GetNextDirents() this method ignores "." and "..". 351 352 \note The iterator used by this method is the same one used by 353 GetNextRef(), GetNextDirents(), Rewind() and CountEntries(). 354 355 \param entry A pointer to a BEntry to be initialized to the found entry 356 \param traverse Specifies whether or not to follow a symbolic link. 357 358 \returns A status code. 359 \retval B_OK Everything went fine. 360 \retval B_BAD_VALUE \c NULL \a entry. 361 \retval B_ENTRY_NOT_FOUND No more entries found. 362 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 363 \retval B_NO_MEMORY Insufficient memory for operation. 364 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 365 \retval B_BUSY A node was busy. 366 \retval B_FILE_ERROR A general file error. 367 \retval B_NO_MORE_FDS The application has run out of file descriptors. 368*/ 369 370 371/*! 372 \fn status_t BDirectory::GetNextRef(entry_ref* ref) 373 \brief Returns the BDirectory's next entry as an entry_ref. 374 375 Unlike GetNextDirents() this method ignores "." and "..". 376 377 \note The iterator used be this method is the same one used by 378 GetNextEntry(), GetNextDirents(), Rewind() and CountEntries(). 379 380 \param ref A pointer to an entry_ref to be filled in with the data 381 from the found entry. 382 383 \returns A status code. 384 \retval B_OK Everything went fine. 385 \retval B_BAD_VALUE \c NULL \a ref. 386 \retval B_ENTRY_NOT_FOUND No more entries found. 387 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 388 \retval B_NO_MEMORY Insufficient memory for operation. 389 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 390 \retval B_BUSY A node was busy. 391 \retval B_FILE_ERROR A general file error. 392 \retval B_NO_MORE_FDS The application has run out of file descriptors. 393*/ 394 395 396/*! 397 \fn int32 BDirectory::GetNextDirents(dirent* buf, size_t bufSize, int32 count) 398 \brief Returns the next entries of the BDirectory object as a pointer 399 to dirent structures. 400 401 Unlike GetNextEntry() and GetNextRef(), this method returns also 402 the entries "." and "..". 403 404 \note The iterator used by this method is the same one used by 405 GetNextEntry(), GetNextRef(), Rewind() and CountEntries(). 406 407 \param buf A pointer to a buffer filled with dirent structures containing 408 the found entries. 409 \param bufSize The size of \a buf. 410 \param count The maximum number of entries to be returned. 411 412 \returns The number of dirent structures stored in the buffer, 0 when 413 there are no more entries to be returned or a status code on error. 414 \retval B_BAD_VALUE \c NULL \a buf. 415 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 416 \retval B_NO_MEMORY Insufficient memory for operation. 417 \retval B_NAME_TOO_LONG The entry's name is too long for the buffer. 418 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 419 \retval B_BUSY A node was busy. 420 \retval B_FILE_ERROR A general file error. 421 \retval B_NO_MORE_FDS The application has run out of file descriptors. 422*/ 423 424 425/*! 426 \fn status_t BDirectory::Rewind() 427 \brief Rewinds the directory iterator. 428 429 \returns A status code. 430 \retval B_OK Everything went fine. 431 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 432 \retval B_NO_MEMORY Insufficient memory for operation. 433 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 434 \retval B_BUSY A node was busy. 435 \retval B_FILE_ERROR A general file error. 436 \retval B_NO_MORE_FDS The application has run out of file descriptors. 437 438 \sa BDirectory::GetNextEntry() 439 \sa BDirectory::GetNextRef() 440 \sa BDirectory::GetNextDirents() 441 \sa BDirectory::CountEntries() 442*/ 443 444 445/*! 446 \fn int32 BDirectory::CountEntries() 447 \brief Returns the number of entries in this directory. 448 449 CountEntries() uses the directory iterator also used by GetNextEntry(), 450 GetNextRef() and GetNextDirents(). It does a Rewind(), iterates through 451 the entries and Rewind()s again. The entries "." and ".." are not counted. 452 453 \returns The number of entries in the directory (not counting "." and 454 "..") or a status code on error. 455 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 456 \retval B_NO_MEMORY Insufficient memory for operation. 457 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 458 \retval B_BUSY A node was busy. 459 \retval B_FILE_ERROR A general file error. 460 \retval B_NO_MORE_FDS The application has run out of file descriptors. 461 462 \sa BDirectory::GetNextEntry() 463 \sa BDirectory::GetNextRef() 464 \sa BDirectory::GetNextDirents() 465 \sa BDirectory::Rewind() 466*/ 467 468 469/*! 470 \fn status_t BDirectory::CreateDirectory(const char* path, BDirectory* dir) 471 \brief Creates a new directory. 472 473 If an entry with the supplied name already exists this method returns 474 an error status code. 475 476 \param path The new path name of the directory. May be a relative 477 path to this directory or an absolute path. 478 \param dir A pointer to a BDirectory to be initialized to the newly 479 created directory. May be \c NULL. 480 481 \returns A status code. 482 \retval B_OK Everything went fine. 483 \retval B_BAD_VALUE \c NULL \a path. 484 \retval B_ENTRY_NOT_FOUND \a path does not refer to a possible entry. 485 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 486 \retval B_NO_MEMORY Insufficient memory for operation. 487 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 488 \retval B_BUSY A node was busy. 489 \retval B_FILE_ERROR A general file error. 490 \retval B_FILE_EXISTS An entry with that name does already exist. 491 \retval B_NO_MORE_FDS The application has run out of file descriptors. 492*/ 493 494 495/*! 496 \fn status_t BDirectory::CreateFile(const char* path, BFile* file, 497 bool failIfExists) 498 \brief Creates a new file. 499 500 If a file with the supplied name does already exist, the method fails, 501 unless it is passed \c false to \a failIfExists -- in that case the file 502 is truncated to zero size. The new BFile will operate in \c B_READ_WRITE 503 mode. 504 505 \param path The new file's path name. May be relative to this 506 directory or an absolute path. 507 \param file A pointer to a BFile to be initialized to the newly 508 created file. May be \c NULL. 509 \param failIfExists Whether or not to fail if the file already exists. 510 511 \returns A status code. 512 \retval B_OK Everything went fine. 513 \retval B_BAD_VALUE \c NULL \a path. 514 \retval B_ENTRY_NOT_FOUND \a path does not refer to a possible entry. 515 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 516 \retval B_NO_MEMORY Insufficient memory for operation. 517 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 518 \retval B_BUSY A node was busy. 519 \retval B_FILE_ERROR A general file error. 520 \retval B_FILE_EXISTS A file with that name does already exist and 521 \c true has been passed for \a failIfExists. 522 \retval B_IS_A_DIRECTORY A directory with the supplied name already 523 exists. 524 \retval B_NO_MORE_FDS The application has run out of file descriptors. 525*/ 526 527 528/*! 529 \fn status_t BDirectory::CreateSymLink(const char* path, 530 const char* linkToPath, BSymLink* link) 531 \brief Creates a new symbolic link. 532 533 This method fails if an entry with the supplied name already exists. 534 535 \param path the new symbolic link's path name. May be relative to this 536 directory or absolute. 537 \param linkToPath the path the symbolic link shall point to. 538 \param link a pointer to a BSymLink to be initialized to the newly 539 created symbolic link. May be \c NULL. 540 541 \returns A status code. 542 \retval B_OK Everything went fine. 543 \retval B_BAD_VALUE \c NULL \a path or \a linkToPath. 544 \retval B_ENTRY_NOT_FOUND \a path does not refer to a possible entry. 545 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 546 \retval B_NO_MEMORY Insufficient memory for operation. 547 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 548 \retval B_BUSY A node was busy. 549 \retval B_FILE_ERROR A general file error. 550 \retval B_FILE_EXISTS An entry with that name does already exist. 551 \retval B_NO_MORE_FDS The application has run out of file descriptors. 552*/ 553 554 555/*! 556 \fn BDirectory& BDirectory::operator=(const BDirectory& dir) 557 \brief Assigns another BDirectory to this BDirectory. 558 559 If the passed in BDirectory object is uninitialized, the returned object 560 will be too. Otherwise it will refer to the same directory, unless an 561 error occurs. 562 563 \param dir The original BDirectory object. 564 565 \returns A reference to this BDirectory object. 566*/ 567 568 569/*! 570 \fn int BDirectory::get_fd() const 571 \brief Returns the file descriptor of the BDirectory object. 572 573 This method should be used instead of accessing the private \c fDirFd 574 member directly. 575 576 \returns the file descriptor, or -1 if not properly initialized. 577*/ 578 579 580/*! 581 \fn status_t create_directory(const char* path, mode_t mode) 582 \brief Creates all missing directories along a given path. 583 584 \param path The directory path name. 585 \param mode A permission specification, which shall be used for the 586 newly created directories. 587 588 \returns A status code. 589 \retval B_OK Everything went fine. 590 \retval B_BAD_VALUE \c NULL \a path. 591 \retval B_ENTRY_NOT_FOUND \a path does not refer to a possible entry. 592 \retval B_PERMISSION_DENIED Directory permissions didn't allow operation. 593 \retval B_NO_MEMORY Insufficient memory for operation. 594 \retval B_LINK_LIMIT Indicates a cyclic loop within the file system. 595 \retval B_BUSY A node was busy. 596 \retval B_FILE_ERROR A general file error. 597 \retval B_NOT_A_DIRECTORY An entry other than a directory with that name 598 already exists. 599 \retval B_NO_MORE_FDS The application has run out of file descriptors. 600*/ 601