+++ /dev/null
-/* $Id: fdtable.c,v 1.6 2002/10/29 04:45:31 rex Exp $
- */
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS POSIX+ Subsystem
- * FILE: subsys/psx/lib/psxdll/misc/fdtable.c
- * PURPOSE: File descriptors table functions
- * PROGRAMMER: KJK::Hyperion <noog@libero.it>
- * UPDATE HISTORY:
- * 12/02/2002: Created
- */
-
-#include <string.h>
-#include <errno.h>
-#include <psx/fdtable.h>
-#include <psx/stdlib.h>
-#include <psx/debug.h>
-#include <psx/safeobj.h>
-
-int __fdtable_init(__fdtable_t * fdtable)
-{
- if(fdtable == 0)
- {
- errno = EINVAL;
- return (-1);
- }
-
- memset(fdtable, 0, sizeof(*fdtable));
-
- fdtable->Signature = __FDTABLE_MAGIC;
-
- return (0);
-}
-
-int __fdtable_free(__fdtable_t * fdtable)
-{
- if(fdtable == 0)
- {
- errno = EINVAL;
- return (-1);
- }
-
- __free(&fdtable->Descriptors);
-
- memset(fdtable, 0, sizeof(*fdtable));
-
- fdtable->Signature = MAGIC('B', 'A', 'A', 'D');
-
- return (0);
-}
-
-int __fdtable_entry_isavail(__fdtable_t * fdtable, int fileno)
-{
- return ((fdtable->DescriptorsBitmap[fileno / 32] >> (fileno % 32)) % 2);
-}
-
-int __fdtable_entry_nextavail(__fdtable_t * fdtable, int fileno)
-{
- int nCurMapIndex;
- int nUnusedIndex;
- uint32_t nCurMapCell;
-
- nUnusedIndex = fileno;
-
- /* The file descriptors bitmap is an array of 32 bit unsigned integers (32 bit
- integers were chosen for proper data alignment without padding). The array is
- big enough to hold at least OPEN_MAX bits, that is it has OPEN_MAX / 32 cells
- (see also the __fdtable_t definition in psx/fdtable.h). Bits correspond to
- file numbers: if a bit is 1, the corresponding file number is in use, else
- it's unused. Bit numbering is right-to-left wise, that is the rightmost (least
- significative) bit of cell 0 corresponds to file number 0, the leftmost (most
- significative) bit of cell 0 to file number 7, the leftmost bit of cell 1 to
- file number 8, and so on
- */
- /* NOTE: I'm sure the algorytm can be greatly optimized, but I prefer to privilege
- readability - it allows for more maintenable code. Please don't pretend to
- outsmart the compiler: such optimizations as performing divisions as bit shifts
- are useless */
-
- /* index of the bitmap cell containing nUnusedIndex */
- nCurMapIndex = nUnusedIndex / 32;
-
- /* get a copy of the bitmap cell containg nUnusedIndex, and shift it to the right
- so that the rightmost (least significative) bit is the one referencing nUnusedIndex */
- nCurMapCell = fdtable->DescriptorsBitmap[nCurMapIndex] >> (nUnusedIndex % 32);
-
- while(1)
- {
- /* if the least significative bit of the current cell is 0, we've found an unused
- fileno, and we return it */
- if((nCurMapCell % 2) == 0)
- return (nUnusedIndex);
-
- /* on to next fileno */
- nUnusedIndex ++;
-
- /* this is NOT a failure. -1 with undefined errno means that no unused file
- number exists */
- if(nUnusedIndex >= OPEN_MAX)
- return (-1);
-
- /* this fileno is referenced in the next cell */
- if((nUnusedIndex % 32) == 0)
- {
- nCurMapIndex ++;
- nCurMapCell = fdtable->DescriptorsBitmap[nCurMapIndex];
- }
- /* on to next fileno (bit) in the current cell */
- else
- nCurMapCell >>= 1;
- }
-
- return (-1);
-}
-
-int __fdtable_entry_add(__fdtable_t * fdtable, int fileno, __fildes_t * fildes, __fildes_t ** newfd)
-{
- int nFileNo;
-
- /* descriptors count reached OPEN_MAX */
- if(fdtable->UsedDescriptors >= OPEN_MAX)
- {
- ERR("file descriptor table full");
- errno = EMFILE;
- return (-1);
- }
-
- /* base fileno less than zero: use the lowest unused fileno */
- if(fileno < 0)
- nFileNo = fdtable->LowestUnusedFileNo;
- /* base fileno greater than or equal to zero: use the next available fileno */
- else
- nFileNo = __fdtable_entry_nextavail(fdtable, fileno);
-
- INFO("lowest unused file number is %d", nFileNo);
-
- /* descriptors count reached OPEN_MAX */
- if(nFileNo < 0)
- {
- ERR("nFileNo is less than zero");
- errno = EMFILE;
- return (-1);
- }
-
- /* if the table doesn't have enough space for the next entry ... */
- if(nFileNo >= fdtable->AllocatedDescriptors)
- {
- void * pTemp;
-
- INFO
- (
- "growing the array from %lu to %lu bytes",
- fdtable->AllocatedDescriptors * sizeof(*fdtable->Descriptors),
- (nFileNo + 1) * sizeof(*fdtable->Descriptors)
- );
-
- /* ... try to increase the size of the table */
- if(fdtable->AllocatedDescriptors * sizeof(*fdtable->Descriptors) == 0)
- pTemp = __malloc((nFileNo + 1) * sizeof(*fdtable->Descriptors));
- else
- pTemp = __realloc
- (
- fdtable->Descriptors,
- (nFileNo + 1) * sizeof(*fdtable->Descriptors)
- );
-
- /* reallocation failed */
- if(pTemp == 0)
- {
- ERR("__realloc() failed");
- errno = ENOMEM;
- return (-1);
- }
-
- /* update the table */
- fdtable->AllocatedDescriptors = nFileNo + 1;
- fdtable->Descriptors = pTemp;
- }
-
- /* initialize descriptor */
- if(fildes == 0)
- memset(&fdtable->Descriptors[nFileNo], 0, sizeof(__fildes_t));
- else
- memcpy(&fdtable->Descriptors[nFileNo], fildes, sizeof(__fildes_t));
-
- if(newfd != 0)
- *newfd = &fdtable->Descriptors[nFileNo];
-
- INFO
- (
- "file number %d: handle 0x%08X, open flags 0x%08X, flags 0x%08X, extra data size %u, extra data at 0x%08X",
- nFileNo,
- fdtable->Descriptors[nFileNo].FileHandle,
- fdtable->Descriptors[nFileNo].OpenFlags,
- fdtable->Descriptors[nFileNo].FdFlags,
- fdtable->Descriptors[nFileNo].ExtraDataSize,
- fdtable->Descriptors[nFileNo].ExtraData
- );
-
- INFO
- (
- "incrementing used descriptors count from %u to %u",
- fdtable->UsedDescriptors,
- fdtable->UsedDescriptors + 1
- );
- fdtable->UsedDescriptors ++;
-
- INFO
- (
- "setting bit %u of cell %u of the bitmap to 1",
- nFileNo % 32,
- nFileNo / 32
- );
- fdtable->DescriptorsBitmap[nFileNo / 32] |= (1 << (nFileNo % 32));
-
- fdtable->LowestUnusedFileNo = __fdtable_entry_nextavail(fdtable, nFileNo);
- INFO("setting the lowest unused file number to %d", fdtable->LowestUnusedFileNo);
-
- return (nFileNo);
-}
-
-int __fdtable_entry_remove(__fdtable_t * fdtable, int fileno)
-{
- return (-1);
-}
-
-__fildes_t *__fdtable_entry_get(__fdtable_t * fdtable, int fileno)
-{
- /* this fileno hasn't been allocated */
- if(fileno >= fdtable->AllocatedDescriptors)
- return (0);
-
- /* TODO: check the fileno against the bitmap */
- return (&fdtable->Descriptors[fileno]);
-}
-
-/* EOF */
-