72 lines
2.2 KiB
C
72 lines
2.2 KiB
C
// stat/fstat/isatty regression for the GNO libc file-status surface.
|
|
//
|
|
// Exercises the three K* status primitives (Kstat/Kfstat 0x2703/0x2803)
|
|
// through their POSIX wrappers in libcGno.c, plus isatty() built on
|
|
// fstat. The hard part these wrappers get right is struct stat's
|
|
// byte-layout: the GNO kernel (kern/gno/stat.c, ORCA/C) writes the buffer
|
|
// directly, so if runtime/include/sys/stat.h drifts by even one field the
|
|
// S_IF* type bits land in the wrong word and every test below flips.
|
|
//
|
|
// The program is launched at the gsh prompt with stdout on the console
|
|
// TTY, so:
|
|
// - fstat(1) succeeds and st_mode is a character special (the TTY).
|
|
// - isatty(1) is therefore true.
|
|
// - stat(".") on the login cwd is a directory.
|
|
// All deterministic (no pids / addresses / times inspected).
|
|
//
|
|
// Bank-2 absolute uint16 markers (DBR-independent), per the gnoHeapProbe
|
|
// convention:
|
|
// 0x025000 C0DE reached end (no hang in any stat path)
|
|
// 0x025010 0001 fstat(1) returned 0
|
|
// 0x025012 0001 S_ISCHR(fstat st_mode) -- stdout is a char device
|
|
// 0x025014 0001 isatty(1) == 1
|
|
// 0x025016 0001 stat(".") returned 0
|
|
// 0x025018 0001 S_ISDIR(stat st_mode) -- cwd is a directory
|
|
#include <stdint.h>
|
|
#include <sys/stat.h>
|
|
|
|
extern int isatty(int fd);
|
|
|
|
#define M(a) (*(volatile uint16_t *)(a))
|
|
#define OK 0x0001
|
|
#define BAD 0xDEAD
|
|
|
|
|
|
int main(void) {
|
|
struct stat sb;
|
|
int rc;
|
|
|
|
M(0x025010UL) = BAD;
|
|
M(0x025012UL) = BAD;
|
|
M(0x025014UL) = BAD;
|
|
M(0x025016UL) = BAD;
|
|
M(0x025018UL) = BAD;
|
|
|
|
// fstat(1): stdout, which the harness leaves on the console TTY.
|
|
rc = fstat(1, &sb);
|
|
if (rc == 0) {
|
|
M(0x025010UL) = OK;
|
|
}
|
|
if (S_ISCHR(sb.st_mode)) {
|
|
M(0x025012UL) = OK;
|
|
}
|
|
|
|
// isatty(1): true because stdout is a character device.
|
|
if (isatty(1) == 1) {
|
|
M(0x025014UL) = OK;
|
|
}
|
|
|
|
// stat("."): the login cwd, which is a directory.
|
|
rc = stat(".", &sb);
|
|
if (rc == 0) {
|
|
M(0x025016UL) = OK;
|
|
}
|
|
if (S_ISDIR(sb.st_mode)) {
|
|
M(0x025018UL) = OK;
|
|
}
|
|
|
|
M(0x025000UL) = 0xC0DE; // reached end
|
|
for (volatile unsigned long j = 0; j < 600000UL; j++) {
|
|
}
|
|
return 0;
|
|
}
|