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