diff --git a/posix/lib/psxdll/unistd/read.c b/posix/lib/psxdll/unistd/read.c index a3ce7126058..a6d6e0f045d 100644 --- a/posix/lib/psxdll/unistd/read.c +++ b/posix/lib/psxdll/unistd/read.c @@ -1,4 +1,4 @@ -/* $Id: +/* $Id: read.c,v 1.2 2002/03/21 22:46:30 hyperion Exp $ */ /* * COPYRIGHT: See COPYING in the top level directory @@ -11,14 +11,13 @@ */ #include +#include #include #include +#include +#include -ssize_t read(int fildes, void *buf, size_t nbyte) -{ -} - -ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset) +ssize_t __read(int fildes, void *buf, size_t nbyte, off_t *offset) { HANDLE hFile; NTSTATUS nErrCode; @@ -28,22 +27,91 @@ ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset) if(fcntl(fildes, F_GETFH, &hFile) == -1) return (-1); - /* read data from file */ - nErrCode = NtReadFile - ( - hFile, - NULL, - NULL, - NULL, - &isbStatus, - buf, - nbyte, - (PLARGE_INTEGER)&off_t, - NULL - ); + if(offset != NULL) + { + /* NT always moves the file pointer, while Unix pread() must not: we have to + duplicate the handle and work on the duplicate */ /* FIXME? better save + the file position and restore it later? */ + HANDLE hDupFile; + + /* duplicate the handle */ + nErrCode = NtDuplicateObject + ( + NtCurrentProcess(), + hFile, + NtCurrentProcess(), + &hDupFile, + 0, + 0, + DUPLICATE_SAME_ACCESS + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + errno = __status_to_errno(nErrCode); + return (0); + } + + /* read data from file at the specified offset */ + nErrCode = NtReadFile + ( + hDupFile, + NULL, + NULL, + NULL, + &isbStatus, + buf, + nbyte, + (PLARGE_INTEGER)offset, + NULL + ); + + NtClose(hDupFile); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + errno = __status_to_errno(nErrCode); + return (0); + } + } + else + { + /* read data from file at the current offset */ + nErrCode = NtReadFile + ( + hFile, + NULL, + NULL, + NULL, + &isbStatus, + buf, + nbyte, + NULL, + NULL + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + errno = __status_to_errno(nErrCode); + return (0); + } + } return ((ssize_t)isbStatus.Information); } +ssize_t read(int fildes, void *buf, size_t nbyte) +{ + return (__read(fildes, buf, nbyte, NULL)); +} + +ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset) +{ + return (__read(fildes, buf, nbyte, &offset)); +} + /* EOF */ diff --git a/posix/lib/psxdll/unistd/write.c b/posix/lib/psxdll/unistd/write.c index 25ab55a4f86..9182e26c6be 100644 --- a/posix/lib/psxdll/unistd/write.c +++ b/posix/lib/psxdll/unistd/write.c @@ -1,4 +1,4 @@ -/* $Id: write.c,v 1.2 2002/02/20 09:17:58 hyperion Exp $ +/* $Id: write.c,v 1.3 2002/03/21 22:46:30 hyperion Exp $ */ /* * COPYRIGHT: See COPYING in the top level directory @@ -8,8 +8,55 @@ * PROGRAMMER: KJK::Hyperion * UPDATE HISTORY: * 15/02/2002: Created + * 21/03/2002: Implemented write() (KJK::Hyperion ) */ +#include +#include +#include +#include +#include +#include +#include + +ssize_t write(int fildes, const void *buf, size_t nbyte) +{ + __fildes_t fdDescriptor; + NTSTATUS nErrCode; + IO_STATUS_BLOCK isbStatus; + + if(nbyte == 0) + return (0); + + if(fcntl(fildes, F_GETALL, &fdDescriptor) == -1) + return (0); + + if((fdDescriptor.OpenFlags && O_APPEND) == O_APPEND) + { + TODO("move file pointer to the end"); + } + + nErrCode = NtWriteFile + ( + fdDescriptor.FileHandle, + NULL, + NULL, + NULL, + &isbStatus, + (PVOID)buf, + nbyte, + NULL, + NULL + ); + + if(!NT_SUCCESS(nErrCode)) + { + errno = __status_to_errno(nErrCode); + return (0); + } + + return (isbStatus.Information); +} /* EOF */