implemented read and write system calls
[reactos.git] / posix / lib / psxdll / unistd / read.c
1 /* $Id: read.c,v 1.2 2002/03/21 22:46:30 hyperion Exp $
2 */
3 /*
4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS POSIX+ Subsystem
6 * FILE: subsys/psx/lib/psxdll/unistd/read.c
7 * PURPOSE: Read from a file
8 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
9 * UPDATE HISTORY:
10 * 15/02/2002: Created
11 */
12
13 #include <ddk/ntddk.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <sys/types.h>
17 #include <psx/debug.h>
18 #include <psx/errno.h>
19
20 ssize_t __read(int fildes, void *buf, size_t nbyte, off_t *offset)
21 {
22 HANDLE hFile;
23 NTSTATUS nErrCode;
24 IO_STATUS_BLOCK isbStatus;
25
26 /* get the file handle for the specified file descriptor */
27 if(fcntl(fildes, F_GETFH, &hFile) == -1)
28 return (-1);
29
30 if(offset != NULL)
31 {
32 /* NT always moves the file pointer, while Unix pread() must not: we have to
33 duplicate the handle and work on the duplicate */ /* FIXME? better save
34 the file position and restore it later? */
35 HANDLE hDupFile;
36
37 /* duplicate the handle */
38 nErrCode = NtDuplicateObject
39 (
40 NtCurrentProcess(),
41 hFile,
42 NtCurrentProcess(),
43 &hDupFile,
44 0,
45 0,
46 DUPLICATE_SAME_ACCESS
47 );
48
49 /* failure */
50 if(!NT_SUCCESS(nErrCode))
51 {
52 errno = __status_to_errno(nErrCode);
53 return (0);
54 }
55
56 /* read data from file at the specified offset */
57 nErrCode = NtReadFile
58 (
59 hDupFile,
60 NULL,
61 NULL,
62 NULL,
63 &isbStatus,
64 buf,
65 nbyte,
66 (PLARGE_INTEGER)offset,
67 NULL
68 );
69
70 NtClose(hDupFile);
71
72 /* failure */
73 if(!NT_SUCCESS(nErrCode))
74 {
75 errno = __status_to_errno(nErrCode);
76 return (0);
77 }
78 }
79 else
80 {
81 /* read data from file at the current offset */
82 nErrCode = NtReadFile
83 (
84 hFile,
85 NULL,
86 NULL,
87 NULL,
88 &isbStatus,
89 buf,
90 nbyte,
91 NULL,
92 NULL
93 );
94
95 /* failure */
96 if(!NT_SUCCESS(nErrCode))
97 {
98 errno = __status_to_errno(nErrCode);
99 return (0);
100 }
101 }
102
103 return ((ssize_t)isbStatus.Information);
104 }
105
106 ssize_t read(int fildes, void *buf, size_t nbyte)
107 {
108 return (__read(fildes, buf, nbyte, NULL));
109 }
110
111 ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
112 {
113 return (__read(fildes, buf, nbyte, &offset));
114 }
115
116 /* EOF */
117