/** * \fn int VFS_ReadDir(int FD, char *Dest) * \brief Read from a directory */ int VFS_ReadDir(int FD, char *Dest) { tVFS_Handle *h = VFS_GetHandle(FD); int rv; //ENTER("ph pDest", h, Dest); if(!h || !h->Node->Type || !h->Node->Type->ReadDir) { //LEAVE('i', 0); return 0; } #if 0 if(h->Node->Size != (Uint64)-1 && h->Position >= h->Node->Size) { //LEAVE('i', 0); return 0; } #endif do { rv = h->Node->Type->ReadDir(h->Node, h->Position, Dest); if(rv > 0) h->Position += rv; else h->Position ++; } while(rv > 0); if(rv < 0) { //LEAVE('i', 0); return 0; } //LEAVE('i', 1); return 1; }
/** * \brief Take a backup of a set of file descriptors */ void *VFS_SaveHandles(int NumFDs, int *FDs) { tVFS_Handle *ret; const int max_handles = *Threads_GetMaxFD(NULL); // Check if this process has any handles if( MM_GetPhysAddr( gaUserHandles ) == 0 ) return NULL; // Allocate ret = malloc( NumFDs * sizeof(tVFS_Handle) ); if( !ret ) return NULL; if( NumFDs > max_handles ) NumFDs = max_handles; // Take copies of the handles if( FDs == NULL ) { memcpy(ret, gaUserHandles, NumFDs * sizeof(tVFS_Handle)); } else { for( int i = 0; i < NumFDs; i ++ ) { if( FDs[i] < -1 ) { Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (%i<0), ignorning", i, FDs[i]); memset(&ret[i], 0, sizeof(tVFS_Handle)); continue ; } int fd = FDs[i] & (VFS_KERNEL_FLAG - 1); tVFS_Handle *h = VFS_GetHandle(fd); if(!h) { Log_Warning("VFS", "VFS_SaveHandles - Invalid FD 0x%x (%i) in slot %i", fd, FDs[i], i ); free(ret); return NULL; } // Log("%i: Duplicate FD %i (%p)", i, fd, h->Node); memcpy( &ret[i], h, sizeof(tVFS_Handle) ); } } // Reference nodes/mounts for( int i = 0; i < NumFDs; i ++ ) { tVFS_Handle *h = &ret[i]; // Reference node if( !h->Node ) continue ; // Debug("VFS_SaveHandles: %i %p", i, h->Node); _ReferenceNode(h->Node); h->Mount->OpenHandleCount ++; } return ret; }
/** * \return Number of files with an action */ int VFS_int_Select_Deregister(tThread *Thread, int MaxHandle, fd_set *Handles, int Type, BOOL IsKernel) { int i, numFlagged = 0; tVFS_SelectList **list; int *flag, wantedFlagValue; if( !Handles ) return 0; ENTER("pThread iMaxHandle pHandles iType iIsKernel", Thread, MaxHandle, Handles, Type, IsKernel); for( i = 0; i < MaxHandle; i ++ ) { tVFS_Handle *handle; // Is the descriptor set if( !FD_ISSET(i, Handles) ) continue; LOG("FD #%i", i); handle = VFS_GetHandle( i | (IsKernel?VFS_KERNEL_FLAG:0) ); // Is the handle valid? if( !handle || !handle->Node ) { if( Type == 2 ) { // Bad FD counts as an error numFlagged ++; } else { FD_CLR(i, Handles); } continue; } // Get the type of the listen if( VFS_int_Select_GetType(Type, handle->Node, &list, &flag, &wantedFlagValue, NULL) ) { LEAVE('i', 0); return 0; } // Remove VFS_int_Select_RemThread(*list, Thread ); // Check for the flag if( !!*flag == !!wantedFlagValue ) { numFlagged ++; LOG(" %i == want %i", !!*flag, !!wantedFlagValue); FD_SET(i, Handles); } else { FD_CLR(i, Handles); } } LEAVE('i', numFlagged); return numFlagged; }
/** * \brief Take a backup of a set of file descriptors */ void *VFS_SaveHandles(int NumFDs, int *FDs) { tVFS_Handle *ret; int i; int max_handles = *Threads_GetMaxFD(); // Check if this process has any handles if( MM_GetPhysAddr( gaUserHandles ) == 0 ) return NULL; // Allocate ret = malloc( NumFDs * sizeof(tVFS_Handle) ); if( !ret ) return NULL; if( NumFDs > max_handles ) NumFDs = max_handles; // Take copies of the handles for( i = 0; i < NumFDs; i ++ ) { tVFS_Handle *h; if( FDs == NULL ) h = &gaUserHandles[i]; else if( FDs[i] == -1 ) { Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (-1), ignorning", i); memset(&ret[i], 0, sizeof(tVFS_Handle)); continue ; } else { h = VFS_GetHandle(FDs[i] & (VFS_KERNEL_FLAG - 1)); if(!h) { Log_Warning("VFS", "VFS_SaveHandles - Invalid FD %i", FDs[i] & (VFS_KERNEL_FLAG - 1) ); free(ret); return NULL; } } memcpy( &ret[i], h, sizeof(tVFS_Handle) ); // Reference node if( !h->Node ) continue ; _ReferenceNode(h->Node); h->Mount->OpenHandleCount ++; } return ret; }