2404587c07d3d304589984001cefcb4d04ad04d0
1 /* $Id: fcntl.c,v 1.4 2002/03/21 22:41:53 hyperion Exp $
4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS POSIX+ Subsystem
6 * FILE: subsys/psx/lib/psxdll/fcntl/fcntl.c
7 * PURPOSE: File control
8 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
11 * 15/02/2002: Implemented fcntl() (KJK::Hyperion)
14 #include <ddk/ntddk.h>
15 #include <sys/types.h>
20 #include <psx/errno.h>
21 #include <psx/stdlib.h>
22 #include <psx/fdtable.h>
23 #include <psx/pdata.h>
24 #include <psx/debug.h>
26 int fcntl(int fildes
, int cmd
, ...)
28 __fdtable_t
*pftFdTable
;
29 __fildes_t
*pfdDescriptor
;
36 /* lock the environment */
37 __PdxAcquirePdataLock();
39 /* get the file descriptors table */
40 pftFdTable
= &__PdxGetProcessData()->FdTable
;
42 /* fildes is an invalid, closed or uninitialized descriptor */
47 __fdtable_entry_isavail(pftFdTable
, fildes
) == 0 ||
48 __fdtable_entry_get(pftFdTable
, fildes
) == 0
52 __PdxReleasePdataLock();
56 /* get the file descriptor referenced by fildes */
57 pfdDescriptor
= __fdtable_entry_get(pftFdTable
, fildes
);
59 /* get third argument as integer */
60 va_start(vlArgs
, cmd
);
61 nThirdArg
= va_arg(vlArgs
, int);
64 /* get third argument as pointer */
65 va_start(vlArgs
, cmd
);
66 pThirdArg
= va_arg(vlArgs
, void *);
69 /* initialize return value */
77 __fildes_t
*pfdDupDescriptor
;
79 /* allocate the duplicated descriptor */
80 nDupFileNo
= __fdtable_entry_add(pftFdTable
, nThirdArg
, 0, &pfdDupDescriptor
);
85 /* copy the open flags */
86 pfdDupDescriptor
->OpenFlags
= pfdDescriptor
->OpenFlags
;
88 /* clear the FD_CLOEXEC flag */
89 pfdDupDescriptor
->FdFlags
= pfdDescriptor
->FdFlags
& ~FD_CLOEXEC
;
91 /* duplicate the extra data */
92 if(pfdDescriptor
->ExtraDataSize
!= 0 && pfdDescriptor
->ExtraData
!= 0)
94 /* allocate space for the duplicated extra data */
95 pfdDupDescriptor
->ExtraDataSize
= pfdDescriptor
->ExtraDataSize
;
96 pfdDupDescriptor
->ExtraData
= __malloc(pfdDupDescriptor
->ExtraDataSize
);
99 if(pfdDupDescriptor
->ExtraData
== 0)
105 /* copy the extra data */
106 memcpy(pfdDupDescriptor
->ExtraData
, pfdDescriptor
->ExtraData
, pfdDupDescriptor
->ExtraDataSize
);
109 "copied %u bytes from 0x%08X into 0x%08X",
110 pfdDupDescriptor
->ExtraDataSize
,
111 pfdDescriptor
->ExtraData
,
112 pfdDupDescriptor
->ExtraData
116 /* duplicate the handle */
117 nErrCode
= NtDuplicateObject
120 pfdDescriptor
->FileHandle
,
122 &pfdDupDescriptor
->FileHandle
,
125 DUPLICATE_SAME_ACCESS
/* | DUPLICATE_SAME_ATTRIBUTES */
129 if(!NT_SUCCESS(nErrCode
))
131 __free(pfdDupDescriptor
->ExtraData
);
132 errno
= __status_to_errno(nErrCode
);
138 "duplicated handle 0x%08X into handle 0x%08X",
139 pfdDescriptor
->FileHandle
,
140 pfdDupDescriptor
->FileHandle
143 /* return the duplicated file number */
144 nRetVal
= nDupFileNo
;
150 nRetVal
= pfdDescriptor
->FdFlags
;
156 pfdDescriptor
->FdFlags
= nThirdArg
;
163 nRetVal
= pfdDescriptor
->OpenFlags
;
169 pfdDescriptor
->OpenFlags
= nThirdArg
;
194 /* allocate a new descriptor */
195 nRetVal
= __fdtable_entry_add(pftFdTable
, fildes
, (__fildes_t
*)pThirdArg
, 0);
201 /* invalid return pointer */
208 memcpy((__fildes_t
*)pThirdArg
, pfdDescriptor
, sizeof(*pfdDescriptor
));
210 /* remove file descriptor */
211 nRetVal
= __fdtable_entry_remove(pftFdTable
, fildes
);
217 /* invalid return pointer */
224 /* return a copy of the file descriptor */
225 memcpy((__fildes_t
*)pThirdArg
, pfdDescriptor
, sizeof(*pfdDescriptor
));
231 /* invalid file descriptor to copy attributes from */
238 /* copy the attributes of file descriptor from the provided descriptor */
239 memcpy(pfdDescriptor
, pThirdArg
, sizeof(*pfdDescriptor
));
245 /* invalid return pointer */
252 /* return a pointer to the extra data associated to the descriptor */
253 *((void **)pThirdArg
) = pfdDescriptor
->ExtraData
;
260 /* set the pointer to the extra data associated */
261 pfdDescriptor
->ExtraData
= pThirdArg
;
268 nRetVal
= pfdDescriptor
->ExtraDataSize
;
274 pfdDescriptor
->ExtraDataSize
= nThirdArg
;
281 /* invalid return pointer */
288 /* return the handle associated to the descriptor */
289 *((void **)pThirdArg
) = pfdDescriptor
->FileHandle
;
296 pfdDescriptor
->FileHandle
= pThirdArg
;
305 /* unlock the environment */
306 __PdxReleasePdataLock();