1 /* $Id: fdtable.c,v 1.2 2002/02/20 09:17:57 hyperion Exp $
4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS POSIX+ Subsystem
6 * FILE: subsys/psx/lib/psxdll/misc/fdtable.c
7 * PURPOSE: File descriptors table functions
8 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
15 #include <psx/fdtable.h>
16 #include <psx/stdlib.h>
17 #include <psx/debug.h>
18 #include <psx/safeobj.h>
20 int __fdtable_init(__fdtable_t
* fdtable
)
28 memset(fdtable
, 0, sizeof(*fdtable
));
30 fdtable
->Signature
= __FDTABLE_MAGIC
;
35 int __fdtable_free(__fdtable_t
* fdtable
)
43 __free(&fdtable
->Descriptors
);
45 memset(fdtable
, 0, sizeof(*fdtable
));
47 fdtable
->Signature
= MAGIC('B', 'A', 'A', 'D');
52 int __fdtable_entry_isavail(__fdtable_t
* fdtable
, int fileno
)
54 return ((fdtable
->DescriptorsBitmap
[fileno
/ 32] >> (fileno
% 32)) % 2);
57 int __fdtable_entry_nextavail(__fdtable_t
* fdtable
, int fileno
)
63 nUnusedIndex
= fileno
;
65 /* The file descriptors bitmap is an array of 32 bit unsigned integers (32 bit
66 integers were chosen for proper data alignment without padding). The array is
67 big enough to hold at least OPEN_MAX bits, that is it has OPEN_MAX / 32 cells
68 (see also the __fdtable_t definition in psx/fdtable.h). Bits correspond to
69 file numbers: if a bit is 1, the corresponding file number is in use, else
70 it's unused. Bit numbering is right-to-left wise, that is the rightmost (least
71 significative) bit of cell 0 corresponds to file number 0, the leftmost (most
72 significative) bit of cell 0 to file number 7, the leftmost bit of cell 1 to
73 file number 8, and so on
75 /* NOTE: I'm sure the algorytm can be greatly optimized, but I prefer to privilege
76 readability - it allows for more maintenable code. Please don't pretend to
77 outsmart the compiler: such optimizations as performing divisions as bit shifts
80 /* index of the bitmap cell containing nUnusedIndex */
81 nCurMapIndex
= nUnusedIndex
/ 32;
83 /* get a copy of the bitmap cell containg nUnusedIndex, and shift it to the right
84 so that the rightmost (least significative) bit is the one referencing nUnusedIndex */
85 nCurMapCell
= fdtable
->DescriptorsBitmap
[nCurMapIndex
] >> (nUnusedIndex
% 32);
89 /* if the least significative bit of the current cell is 0, we've found an unused
90 fileno, and we return it */
91 if((nCurMapCell
% 2) == 0)
92 return (nUnusedIndex
);
94 /* on to next fileno */
97 /* this is NOT a failure. -1 with undefined errno means that no unused file
99 if(nUnusedIndex
>= OPEN_MAX
)
102 /* this fileno is referenced in the next cell */
103 if((nUnusedIndex
% 32) == 0)
106 nCurMapCell
= fdtable
->DescriptorsBitmap
[nCurMapIndex
];
108 /* on to next fileno (bit) in the current cell */
116 int __fdtable_entry_add(__fdtable_t
* fdtable
, int fileno
, __fildes_t
* fildes
, __fildes_t
** newfd
)
120 /* descriptors count reached OPEN_MAX */
121 if(fdtable
->UsedDescriptors
>= OPEN_MAX
)
123 ERR("file descriptor table full");
128 /* base fileno less than zero: use the lowest unused fileno */
130 nFileNo
= fdtable
->LowestUnusedFileNo
;
131 /* base fileno greater than or equal to zero: use the next available fileno */
133 nFileNo
= __fdtable_entry_nextavail(fdtable
, fileno
);
135 INFO("lowest unused file number is %d", nFileNo
);
137 /* descriptors count reached OPEN_MAX */
140 ERR("nFileNo is less than zero");
145 /* if the table doesn't have enough space for the next entry ... */
146 if(nFileNo
>= fdtable
->AllocatedDescriptors
)
152 "growing the array from %lu to %lu bytes",
153 fdtable
->AllocatedDescriptors
* sizeof(*fdtable
->Descriptors
),
154 (nFileNo
+ 1) * sizeof(*fdtable
->Descriptors
)
157 /* ... try to increase the size of the table */
160 fdtable
->Descriptors
,
161 (nFileNo
+ 1) * sizeof(*fdtable
->Descriptors
)
164 /* reallocation failed */
167 ERR("__realloc() failed");
172 /* update the table */
173 fdtable
->AllocatedDescriptors
= nFileNo
+ 1;
174 fdtable
->Descriptors
= pTemp
;
177 /* initialize descriptor */
179 memset(&fdtable
->Descriptors
[nFileNo
], 0, sizeof(__fildes_t
));
181 memcpy(&fdtable
->Descriptors
[nFileNo
], fildes
, sizeof(__fildes_t
));
184 *newfd
= &fdtable
->Descriptors
[nFileNo
];
188 "file number %d: handle 0x%08X, open flags 0x%08X, flags 0x%08X, extra data size %u, extra data at 0x%08X",
190 fdtable
->Descriptors
[nFileNo
].FileHandle
,
191 fdtable
->Descriptors
[nFileNo
].OpenFlags
,
192 fdtable
->Descriptors
[nFileNo
].FdFlags
,
193 fdtable
->Descriptors
[nFileNo
].ExtraDataSize
,
194 fdtable
->Descriptors
[nFileNo
].ExtraData
199 "incrementing used descriptors count from %u to %u",
200 fdtable
->UsedDescriptors
,
201 fdtable
->UsedDescriptors
+ 1
203 fdtable
->UsedDescriptors
++;
207 "setting bit %u of cell %u of the bitmap to 1",
211 fdtable
->DescriptorsBitmap
[nFileNo
/ 32] |= (1 << (nFileNo
% 32));
213 fdtable
->LowestUnusedFileNo
= __fdtable_entry_nextavail(fdtable
, nFileNo
);
214 INFO("setting the lowest unused file number to %d", fdtable
->LowestUnusedFileNo
);
219 int __fdtable_entry_remove(__fdtable_t
* fdtable
, int fileno
)
224 __fildes_t
*__fdtable_entry_get(__fdtable_t
* fdtable
, int fileno
)
226 /* this fileno hasn't been allocated */
227 if(fileno
>= fdtable
->AllocatedDescriptors
)
230 return (&fdtable
->Descriptors
[fileno
]);