/* unistd.h: POSIX constants and functions. */

#ifndef _UNISTD_H
#define _UNISTD_H

#define __need_NULL
#include <stddef.h>

#include <bits/access.h>
#include <bits/attrs.h>
#include <bits/seek.h>
#include <stdint.h>
#include <sys/types.h>

#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2

#define _POSIX_CHOWN_RESTRICTED 200112L
#define _POSIX_SHELL 200112L
#define _POSIX_MAPPED_FILES 200112L
#define _POSIX_SYNCHRONIZED_IO 200112L
#define _POSIX_SAVED_IDS 200112L
#define _POSIX_VDISABLE (-2)

#ifdef __cplusplus
extern "C"
{
#endif

    /* Create a new process that is a clone of the current one. */
    pid_t fork(void);

    /* Return the current process' process ID. */
    pid_t getpid(void);

    /* Return the current process' parent process ID. */
    pid_t getppid(void);

    /* Return the current process' real user ID. */
    uid_t getuid(void);

    /* Return the current process' effective user ID. */
    uid_t geteuid(void);

    /* Return the current process' real group ID. */
    gid_t getgid(void);

    /* Return the current process' effective group ID. */
    gid_t getegid(void);

    /* Return a process' process group ID. */
    pid_t getpgid(pid_t pid);

    /* Set the current process' user IDs. */
    int setuid(uid_t uid);

    /* Set the current process' effective user ID. */
    int seteuid(uid_t uid);

    /* Set the current process' group IDs. */
    int setgid(gid_t gid);

    /* Set the current process' effective group ID. */
    int setegid(gid_t gid);

    /* Set the current process or a child process's process group. */
    int setpgid(pid_t pid, pid_t pgid);

    /* Change the owner and group of a file. */
    int chown(const char* path, uid_t uid, gid_t gid);

    /* Change the owner and group of a file descriptor. */
    int fchown(int fd, uid_t uid, gid_t gid);

    /* Replace the current process with another one. On success, does not return. */
    int execv(const char* path, char* const* argv);

    /* Replace the current process with another one. On success, does not return. */
    int execl(const char* path, const char* arg, ...);

    /* Replace the current process with another one. On success, does not return. */
    int execlp(const char* path, const char* arg, ...);

    /* Replace the current process with another one. On success, does not return. */
    int execle(const char* path, const char* arg, ...);

    /* Replace the current process with another one. On success, does not return. */
    int execve(const char* path, char* const* argv, char* const* envp);

    /* Replace the current process with another one. On success, does not return. */
    int execvp(const char* name, char* const* argv);

    /* Replace the current process with another one. On success, does not return. */
    int execvpe(const char* name, char* const* argv, char* const* envp);

    /* Call the operating system kernel for a specific service. */
    long syscall(long num, ...);

    /* Exit the process immediately, without performing any cleanup actions. */
    __noreturn void _exit(int status);

    /* Sleep for X microseconds. */
    int usleep(useconds_t us);

    /* Sleep for X seconds. */
    unsigned long sleep(unsigned long seconds);

    /* Close a file descriptor. */
    int close(int fd);

    /* Read bytes from a file descriptor. */
    ssize_t read(int fd, void* buf, size_t size);

    /* Write bytes to a file descriptor. */
    ssize_t write(int fd, const void* buf, size_t size);

    /* Modify a file descriptor's offset. */
    off_t lseek(int fd, off_t offset, int whence);

    /* Duplicate a file descriptor. */
    int dup(int fd);

    /* Replace a file descriptor with a copy of another one. */
    int dup2(int oldfd, int newfd);

    /* Change the current working directory. */
    int chdir(const char* path);

    /* Retrieve the current working directory. */
    char* getcwd(char* buf, size_t size);

    /* Remove a name from the filesystem. */
    int unlink(const char* path);

    /* Remove a name or directory from the filesystem. */
    int unlinkat(int dirfd, const char* path, int flags);

    /* Remove a directory from the filesystem. */
    int rmdir(const char* path);

    /* Get the current network hostname. */
    int gethostname(char* buf, size_t len);

    /* Set the current network hostname. */
    int sethostname(const char* buf, size_t len);

    /* Create a pipe for inter-process communication. */
    int pipe(int pfds[2]);

    /* Create a symbolic link. */
    int symlink(const char* target, const char* linkpath);

    /* Create a symbolic link relative to a file descriptor. */
    int symlinkat(const char* target, int dirfd, const char* linkpath);

    /* Read the contents of a symbolic link. */
    ssize_t readlink(const char* path, char* buf, size_t max);

    /* Read the contents of a symbolic link relative to a file descriptor. */
    ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t max);

    /* Create a hard link. */
    int link(const char* oldpath, const char* newpath);

    /* Create a hard link relative to a file descriptor. */
    int linkat(int olddirfd, const char* oldpath, int newdirfd, const char* newpath, int flags);

    /* Check for a file's accessibility. */
    int access(const char* path, int amode);

    /* Check for a file's accessibility using the effective user and group IDs. */
    int eaccess(const char* path, int amode);

    /* Check for a file's accessibility relative to a file descriptor. */
    int faccessat(int dirfd, const char* path, int amode, int flags);

    /* Check whether a file descriptor refers to a terminal device. */
    int isatty(int fd);

    /* Fetch the process group associated with a terminal file descriptor. */
    pid_t tcgetpgrp(int fd);

    /* Set the process group associated with a terminal file descriptor. */
    int tcsetpgrp(int fd, pid_t pgrp);

    /* Truncate a file to a specific length. */
    int truncate(const char* path, size_t size);

    /* Truncate a file to a specific length. */
    int ftruncate(int fd, size_t size);

    /* Return the system page size. */
    int getpagesize(void);

    /* Schedule an alarm signal. */
    unsigned int alarm(unsigned int seconds);

    /* Restrict system operations. */
    int pledge(const char* promises, const char* execpromises);

#ifdef __cplusplus
}
#endif

#endif