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

#include "rsxnt.h"
#include <string.h>

int __fstat(int fd, struct stat *statbuf)
{
    EMXPROCESS *p = _rsxnt_get_process_ptr();
    DWORD type;

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

    memset(statbuf, 0, sizeof (struct stat));

    if (p->file[fd].f_mode == HT_SOCKET) {
        statbuf->st_mode = MAKEPERM (S_IREAD|S_IWRITE);
        statbuf->st_mode |= S_IFSOCK;
        statbuf->st_size = 0;
        statbuf->st_dev = 0;
        statbuf->st_uid = 0;
        statbuf->st_gid = 0;
        statbuf->st_ino = _rsxnt_stat_ino();
        statbuf->st_rdev = statbuf->st_dev;
        statbuf->st_nlink = 1;
        return 0;
    }

    type = GetFileType(p->file[fd].f_handle);

    if (type == FILE_TYPE_CHAR) {
        statbuf->st_ino = _rsxnt_stat_ino();
        statbuf->st_nlink = 1;
        statbuf->st_mode = S_IFCHR | MAKEPERM (S_IREAD|S_IWRITE);
    }
    else if (type == FILE_TYPE_PIPE) {
        statbuf->st_ino = _rsxnt_stat_ino();
        statbuf->st_nlink = 1;
        statbuf->st_mode = S_IFIFO | MAKEPERM (S_IREAD|S_IWRITE);
    }
    else {
        BY_HANDLE_FILE_INFORMATION bhfi;

        if (GetFileInformationByHandle(p->file[fd].f_handle, & bhfi) == FALSE)
            return _rsxnt_get_last_errno();

        /* cut other attrib */
        bhfi.dwFileAttributes &= 0x7f;
        statbuf->st_attr = bhfi.dwFileAttributes;

        /* convert times to gmt */
        _rsxnt_ft2stat(statbuf, &bhfi.ftCreationTime, &bhfi.ftLastAccessTime, &bhfi.ftLastWriteTime);

        /* set mode */
        if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
            statbuf->st_mode = S_IFREG |MAKEPERM (S_IREAD);
          else
            statbuf->st_mode = S_IFREG | MAKEPERM (S_IREAD|S_IWRITE);

        statbuf->st_size = bhfi.nFileSizeLow;
        statbuf->st_nlink = bhfi.nNumberOfLinks;
        statbuf->st_ino = bhfi.nFileIndexHigh + bhfi.nFileIndexLow;
    }
    return 0;
}
