// unistd.h -- POSIX process, credential, job-control + timing glue for the
// GNO/ME runtime.  These wrap the GNO kernel toolset $03 primitives (see
// gno/kernel.h) into POSIX names; the bodies live in runtime/src/libcGno.c.
// File/stat decls live in <fcntl.h> / <sys/stat.h>.
#ifndef _UNISTD_H
#define _UNISTD_H

#include <stddef.h>
#include <sys/types.h>     // single source of truth for pid_t/uid_t/gid_t/off_t

#ifdef __cplusplus
extern "C" {
#endif

// usleep granularity argument.  32-bit so callers can request more than the
// 65 ms an int would cap at, even though the kernel floors us at 0.1 s.
typedef unsigned long useconds_t;

// Standard stream fd numbers (POSIX Unix values; gnoFd remaps to GNO 1/2/3).
#define STDIN_FILENO   0
#define STDOUT_FILENO  1
#define STDERR_FILENO  2

// ---- process control (runtime/src/libcGno.c) ----
int   fork(void *subr);         // GNO thread-spawn (subr = (void *)&leafFn)
int   getpid(void);
int   getppid(void);
int   dup(int oldfd);
int   dup2(int oldfd, int newfd);
int   pipe(int fds[2]);
int   isatty(int fd);           // terminal test via fstat + S_ISCHR

// ---- credentials (runtime/src/libcGno.c) ----
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
int   setuid(uid_t uid);
int   setgid(gid_t gid);

// ---- job control (runtime/src/libcGno.c) ----
pid_t getpgrp(void);
int   setpgid(pid_t pid, pid_t pgrp);
int   setpgrp(pid_t pid, pid_t pgrp);   // BSD alias of setpgid (same 0x3403 entry)
int   tcsetpgrp(int fd, pid_t pgrp);
pid_t tcgetpgrp(int fd);                // stub: ENOSYS (kernel routes TIOCGPGRP to `invalid`)
pid_t setsid(void);                     // stub: ENOSYS (no GNO session primitive)

// ---- raw I/O + file (bodies in libcGno.c) ----
long  read(int fd, void *buf, unsigned long n);
long  write(int fd, const void *buf, unsigned long n);
int   close(int fd);
off_t lseek(int fd, off_t offset, int whence);
int   unlink(const char *path);

// ---- file access test (runtime/src/libcGno.c) ----
// Only F_OK (existence) is honored under GNO; R/W/X_OK degrade to an existence
// test (GNO stat reports no meaningful owner/perm bits).
#define F_OK  0     // test for existence of the file
#define X_OK  0x01  // test for execute/search permission
#define W_OK  0x02  // test for write permission
#define R_OK  0x04  // test for read permission
int   access(const char *path, int mode);

// ---- exec family (runtime/src/libcGno.c) ----
// GNO's kernel exec takes ONE flattened command line (not argv/envp): these
// space-join argv, stripping argv[0]'s GS/OS prefix, and IGNORE envp.  On
// success they replace the process image and do not return; on failure they
// return -1 with errno set.  execvp/execlp resolve a bare name through $PATH.
int   execv (const char *path, char *const *argv);
int   execve(const char *path, char *const *argv, char *const *envp);
int   execvp(const char *file, char *const *argv);
int   execl (const char *path, const char *arg, ...);
int   execle(const char *path, const char *arg, ...);
int   execlp(const char *file, const char *arg, ...);

// ---- timing ----
unsigned long alarm(unsigned long seconds);
unsigned int  sleep(unsigned int seconds);
int           usleep(useconds_t useconds);
int           pause(void);

#ifdef __cplusplus
}
#endif

#endif
