void VFS_CloseAllUserHandles(struct sProcess *Process) { const int max_handles = *Threads_GetMaxFD(Process); ENTER("pProcess", Process); if( max_handles >= PAGE_SIZE / sizeof(tVFS_Handle) ) TODO("More than a page of handles"); tVFS_Handle *handles = MM_MapTempFromProc(Process, gaUserHandles); LOG("handles=%p", handles); // Check if this process has any handles if( !handles ) { LEAVE('-'); return ; } for( int i = 0; i < max_handles; i ++ ) { tVFS_Handle *h = &handles[i]; LOG("handles[%i].Node = %p", i, h->Node); if( !h->Node ) continue ; _CloseNode(h->Node); h->Node = NULL; } MM_FreeTemp(handles); LEAVE('-'); }
void VFS_CloseAllUserHandles(void) { int i; int max_handles = *Threads_GetMaxFD(); // Check if this process has any handles if( MM_GetPhysAddr( gaUserHandles ) == 0 ) return ; for( i = 0; i < max_handles; i ++ ) { tVFS_Handle *h; h = &gaUserHandles[i]; if( !h->Node ) continue ; _CloseNode(h->Node); } }
void VFS_FreeSavedHandles(int NumFDs, void *Handles) { tVFS_Handle *handles = Handles; int i; // NULL = nothing to do if( !Handles ) return ; // Dereference all saved nodes for( i = 0; i < NumFDs; i ++ ) { tVFS_Handle *h = &handles[i]; if( !h->Node ) continue ; _CloseNode(h->Node); ASSERT(h->Mount->OpenHandleCount > 0); LOG("dec. mntpt '%s' to %i", h->Mount->MountPoint, h->Mount->OpenHandleCount-1); h->Mount->OpenHandleCount --; } free( Handles ); }
/** * \fn int VFS_MkNod(char *Path, Uint Flags) * \brief Create a new node in a directory * \param Path Path of new node * \param Flags Flags to apply to the node */ int VFS_MkNod(const char *Path, Uint Flags) { tVFS_Mount *mountpt; char *absPath, *name; int pos = 0, oldpos = 0; int next = 0; tVFS_Node *parent; tVFS_Node *ret; ENTER("sPath xFlags", Path, Flags); absPath = VFS_GetAbsPath(Path); LOG("absPath = '%s'", absPath); while( (next = strpos(&absPath[pos+1], '/')) != -1 ) { LOG("next = %i", next); pos += next+1; LOG("pos = %i", pos); oldpos = pos; } absPath[oldpos] = '\0'; // Mutilate path name = &absPath[oldpos+1]; LOG("absPath = '%s', name = '%s'", absPath, name); // Check for root if(absPath[0] == '\0') parent = VFS_ParsePath("/", NULL, &mountpt); else parent = VFS_ParsePath(absPath, NULL, &mountpt); LOG("parent = %p", parent); if(!parent) { errno = ENOENT; goto _error; } // Permissions Check if( !VFS_CheckACL(parent, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) { errno = EACCES; goto _error; } LOG("parent = %p", parent); if(!parent->Type || !parent->Type->MkNod) { Log_Warning("VFS", "VFS_MkNod - Directory has no MkNod method"); errno = ENOTDIR; goto _error; } // Create node ret = parent->Type->MkNod(parent, name, Flags); _CloseNode(ret); // Free allocated string free(absPath); // Free Parent ASSERT(mountpt->OpenHandleCount>0); mountpt->OpenHandleCount --; _CloseNode(parent); // Return whatever the driver said LEAVE('i', ret==NULL); return ret==NULL; _error: if( parent ) { _CloseNode(parent); ASSERT(mountpt->OpenHandleCount>0); mountpt->OpenHandleCount --; } free(absPath); LEAVE('i', -1); return -1; }
void VFS_RestoreHandles(int NumFDs, void *Handles) { tVFS_Handle *handles = Handles; const int max_handles = *Threads_GetMaxFD(NULL); // NULL = nothing to do if( !Handles ) return ; if( NumFDs > max_handles ) { Log_Notice("VFS", "RestoreHandles: Capping from %i FDs to %i", NumFDs, max_handles); NumFDs = max_handles; } // Allocate user handle area (and dereference existing handles) for( int i = 0; i < NumFDs; i ++ ) { tVFS_Handle *h = &gaUserHandles[i]; if( !MM_GetPhysAddr(h) ) { void *pg = (void*)( (tVAddr)h & ~(PAGE_SIZE-1) ); if( !MM_Allocate( pg ) ) { // OOM? return ; } memset(pg, 0, PAGE_SIZE); } // Safe to dereference, as Threads_CloneTCB references handles #if 1 else { if(h->Node) { _CloseNode(h->Node); h->Mount->OpenHandleCount --; } } #endif } // Clean up existing // Restore handles memcpy( gaUserHandles, handles, NumFDs * sizeof(tVFS_Handle) ); // Reference when copied for( int i = 0; i < NumFDs; i ++ ) { tVFS_Handle *h = &gaUserHandles[i]; if( !h->Node ) continue ; // Debug("VFS_RestoreHandles: %i %p", i, h->Node); _ReferenceNode(h->Node); h->Mount->OpenHandleCount ++; } for( int i = NumFDs; i < max_handles; i ++ ) { gaUserHandles[i].Node = NULL; } }