30a83dce1af5fdf1692d87f619606e260adc5952
1 /* $Id: fcntl.c,v 1.5 2002/05/17 01:54:39 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();
38 INFO("environment locked");
40 /* get the file descriptors table */
41 pftFdTable
= &__PdxGetProcessData()->FdTable
;
42 INFO("file descriptors table at 0x%08X", pftFdTable
);
44 /* fildes is an invalid descriptor, or it's a closed or uninitialized
45 descriptor and the requested operation is not the creation of a new
54 __fdtable_entry_isavail(pftFdTable
, fildes
) == 0 ||
55 __fdtable_entry_get(pftFdTable
, fildes
) == 0
60 INFO("invalid file descriptor");
62 __PdxReleasePdataLock();
66 /* get the file descriptor referenced by fildes */
67 pfdDescriptor
= __fdtable_entry_get(pftFdTable
, fildes
);
68 INFO("file descriptor %d at 0x%08X", fildes
, pftFdTable
);
70 /* get third argument as integer */
71 va_start(vlArgs
, cmd
);
72 nThirdArg
= va_arg(vlArgs
, int);
75 /* get third argument as pointer */
76 va_start(vlArgs
, cmd
);
77 pThirdArg
= va_arg(vlArgs
, void *);
80 /* initialize return value */
88 __fildes_t
*pfdDupDescriptor
;
90 INFO("requested operation: F_DUPFD");
92 /* allocate the duplicated descriptor */
93 nDupFileNo
= __fdtable_entry_add(pftFdTable
, nThirdArg
, 0, &pfdDupDescriptor
);
97 ERR("__fdtable_entry_add() failed, errno %d", errno
);
101 /* copy the open flags */
102 pfdDupDescriptor
->OpenFlags
= pfdDescriptor
->OpenFlags
;
104 /* clear the FD_CLOEXEC flag */
105 pfdDupDescriptor
->FdFlags
= pfdDescriptor
->FdFlags
& ~FD_CLOEXEC
;
107 /* duplicate the extra data */
108 if(pfdDescriptor
->ExtraDataSize
!= 0 && pfdDescriptor
->ExtraData
!= 0)
110 /* allocate space for the duplicated extra data */
111 pfdDupDescriptor
->ExtraDataSize
= pfdDescriptor
->ExtraDataSize
;
112 pfdDupDescriptor
->ExtraData
= __malloc(pfdDupDescriptor
->ExtraDataSize
);
115 if(pfdDupDescriptor
->ExtraData
== 0)
121 /* copy the extra data */
122 memcpy(pfdDupDescriptor
->ExtraData
, pfdDescriptor
->ExtraData
, pfdDupDescriptor
->ExtraDataSize
);
125 "copied %u bytes from 0x%08X into 0x%08X",
126 pfdDupDescriptor
->ExtraDataSize
,
127 pfdDescriptor
->ExtraData
,
128 pfdDupDescriptor
->ExtraData
132 /* duplicate the handle */
133 nErrCode
= NtDuplicateObject
136 pfdDescriptor
->FileHandle
,
138 &pfdDupDescriptor
->FileHandle
,
141 DUPLICATE_SAME_ACCESS
/* | DUPLICATE_SAME_ATTRIBUTES */
145 if(!NT_SUCCESS(nErrCode
))
147 __free(pfdDupDescriptor
->ExtraData
);
148 errno
= __status_to_errno(nErrCode
);
154 "duplicated handle 0x%08X into handle 0x%08X",
155 pfdDescriptor
->FileHandle
,
156 pfdDupDescriptor
->FileHandle
159 /* return the duplicated file number */
160 nRetVal
= nDupFileNo
;
166 INFO("requested operation: F_GETFD");
167 nRetVal
= pfdDescriptor
->FdFlags
;
173 INFO("requested operation: F_SETFD");
174 pfdDescriptor
->FdFlags
= nThirdArg
;
181 INFO("requested operation: F_GETFL");
182 nRetVal
= pfdDescriptor
->OpenFlags
;
188 INFO("requested operation: F_SETFL");
189 pfdDescriptor
->OpenFlags
= nThirdArg
;
196 INFO("requested operation: F_GETLK");
203 INFO("requested operation: F_SETLK");
210 INFO("requested operation: F_SETLKW");
217 INFO("requested operation: F_NEWFD");
218 /* allocate a new descriptor */
219 nRetVal
= __fdtable_entry_add(pftFdTable
, fildes
, (__fildes_t
*)pThirdArg
, 0);
225 INFO("requested operation: F_DELFD");
226 /* invalid return pointer */
233 memcpy((__fildes_t
*)pThirdArg
, pfdDescriptor
, sizeof(*pfdDescriptor
));
235 /* remove file descriptor */
236 nRetVal
= __fdtable_entry_remove(pftFdTable
, fildes
);
242 INFO("requested operation: F_GETALL");
243 /* invalid return pointer */
250 /* return a copy of the file descriptor */
251 memcpy((__fildes_t
*)pThirdArg
, pfdDescriptor
, sizeof(*pfdDescriptor
));
259 INFO("requested operation: F_SETALL");
260 /* invalid file descriptor to copy attributes from */
267 /* copy the attributes of file descriptor from the provided descriptor */
268 memcpy(pfdDescriptor
, pThirdArg
, sizeof(*pfdDescriptor
));
276 INFO("requested operation: F_GETXP");
277 /* invalid return pointer */
284 /* return a pointer to the extra data associated to the descriptor */
285 *((void **)pThirdArg
) = pfdDescriptor
->ExtraData
;
293 INFO("requested operation: F_SETXP");
294 /* set the pointer to the extra data associated */
295 pfdDescriptor
->ExtraData
= pThirdArg
;
302 INFO("requested operation: F_GETXS");
303 nRetVal
= pfdDescriptor
->ExtraDataSize
;
309 INFO("requested operation: F_SETXS");
310 pfdDescriptor
->ExtraDataSize
= nThirdArg
;
317 INFO("requested operation: F_GETFH");
318 /* invalid return pointer */
325 /* return the handle associated to the descriptor */
326 *((void **)pThirdArg
) = pfdDescriptor
->FileHandle
;
333 INFO("requested operation: F_SETFH");
334 pfdDescriptor
->FileHandle
= pThirdArg
;
340 INFO("invalid operation requested");
344 /* unlock the environment */
345 __PdxReleasePdataLock();
346 INFO("environment unlocked");