/* read.c (rsxnt) -- Copyright (c) 1996-1997 Rainer Schnitker */

#include "rsxnt.h"

int __read (int fd, void *buf, size_t nbyte)
{
    EMXPROCESS *p = _rsxnt_get_process_ptr();
    DWORD n;

    if (fd >= N_FILES || fd < 0)
	return _rsxnt_errno(EBADF);
    if (p->file[fd].f_handle == INVALID_HANDLE_VALUE)
	return _rsxnt_errno(EBADF);

#ifndef EMX_SYS_LIB
    if (_rsxnt_win32_version == WIN32S
	&& fd < 3 && p->file[fd].f_handle == BAD_FS_HANDLE)
	return win32s_read (fd, buf, nbyte);
#endif

    if (fd == 0 && (p->p_flags & PF_TERMIO))
	return _rsxnt_termio_read(p, buf, nbyte);

    if (p->file[fd].f_mode == HT_SOCKET)
    {
	if (!_rsxnt_socket_fop.read)
	    return _rsxnt_errno (EBADF);
	else
	return (*_rsxnt_socket_fop.read) ((int) p->file[fd].f_handle, buf, nbyte);
    }

    if (ReadFile (p->file[fd].f_handle, buf, nbyte, &n, NULL) == FALSE)
    {
        /*
           ReadFile error, recognize two special cases:

           1) ERROR_BROKEN_FILE should return 0 (pipe writers closed)
           2) convert EACCESS to EBADF (wrong read/write mode)
        */
        DWORD dwError = GetLastError();

        if (dwError == ERROR_BROKEN_PIPE)
            return 0;

        else if (dwError == ERROR_ACCESS_DENIED)
            SetLastError(ERROR_INVALID_HANDLE);

        return _rsxnt_get_last_errno();
    }
    else
	return (n);
}
