100 lines
4.1 KiB
C
100 lines
4.1 KiB
C
// sys/stat.h -- file status for the GNO/ME runtime.
|
|
//
|
|
// struct stat MUST byte-match the layout the GNO kernel's stat.c writes
|
|
// (kern/gno/stat.c, compiled by ORCA/C with 16-bit int / 32-bit long).
|
|
// Kstat/Kfstat/Klstat (gno/kernel.h) fill this buffer directly, so any
|
|
// field-order or size drift silently corrupts every returned field. The
|
|
// _Static_assert below pins sizeof to the ORCA/C layout (54 bytes); the
|
|
// field offsets all land on even boundaries, so our 2-byte i32 alignment
|
|
// (datalayout i32:16) inserts no padding and matches ORCA/C's packing.
|
|
// (Verified: sizeof==54, offsetof(st_size)==16, st_mtime==26, st_blocks==42,
|
|
// matching the __GNO__ branch of tools/gno/src-repo/include/sys/stat.h.)
|
|
//
|
|
// Field semantics follow GNO's kernel: st_nlink/st_uid/st_gid/st_rdev are
|
|
// always 0, st_ino is a per-call fake, times are Unix epoch seconds, and
|
|
// st_mode carries the S_IF* type bits plus ProDOS-derived permission bits.
|
|
#ifndef _SYS_STAT_H_
|
|
#define _SYS_STAT_H_
|
|
|
|
#include <sys/types.h>
|
|
#include <time.h> // time_t (single source of truth)
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct stat {
|
|
dev_t st_dev; // device number
|
|
ino_t st_ino; // (faked) inode number
|
|
unsigned short st_mode; // file type + permission bits
|
|
short st_nlink; // link count (always 0 under GNO)
|
|
uid_t st_uid; // owner uid (always 0)
|
|
gid_t st_gid; // owner gid (always 0)
|
|
dev_t st_rdev; // device type (always 0)
|
|
off_t st_size; // file size in bytes
|
|
time_t st_atime; // last access time (== mod time)
|
|
int st_spare1;
|
|
time_t st_mtime; // last modification time
|
|
int st_spare2;
|
|
time_t st_ctime; // creation / status-change time
|
|
int st_spare3;
|
|
long st_blksize; // preferred I/O block size (512)
|
|
long st_blocks; // 512-byte blocks allocated
|
|
long st_spare4[2];
|
|
};
|
|
|
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
|
_Static_assert(sizeof(struct stat) == 54, "struct stat must byte-match the GNO kernel layout");
|
|
#endif
|
|
|
|
// File type mask + type values (ProDOS/GS-OS mapped by the kernel).
|
|
#define S_IFMT 0170000 // type-of-file mask
|
|
#define S_IFIFO 0010000 // named pipe (fifo)
|
|
#define S_IFCHR 0020000 // character special (TTY / device)
|
|
#define S_IFDIR 0040000 // directory
|
|
#define S_IFBLK 0060000 // block special
|
|
#define S_IFREG 0100000 // regular file
|
|
#define S_IFLNK 0120000 // symbolic link
|
|
#define S_IFSOCK 0140000 // socket (GNO reports pipes as this)
|
|
|
|
// Permission bits.
|
|
#define S_ISUID 0004000 // set-user-id on execution
|
|
#define S_ISGID 0002000 // set-group-id on execution
|
|
#define S_ISVTX 0001000 // sticky bit
|
|
|
|
#define S_IRWXU 0000700 // RWX mask for owner
|
|
#define S_IRUSR 0000400 // R for owner
|
|
#define S_IWUSR 0000200 // W for owner
|
|
#define S_IXUSR 0000100 // X for owner
|
|
#define S_IREAD S_IRUSR
|
|
#define S_IWRITE S_IWUSR
|
|
#define S_IEXEC S_IXUSR
|
|
|
|
#define S_IRWXG 0000070 // RWX mask for group
|
|
#define S_IRGRP 0000040 // R for group
|
|
#define S_IWGRP 0000020 // W for group
|
|
#define S_IXGRP 0000010 // X for group
|
|
|
|
#define S_IRWXO 0000007 // RWX mask for other
|
|
#define S_IROTH 0000004 // R for other
|
|
#define S_IWOTH 0000002 // W for other
|
|
#define S_IXOTH 0000001 // X for other
|
|
|
|
// File-type test macros.
|
|
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
|
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
|
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
|
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
|
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
|
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
|
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
|
|
|
int stat(const char *path, struct stat *sb);
|
|
int fstat(int fd, struct stat *sb);
|
|
int lstat(const char *path, struct stat *sb);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|