diff --git a/sortix/dtable.cpp b/sortix/dtable.cpp index f3786679..40136d3b 100644 --- a/sortix/dtable.cpp +++ b/sortix/dtable.cpp @@ -101,12 +101,15 @@ bool DescriptorTable::Enlargen(int atleast) return true; } -int DescriptorTable::Allocate(Ref desc, int flags) +int DescriptorTable::AllocateInternal(Ref desc, int flags, + int min_index) { + // dtablelock is held. if ( flags & ~__FD_ALLOWED_FLAGS ) return errno = EINVAL, -1; - ScopedLock lock(&dtablelock); - for ( int i = 0; i < numentries; i++ ) + if ( min_index < 0 ) + return errno = EINVAL, -1; + for ( int i = min_index; i < numentries; i++ ) if ( !entries[i].desc ) { entries[i].desc = desc; @@ -114,7 +117,7 @@ int DescriptorTable::Allocate(Ref desc, int flags) return i; } int oldnumentries = numentries; - if ( !Enlargen(0) ) + if ( !Enlargen(min_index) ) return -1; int i = oldnumentries++; entries[i].desc = desc; @@ -122,6 +125,20 @@ int DescriptorTable::Allocate(Ref desc, int flags) return i; } +int DescriptorTable::Allocate(Ref desc, int flags, int min_index) +{ + ScopedLock lock(&dtablelock); + return AllocateInternal(desc, flags, min_index); +} + +int DescriptorTable::Allocate(int src_index, int flags, int min_index) +{ + ScopedLock lock(&dtablelock); + if ( !IsGoodEntry(src_index) ) + return errno = EBADF, -1; + return AllocateInternal(entries[src_index].desc, flags, min_index); +} + int DescriptorTable::Copy(int from, int to, int flags) { if ( flags & ~__FD_ALLOWED_FLAGS ) diff --git a/sortix/include/sortix/kernel/dtable.h b/sortix/include/sortix/kernel/dtable.h index 5df265b3..70ae49d4 100644 --- a/sortix/include/sortix/kernel/dtable.h +++ b/sortix/include/sortix/kernel/dtable.h @@ -44,7 +44,8 @@ public: ~DescriptorTable(); Ref Fork(); Ref Get(int index); - int Allocate(Ref desc, int flags); + int Allocate(Ref desc, int flags, int min_index = 0); + int Allocate(int src_index, int flags, int min_index = 0); int Copy(int from, int to, int flags); void Free(int index); Ref FreeKeep(int index); @@ -56,6 +57,7 @@ private: void Reset(); // Hey, reference counted. Don't call this. bool IsGoodEntry(int i); bool Enlargen(int atleast); + int AllocateInternal(Ref desc, int flags, int min_index); private: kthread_mutex_t dtablelock;