// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses these ABI declarations to you under the MIT license.
// Extracted from dotnet/runtime v10.0.12, commit 4271d88e0aebf3d04f188f1334c2220d80555ef6.
// XFESystem derives this header to omit host POSIX headers and inline host calls.
// Unmodified references and license: ../ThirdParty/DotNetSystemNative/.
#pragma once
#include <stdint.h>
#include <stddef.h>
struct __dirstream;
typedef struct __dirstream DIR;
typedef void (*TerminalInvalidationCallback)(void);
typedef enum
{
    Error_SUCCESS = 0,

    Error_E2BIG = 0x10001,           // Argument list too long.
    Error_EACCES = 0x10002,          // Permission denied.
    Error_EADDRINUSE = 0x10003,      // Address in use.
    Error_EADDRNOTAVAIL = 0x10004,   // Address not available.
    Error_EAFNOSUPPORT = 0x10005,    // Address family not supported.
    Error_EAGAIN = 0x10006,          // Resource unavailable, try again (same value as EWOULDBLOCK),
    Error_EALREADY = 0x10007,        // Connection already in progress.
    Error_EBADF = 0x10008,           // Bad file descriptor.
    Error_EBADMSG = 0x10009,         // Bad message.
    Error_EBUSY = 0x1000A,           // Device or resource busy.
    Error_ECANCELED = 0x1000B,       // Operation canceled.
    Error_ECHILD = 0x1000C,          // No child processes.
    Error_ECONNABORTED = 0x1000D,    // Connection aborted.
    Error_ECONNREFUSED = 0x1000E,    // Connection refused.
    Error_ECONNRESET = 0x1000F,      // Connection reset.
    Error_EDEADLK = 0x10010,         // Resource deadlock would occur.
    Error_EDESTADDRREQ = 0x10011,    // Destination address required.
    Error_EDOM = 0x10012,            // Mathematics argument out of domain of function.
    Error_EDQUOT = 0x10013,          // Reserved.
    Error_EEXIST = 0x10014,          // File exists.
    Error_EFAULT = 0x10015,          // Bad address.
    Error_EFBIG = 0x10016,           // File too large.
    Error_EHOSTUNREACH = 0x10017,    // Host is unreachable.
    Error_EIDRM = 0x10018,           // Identifier removed.
    Error_EILSEQ = 0x10019,          // Illegal byte sequence.
    Error_EINPROGRESS = 0x1001A,     // Operation in progress.
    Error_EINTR = 0x1001B,           // Interrupted function.
    Error_EINVAL = 0x1001C,          // Invalid argument.
    Error_EIO = 0x1001D,             // I/O error.
    Error_EISCONN = 0x1001E,         // Socket is connected.
    Error_EISDIR = 0x1001F,          // Is a directory.
    Error_ELOOP = 0x10020,           // Too many levels of symbolic links.
    Error_EMFILE = 0x10021,          // File descriptor value too large.
    Error_EMLINK = 0x10022,          // Too many links.
    Error_EMSGSIZE = 0x10023,        // Message too large.
    Error_EMULTIHOP = 0x10024,       // Reserved.
    Error_ENAMETOOLONG = 0x10025,    // Filename too long.
    Error_ENETDOWN = 0x10026,        // Network is down.
    Error_ENETRESET = 0x10027,       // Connection aborted by network.
    Error_ENETUNREACH = 0x10028,     // Network unreachable.
    Error_ENFILE = 0x10029,          // Too many files open in system.
    Error_ENOBUFS = 0x1002A,         // No buffer space available.
    Error_ENODEV = 0x1002C,          // No such device.
    Error_ENOENT = 0x1002D,          // No such file or directory.
    Error_ENOEXEC = 0x1002E,         // Executable file format error.
    Error_ENOLCK = 0x1002F,          // No locks available.
    Error_ENOLINK = 0x10030,         // Reserved.
    Error_ENOMEM = 0x10031,          // Not enough space.
    Error_ENOMSG = 0x10032,          // No message of the desired type.
    Error_ENOPROTOOPT = 0x10033,     // Protocol not available.
    Error_ENOSPC = 0x10034,          // No space left on device.
    Error_ENOSYS = 0x10037,          // Function not supported.
    Error_ENOTCONN = 0x10038,        // The socket is not connected.
    Error_ENOTDIR = 0x10039,         // Not a directory or a symbolic link to a directory.
    Error_ENOTEMPTY = 0x1003A,       // Directory not empty.
    Error_ENOTRECOVERABLE = 0x1003B, // State not recoverable.
    Error_ENOTSOCK = 0x1003C,        // Not a socket.
    Error_ENOTSUP = 0x1003D,         // Not supported (same value as EOPNOTSUP).
    Error_ENOTTY = 0x1003E,          // Inappropriate I/O control operation.
    Error_ENXIO = 0x1003F,           // No such device or address.
    Error_EOVERFLOW = 0x10040,       // Value too large to be stored in data type.
    Error_EOWNERDEAD = 0x10041,      // Previous owner died.
    Error_EPERM = 0x10042,           // Operation not permitted.
    Error_EPIPE = 0x10043,           // Broken pipe.
    Error_EPROTO = 0x10044,          // Protocol error.
    Error_EPROTONOSUPPORT = 0x10045, // Protocol not supported.
    Error_EPROTOTYPE = 0x10046,      // Protocol wrong type for socket.
    Error_ERANGE = 0x10047,          // Result too large.
    Error_EROFS = 0x10048,           // Read-only file system.
    Error_ESPIPE = 0x10049,          // Invalid seek.
    Error_ESRCH = 0x1004A,           // No such process.
    Error_ESTALE = 0x1004B,          // Reserved.
    Error_ETIMEDOUT = 0x1004D,       // Connection timed out.
    Error_ETXTBSY = 0x1004E,         // Text file busy.
    Error_EXDEV = 0x1004F,           // Cross-device link.
    Error_ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported.
    Error_EPFNOSUPPORT = 0x10060,    // Protocol family not supported.
    Error_ESHUTDOWN = 0x1006C,       // Socket shutdown.
    Error_EHOSTDOWN = 0x10070,       // Host is down.
    Error_ENODATA = 0x10071,         // No data available.

    // Error codes to track errors beyond kernel.
    Error_EHOSTNOTFOUND = 0x20001,   // Name lookup failed.
    Error_ESOCKETERROR = 0x20002,    // Unidentified socket error.

    // POSIX permits these to have the same value and we make them
    // always equal so that we cannot introduce a dependency on
    // distinguishing between them that would not work on all
    // platforms.
    Error_EOPNOTSUPP = Error_ENOTSUP, // Operation not supported on socket
    Error_EWOULDBLOCK = Error_EAGAIN, // Operation would block

    // This one is not part of POSIX, but is a catch-all for the case
    // where we cannot convert the raw errno value to something above.
    Error_ENONSTANDARD = 0x1FFFF,
} Error;

typedef struct
{
    int32_t Flags;     // flags for testing if some members are present (see FileStatusFlags)
    int32_t Mode;      // file mode (see S_I* constants above for bit values)
    uint32_t Uid;      // user ID of owner
    uint32_t Gid;      // group ID of owner
    int64_t Size;      // total size, in bytes
    int64_t ATime;     // time of last access
    int64_t ATimeNsec; //     nanosecond part
    int64_t MTime;     // time of last modification
    int64_t MTimeNsec; //     nanosecond part
    int64_t CTime;     // time of last status change
    int64_t CTimeNsec; //     nanosecond part
    int64_t BirthTime; // time the file was created
    int64_t BirthTimeNsec; // nanosecond part
    int64_t Dev;       // ID of the device containing the file
    int64_t RDev;      // ID of the device if it is a special file
    int64_t Ino;       // inode number of the file
    uint32_t UserFlags; // user defined flags
} FileStatus;

typedef struct
{
    uint8_t* Base;
    uintptr_t Count;
} IOVector;

typedef struct
{
    const char* Name;   // Address of the name of the inode
    int32_t NameLength; // Length (in chars) of the inode name
    int32_t InodeType; // The inode type as described in the NodeType enum
} DirectoryEntry;

typedef struct
{
    int32_t FileDescriptor;  // The file descriptor to poll
    int16_t Events;          // The events to poll for
    int16_t TriggeredEvents; // The events that triggered the poll
} PollEvent;

typedef struct
{
    uint16_t Row;
    uint16_t Col;
    uint16_t XPixel;
    uint16_t YPixel;
} WinSize;

typedef struct ProcessCpuInformation
{
    uint64_t lastRecordedCurrentTime;
    uint64_t lastRecordedKernelTime;
    uint64_t lastRecordedUserTime;
} ProcessCpuInformation;

typedef struct
{
    char* Name;
    char* Password;
    uint32_t UserId;
    uint32_t GroupId;
    char* UserInfo;
    char* HomeDirectory;
    char* Shell;
} Passwd;


#ifdef __cplusplus
extern "C" {
#endif
int32_t SystemNative_CanGetHiddenFlag(void);
int32_t SystemNative_Close(intptr_t fd);
int32_t SystemNative_CloseDir(DIR* dir);
int32_t SystemNative_ConvertErrorPalToPlatform(int32_t error);
int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno);
intptr_t SystemNative_Dup(intptr_t oldfd);
int32_t SystemNative_FAllocate(intptr_t fd, int64_t offset, int64_t length);
int32_t SystemNative_FLock(intptr_t fd, int32_t operation);
void SystemNative_FreeLibrary(void* handle);
int32_t SystemNative_FStat(intptr_t fd, FileStatus* output);
int32_t SystemNative_FSync(intptr_t fd);
int32_t SystemNative_FTruncate(intptr_t fd, int64_t length);
void SystemNative_GetControlCharacters(
    int32_t* controlCharacterNames, uint8_t* controlCharacterValues, int32_t controlCharacterLength,
    uint8_t* posixDisableValue);
double SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo);
char* SystemNative_GetCwd(char* buffer, int32_t bufferSize);
uint32_t SystemNative_GetEGid(void);
uint32_t SystemNative_GetEUid(void);
uint32_t SystemNative_GetFileSystemType(intptr_t fd);
int32_t SystemNative_GetGroups(int32_t ngroups, uint32_t* groups);
void* SystemNative_GetLoadLibraryError(void);
void* SystemNative_GetProcAddress(void* handle, const char* symbol);
char* SystemNative_GetProcessPath(void);
int32_t SystemNative_GetPwUidR(uint32_t uid, Passwd* pwd, char* buf, int32_t buflen);
int64_t SystemNative_GetSystemTimeAsTicks(void);
int32_t SystemNative_GetWindowSize(intptr_t fd, WinSize* windowsSize);
void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t decisecondsTimeout);
int32_t SystemNative_InitializeTerminalAndSignalHandling(void);
uint32_t SystemNative_InterfaceNameToIndex(char* interfaceName);
int32_t SystemNative_IsATty(intptr_t fd);
int32_t SystemNative_LChflagsCanSetHiddenFlag(void);
void* SystemNative_LoadLibrary(const char* filename);
int64_t SystemNative_LSeek(intptr_t fd, int64_t offset, int32_t whence);
int32_t SystemNative_LStat(const char* path, FileStatus* output);
intptr_t SystemNative_Open(const char* path, int32_t flags, int32_t mode);
DIR* SystemNative_OpenDir(const char* path);
int32_t SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered);
int32_t SystemNative_PosixFAdvise(intptr_t fd, int64_t offset, int64_t length, int32_t advice);
int32_t SystemNative_PRead(intptr_t fd, void* buffer, int32_t bufferSize, int64_t fileOffset);
int64_t SystemNative_PReadV(intptr_t fd, IOVector* vectors, int32_t vectorCount, int64_t fileOffset);
int32_t SystemNative_PWrite(intptr_t fd, void* buffer, int32_t bufferSize, int64_t fileOffset);
int64_t SystemNative_PWriteV(intptr_t fd, IOVector* vectors, int32_t vectorCount, int64_t fileOffset);
int32_t SystemNative_Read(intptr_t fd, void* buffer, int32_t bufferSize);
int32_t SystemNative_ReadDir(DIR* dir, DirectoryEntry* outputEntry);
int32_t SystemNative_ReadLink(const char* path, char* buffer, int32_t bufferSize);
int32_t SystemNative_ReadStdin(void* buffer, int32_t bufferSize);
void SystemNative_SetKeypadXmit(intptr_t fd, const char* terminfoString);
void SystemNative_SetTerminalInvalidationHandler(TerminalInvalidationCallback callback);
int32_t SystemNative_Stat(const char* path, FileStatus* output);
const char* SystemNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize);
void SystemNative_UninitializeConsoleAfterRead(void);
void SystemNative_UninitializeTerminal(void);
int32_t SystemNative_Unlink(const char* path);
int32_t SystemNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize);
int32_t SystemNative_SNPrintF_1S(char* buffer, int32_t bufferSize, const char* format, const char* arg);
int32_t SystemNative_SNPrintF_1I(char* buffer, int32_t bufferSize, const char* format, int32_t arg);
#ifdef __cplusplus
}
#endif
