diff options
| author | user <user@clank> | 2026-09-24 12:48:37 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-24 12:48:37 +0200 |
| commit | dc9dffb9069e32a1a0cf14883176544b234fc3e5 (patch) | |
| tree | 4877daa5f01e98ac5d7e64d98c4144c94fa94a91 /usr/stat.h | |
| parent | term: write the palette attribute for every re-rendered tile, not just the cu... (diff) | |
| download | gbos-dc9dffb9069e32a1a0cf14883176544b234fc3e5.tar.gz gbos-dc9dffb9069e32a1a0cf14883176544b234fc3e5.tar.xz gbos-dc9dffb9069e32a1a0cf14883176544b234fc3e5.zip | |
kernel: stat/fsstat/isatty syscalls, and O_APPEND
Four things userland had no way to ask for:
- SYS_STAT: type, link count, size and inode for a path. The trap needs HL
for its dispatch table, so a call taking both a path and an output buffer
passes a request block - the shape SYS_NET already established. usr/stat.h
wraps it, header-only like sock.h, because the block must live in the
caller's RAM.
- SYS_FSSTAT: blocks/inodes, total and free. The bitmaps are already cached
write-through in fs_bmbuf, so this is the popcount boot_fs already prints.
- SYS_ISATTY: is this process's stdin the console? The shell needs it to tell
an interactive session from a script.
- O_APPEND: open a file positioned at EOF. There is no seek syscall, so this
is the only way to add to a file - without it nothing running ON the Game
Boy can build a multi-line file, shell scripts included.
Together these back ls -l, df, and `>>`.
Diffstat (limited to '')
| -rw-r--r-- | usr/stat.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/usr/stat.h b/usr/stat.h new file mode 100644 index 0000000..10acc54 --- /dev/null +++ b/usr/stat.h @@ -0,0 +1,36 @@ +#ifndef STAT_H +#define STAT_H +/* stat.h - file metadata and filesystem totals. Header-only (one copy per + program), like sock.h: the request block has to live in the caller's RAM. + The kernel trap needs HL for its dispatch table, so a call with both a path + and an output buffer passes a request block rather than two pointers. */ +#include "gbos.h" + +#define ST_FILE 1 +#define ST_DIR 2 + +struct gstat { + unsigned char type; /* ST_FILE / ST_DIR */ + unsigned char nlink; + unsigned int size; /* bytes */ + unsigned char ino; +}; + +static unsigned char _sreq[7]; /* path ptr, then type/nlink/size/ino */ + +/* -> 1 on success, 0 if the path does not exist */ +static unsigned char gstat(const char *path, struct gstat *st) { + _sreq[0] = (unsigned char)(unsigned int)path; + _sreq[1] = (unsigned char)(((unsigned int)path) >> 8); + if (sys_stat(_sreq) != 0) return 0; + st->type = _sreq[2]; + st->nlink = _sreq[3]; + st->size = (unsigned int)_sreq[4] | ((unsigned int)_sreq[5] << 8); + st->ino = _sreq[6]; + return 1; +} + +/* out[] = { blocks total, blocks free, inodes total, inodes free } */ +static void gfsstat(unsigned char *out) { sys_fsstat(out); } + +#endif |
