void f_hphp_directoryiterator_rewind(CObjRef obj) { DirectoryIterator *di = get_directoryiterator(obj); di->rewind(); }
bool f_hphp_directoryiterator_valid(CObjRef obj) { DirectoryIterator *di = get_directoryiterator(obj); return di->valid(); }
bool f_hphp_directoryiterator_isdot(CObjRef obj) { DirectoryIterator *di = get_directoryiterator(obj); return di->isdot(); }
void f_hphp_directoryiterator_next(CObjRef obj) { DirectoryIterator *di = get_directoryiterator(obj); di->next(); }
static status_t ext2_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, fs_vnode* _newDir, const char* newName) { TRACE("ext2_rename()\n"); Volume* volume = (Volume*)_volume->private_volume; Inode* oldDirectory = (Inode*)_oldDir->private_node; Inode* newDirectory = (Inode*)_newDir->private_node; if (oldDirectory == newDirectory && strcmp(oldName, newName) == 0) return B_OK; Transaction transaction(volume->GetJournal()); oldDirectory->WriteLockInTransaction(transaction); if (oldDirectory != newDirectory) newDirectory->WriteLockInTransaction(transaction); status_t status = oldDirectory->CheckPermissions(W_OK); if (status == B_OK) status = newDirectory->CheckPermissions(W_OK); if (status != B_OK) return status; HTree oldHTree(volume, oldDirectory); DirectoryIterator* oldIterator; status = oldHTree.Lookup(oldName, &oldIterator); if (status != B_OK) return status; ObjectDeleter<DirectoryIterator> oldIteratorDeleter(oldIterator); ino_t oldID; status = oldIterator->FindEntry(oldName, &oldID); if (status != B_OK) return status; if (oldDirectory != newDirectory) { TRACE("ext2_rename(): Different parent directories\n"); CachedBlock cached(volume); ino_t parentID = newDirectory->ID(); ino_t oldDirID = oldDirectory->ID(); do { Vnode vnode(volume, parentID); Inode* parent; status = vnode.Get(&parent); if (status != B_OK) return B_IO_ERROR; fsblock_t blockNum; status = parent->FindBlock(0, blockNum); if (status != B_OK) return status; const HTreeRoot* data = (const HTreeRoot*)cached.SetTo(blockNum); parentID = data->dotdot.InodeID(); } while (parentID != oldID && parentID != oldDirID && parentID != EXT2_ROOT_NODE); if (parentID == oldID) return B_BAD_VALUE; } HTree newHTree(volume, newDirectory); DirectoryIterator* newIterator; status = newHTree.Lookup(newName, &newIterator); if (status != B_OK) return status; ObjectDeleter<DirectoryIterator> newIteratorDeleter(newIterator); Vnode vnode(volume, oldID); Inode* inode; status = vnode.Get(&inode); if (status != B_OK) return status; uint8 fileType; // TODO: Support all file types? if (inode->IsDirectory()) fileType = EXT2_TYPE_DIRECTORY; else if (inode->IsSymLink()) fileType = EXT2_TYPE_SYMLINK; else fileType = EXT2_TYPE_FILE; // Add entry in destination directory ino_t existentID; status = newIterator->FindEntry(newName, &existentID); if (status == B_OK) { if (existentID == oldID) { // Remove entry in oldID // return inode->Unlink(); return B_BAD_VALUE; } Vnode vnodeExistent(volume, existentID); Inode* existent; if (vnodeExistent.Get(&existent) != B_OK) return B_NAME_IN_USE; if (existent->IsDirectory() != inode->IsDirectory()) { return existent->IsDirectory() ? B_IS_A_DIRECTORY : B_NOT_A_DIRECTORY; } // TODO: Perhaps we have to revert this in case of error? status = newIterator->ChangeEntry(transaction, oldID, fileType); if (status != B_OK) return status; notify_entry_removed(volume->ID(), newDirectory->ID(), newName, existentID); } else if (status == B_ENTRY_NOT_FOUND) { newIterator->Restart(); status = newIterator->AddEntry(transaction, newName, strlen(newName), oldID, fileType); if (status != B_OK) return status; } else return status; // Remove entry from source folder status = oldIterator->RemoveEntry(transaction); if (status != B_OK) return status; inode->WriteLockInTransaction(transaction); if (oldDirectory != newDirectory && inode->IsDirectory()) { DirectoryIterator inodeIterator(inode); status = inodeIterator.FindEntry(".."); if (status == B_ENTRY_NOT_FOUND) { TRACE("Corrupt file system. Missing \"..\" in directory %" B_PRIdINO "\n", inode->ID()); return B_BAD_DATA; } else if (status != B_OK) return status; inodeIterator.ChangeEntry(transaction, newDirectory->ID(), (uint8)EXT2_TYPE_DIRECTORY); } status = inode->WriteBack(transaction); if (status != B_OK) return status; entry_cache_remove(volume->ID(), oldDirectory->ID(), oldName); entry_cache_add(volume->ID(), newDirectory->ID(), newName, oldID); status = transaction.Done(); if (status != B_OK) { entry_cache_remove(volume->ID(), oldDirectory->ID(), newName); entry_cache_add(volume->ID(), newDirectory->ID(), oldName, oldID); return status; } notify_entry_moved(volume->ID(), oldDirectory->ID(), oldName, newDirectory->ID(), newName, oldID); return B_OK; }
static status_t ext2_rewind_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/, void *_cookie) { DirectoryIterator *iterator = (DirectoryIterator *)_cookie; return iterator->Rewind(); }
static status_t ext2_remove_dir(fs_volume* _volume, fs_vnode* _directory, const char* name) { TRACE("ext2_remove_dir()\n"); Volume* volume = (Volume*)_volume->private_volume; Inode* directory = (Inode*)_directory->private_node; status_t status = directory->CheckPermissions(W_OK); if (status != B_OK) return status; TRACE("ext2_remove_dir(): Starting transaction\n"); Transaction transaction(volume->GetJournal()); directory->WriteLockInTransaction(transaction); TRACE("ext2_remove_dir(): Looking up for directory entry\n"); HTree htree(volume, directory); DirectoryIterator* directoryIterator; status = htree.Lookup(name, &directoryIterator); if (status != B_OK) return status; ino_t id; status = directoryIterator->FindEntry(name, &id); if (status != B_OK) return status; Vnode vnode(volume, id); Inode* inode; status = vnode.Get(&inode); if (status != B_OK) return status; inode->WriteLockInTransaction(transaction); status = inode->Unlink(transaction); if (status != B_OK) return status; status = directory->Unlink(transaction); if (status != B_OK) return status; status = directoryIterator->RemoveEntry(transaction); if (status != B_OK) return status; entry_cache_remove(volume->ID(), directory->ID(), name); entry_cache_remove(volume->ID(), id, ".."); status = transaction.Done(); if (status != B_OK) { entry_cache_add(volume->ID(), directory->ID(), name, id); entry_cache_add(volume->ID(), id, "..", id); } else notify_entry_removed(volume->ID(), directory->ID(), name, id); return status; }
/////////////////////////////////////////////////////////////////////////////// // Called after OnInitCmdLine. The base class handles the /help command line // switch and exits. If we get this far, we need to parse the command line // and determine what mode to launch the app in. // bool App::OnInit() { SetVendorName( HELIUM_APP_NAME ); #if !HELIUM_RELEASE && !HELIUM_PROFILE HELIUM_TRACE_SET_LEVEL( TraceLevels::Debug ); Helium::InitializeSymbols(); #endif // Initialize sibling dynamically loaded modules. Helium::FilePath path ( Helium::GetProcessPath() ); for ( DirectoryIterator itr ( FilePath( path.Directory() ) ); !itr.IsDone(); itr.Next() ) { std::string ext = itr.GetItem().m_Path.Extension(); if ( ext == HELIUM_MODULE_EXTENSION ) { ModuleHandle module = LoadModule( itr.GetItem().m_Path.c_str() ); HELIUM_ASSERT( module != HELIUM_INVALID_MODULE ); } } // don't spend a lot of time updating idle events for windows that don't need it wxUpdateUIEvent::SetMode( wxUPDATE_UI_PROCESS_SPECIFIED ); wxIdleEvent::SetMode( wxIDLE_PROCESS_SPECIFIED ); Helium::FilePath exePath( GetProcessPath() ); Helium::FilePath iconFolder( exePath.Directory() + TXT( "Icons/" ) ); wxInitAllImageHandlers(); wxImageHandler* curHandler = wxImage::FindHandler( wxBITMAP_TYPE_CUR ); if ( curHandler ) { // Force the cursor handler to the end of the list so that it doesn't try to // open TGA files. wxImage::RemoveHandler( curHandler->GetName() ); curHandler = NULL; wxImage::AddHandler( new wxCURHandler ); } ArtProvider* artProvider = new ArtProvider(); wxArtProvider::Push( artProvider ); wxSimpleHelpProvider* helpProvider = new wxSimpleHelpProvider(); wxHelpProvider::Set( helpProvider ); // Make sure various module-specific heaps are initialized from the main thread before use. InitEngineJobsDefaultHeap(); InitGraphicsJobsDefaultHeap(); // Register shutdown for general systems. m_InitializerStack.Push( FileLocations::Shutdown ); m_InitializerStack.Push( Name::Shutdown ); m_InitializerStack.Push( AssetPath::Shutdown ); // Async I/O. AsyncLoader& asyncLoader = AsyncLoader::GetStaticInstance(); HELIUM_VERIFY( asyncLoader.Initialize() ); m_InitializerStack.Push( AsyncLoader::DestroyStaticInstance ); // Asset cache management. FilePath baseDirectory; if ( !FileLocations::GetBaseDirectory( baseDirectory ) ) { HELIUM_TRACE( TraceLevels::Error, TXT( "Could not get base directory." ) ); return false; } HELIUM_VERIFY( CacheManager::InitializeStaticInstance( baseDirectory ) ); m_InitializerStack.Push( CacheManager::DestroyStaticInstance ); // libs Editor::PerforceWaitDialog::EnableWaitDialog( true ); m_InitializerStack.Push( Perforce::Initialize, Perforce::Cleanup ); m_InitializerStack.Push( Reflect::ObjectRefCountSupport::Shutdown ); m_InitializerStack.Push( Asset::Shutdown ); m_InitializerStack.Push( AssetType::Shutdown ); m_InitializerStack.Push( Reflect::Initialize, Reflect::Cleanup ); m_InitializerStack.Push( Editor::Initialize, Editor::Cleanup ); // Asset loader and preprocessor. HELIUM_VERIFY( LooseAssetLoader::InitializeStaticInstance() ); m_InitializerStack.Push( LooseAssetLoader::DestroyStaticInstance ); AssetLoader* pAssetLoader = AssetLoader::GetStaticInstance(); HELIUM_ASSERT( pAssetLoader ); AssetPreprocessor* pAssetPreprocessor = AssetPreprocessor::CreateStaticInstance(); HELIUM_ASSERT( pAssetPreprocessor ); PlatformPreprocessor* pPlatformPreprocessor = new PcPreprocessor; HELIUM_ASSERT( pPlatformPreprocessor ); pAssetPreprocessor->SetPlatformPreprocessor( Cache::PLATFORM_PC, pPlatformPreprocessor ); m_InitializerStack.Push( AssetPreprocessor::DestroyStaticInstance ); m_InitializerStack.Push( ThreadSafeAssetTrackerListener::DestroyStaticInstance ); m_InitializerStack.Push( AssetTracker::DestroyStaticInstance ); m_InitializerStack.Push( InitializeEditorSystem, DestroyEditorSystem ); //HELIUM_ASSERT( g_EditorSystemDefinition.Get() ); // TODO: Figure out why this sometimes doesn't load Helium::Components::Initialize( g_EditorSystemDefinition.Get() ); m_InitializerStack.Push( Components::Cleanup ); // Engine configuration. Config& rConfig = Config::GetStaticInstance(); rConfig.BeginLoad(); while( !rConfig.TryFinishLoad() ) { pAssetLoader->Tick(); } m_InitializerStack.Push( Config::DestroyStaticInstance ); ConfigPc::SaveUserConfig(); LoadSettings(); Connect( wxEVT_CHAR, wxKeyEventHandler( App::OnChar ), NULL, this ); m_Frame = new MainFrame( m_SettingsManager ); #if HELIUM_OS_WIN m_Engine.Initialize( &m_Frame->GetSceneManager(), GetHwndOf( m_Frame ) ); #else m_Engine.Initialize( &m_Frame->GetSceneManager(), NULL ); #endif HELIUM_VERIFY( m_Frame->Initialize() ); m_Frame->Show(); if ( GetSettingsManager()->GetSettings< EditorSettings >()->GetReopenLastProjectOnStartup() ) { const std::vector< std::string >& mruPaths = wxGetApp().GetSettingsManager()->GetSettings<EditorSettings>()->GetMRUProjects(); if ( !mruPaths.empty() ) { FilePath projectPath( *mruPaths.rbegin() ); if ( projectPath.Exists() ) { m_Frame->OpenProject( FilePath( *mruPaths.rbegin() ) ); } } } return true; }
/*static*/ status_t Inode::Create(Transaction& transaction, Inode* parent, const char* name, int32 mode, int openMode, uint8 type, bool* _created, ino_t* _id, Inode** _inode, fs_vnode_ops* vnodeOps, uint32 publishFlags) { TRACE("Inode::Create()\n"); Volume* volume = transaction.GetVolume(); DirectoryIterator* entries = NULL; ObjectDeleter<DirectoryIterator> entriesDeleter; if (parent != NULL) { parent->WriteLockInTransaction(transaction); TRACE("Inode::Create(): Looking up entry destination\n"); HTree htree(volume, parent); status_t status = htree.Lookup(name, &entries); if (status == B_ENTRY_NOT_FOUND) { panic("We need to add the first node.\n"); return B_ERROR; } if (status != B_OK) return status; entriesDeleter.SetTo(entries); TRACE("Inode::Create(): Looking up to see if file already exists\n"); ino_t entryID; status = entries->FindEntry(name, &entryID); if (status == B_OK) { // File already exists TRACE("Inode::Create(): File already exists\n"); if (S_ISDIR(mode) || S_ISLNK(mode) || (openMode & O_EXCL) != 0) return B_FILE_EXISTS; Vnode vnode(volume, entryID); Inode* inode; status = vnode.Get(&inode); if (status != B_OK) { TRACE("Inode::Create() Failed to get the inode from the " "vnode\n"); return B_ENTRY_NOT_FOUND; } 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; 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) { // Truncate requested TRACE("Inode::Create(): Truncating file\n"); inode->WriteLockInTransaction(transaction); status = inode->Resize(transaction, 0); if (status != B_OK) return status; } if (_created != NULL) *_created = false; if (_id != NULL) *_id = inode->ID(); if (_inode != NULL) *_inode = inode; if (_id != NULL || _inode != NULL) vnode.Keep(); TRACE("Inode::Create(): Done opening file\n"); return B_OK; /*} else if ((mode & S_ATTR_DIR) == 0) { TRACE("Inode::Create(): (mode & S_ATTR_DIR) == 0\n"); return B_BAD_VALUE;*/ } else if ((openMode & O_DIRECTORY) != 0) { TRACE("Inode::Create(): (openMode & O_DIRECTORY) != 0\n"); return B_ENTRY_NOT_FOUND; } // Return to initial position TRACE("Inode::Create(): Restarting iterator\n"); entries->Restart(); } status_t status; if (parent != NULL) { status = parent->CheckPermissions(W_OK); if (status != B_OK) return status; } TRACE("Inode::Create(): Allocating inode\n"); ino_t id; status = volume->AllocateInode(transaction, parent, mode, id); if (status != B_OK) { ERROR("Inode::Create(): AllocateInode() failed\n"); return status; } if (entries != NULL) { size_t nameLength = strlen(name); status = entries->AddEntry(transaction, name, nameLength, id, type); if (status != B_OK) { ERROR("Inode::Create(): AddEntry() failed\n"); return status; } } TRACE("Inode::Create(): Creating inode\n"); Inode* inode = new(std::nothrow) Inode(volume); if (inode == NULL) return B_NO_MEMORY; TRACE("Inode::Create(): Getting node structure\n"); ext2_inode& node = inode->Node(); TRACE("Inode::Create(): Initializing inode data\n"); memset(&node, 0, sizeof(ext2_inode)); node.SetMode(mode); node.SetUserID(geteuid()); node.SetGroupID(parent != NULL ? parent->Node().GroupID() : getegid()); node.SetNumLinks(inode->IsDirectory() ? 2 : 1); TRACE("Inode::Create(): Updating time\n"); struct timespec timespec; _BigtimeToTimespec(real_time_clock_usecs(), ×pec); inode->SetAccessTime(×pec); inode->SetCreationTime(×pec); inode->SetModificationTime(×pec); if (parent != NULL) node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED); if (volume->HasExtentsFeature() && (inode->IsDirectory() || inode->IsFile())) { node.SetFlag(EXT2_INODE_EXTENTS); ExtentStream stream(volume, &node.extent_stream, 0); stream.Init(); ASSERT(stream.Check()); } if (sizeof(ext2_inode) < volume->InodeSize()) node.SetExtraInodeSize(sizeof(ext2_inode) - EXT2_INODE_NORMAL_SIZE); TRACE("Inode::Create(): Updating ID\n"); inode->fID = id; if (inode->IsDirectory()) { TRACE("Inode::Create(): Initializing directory\n"); status = inode->InitDirectory(transaction, parent); if (status != B_OK) { ERROR("Inode::Create(): InitDirectory() failed\n"); delete inode; return status; } } // TODO: Maybe it can be better /*if (volume->HasExtendedAttributes()) { TRACE("Inode::Create(): Initializing extended attributes\n"); uint32 blockGroup = 0; uint32 pos = 0; uint32 allocated; status = volume->AllocateBlocks(transaction, 1, 1, blockGroup, pos, allocated); if (status != B_OK) return status; // Clear the new block uint32 blockNum = volume->FirstDataBlock() + pos + volume->BlocksPerGroup() * blockGroup; CachedBlock cached(volume); cached.SetToWritable(transaction, blockNum, true); node.SetExtendedAttributesBlock(blockNum); }*/ TRACE("Inode::Create(): Saving inode\n"); status = inode->WriteBack(transaction); if (status != B_OK) { delete inode; return status; } TRACE("Inode::Create(): Creating vnode\n"); Vnode vnode; status = vnode.Publish(transaction, inode, vnodeOps, publishFlags); if (status != B_OK) return status; if (!inode->IsSymLink()) { // Vnode::Publish doesn't publish symlinks if (!inode->IsDirectory()) { status = inode->CreateFileCache(); if (status != B_OK) return status; } inode->WriteLockInTransaction(transaction); } if (_created) *_created = true; if (_id != NULL) *_id = id; if (_inode != NULL) *_inode = inode; if (_id != NULL || _inode != NULL) vnode.Keep(); TRACE("Inode::Create(): Deleting entries iterator\n"); DirectoryIterator* iterator = entriesDeleter.Detach(); TRACE("Inode::Create(): Entries iterator: %p\n", entries); delete iterator; TRACE("Inode::Create(): Done\n"); return B_OK; }