SchOS/cmd/shmtest/main.c
Nexoniarz e04ca28812 Rename Schunix to SchOS; the kernel becomes SchIFT
Removes the "-unix" element and with it any trademark exposure to The
Open Group.

The split follows the ecosystem layout: SchOS is the system, and the
kernel has its own name. Kernel-identity strings are the only places
that take SchIFT -- uname(2) sysname, /proc/version, and the two licence
sentences that say "kernel" outright. That is what every Unix does here:
`uname -s` on Linux reports the kernel, not the distribution. Everything
a user reads as the product -- panic screen, boot menu, error prefixes,
docs, LICENSE, NOTICE -- is SchOS.

schunix.img is schos.img, the logo assets and the musl TLS patch are
renamed, and __SCHUNIX__ is __SCHOS__ (the define and the patch that
consumes it moved together).

Two things the rename broke, both found by the bootcheck suite:

  - shmtest wrote "SCHUNIX-MMAP-OK" with a hardcoded length of 15 and
    compared it back by hand-counted offsets (m[3]=='U', m[14]=='K').
    The shorter marker left the write running two bytes past the literal
    and the compare reading past the data, failing a file-backed mmap
    that was working correctly. Now written and compared through one
    constant with sizeof.
  - bootcheck asserted a 31-byte file after appending to
    "hello-from-schunix"; the shorter string makes it 29.

Both are the same mistake: a string literal whose length is written out
somewhere else. Full suite green -- base, Tty, Ps, Sock, Fb, Usb, Evdev.
2026-08-09 14:09:59 +02:00

122 lines
3.9 KiB
C

// shmtest -- prove that shared memory is actually shared, and that a
// file-backed mmap returns the file.
//
// Both of these are things you cannot check by reading a return value. shmget
// and shmat returned -ENOSYS until now, and mmap of a file "succeeded" while
// handing back zeroed anonymous pages -- a lie that looks exactly like
// success. The only convincing test is for one process to write and a
// different one to read.
//
// shmtest run every check
//
// Prints one line per check, and a final verdict a script can grep for.
#include "types.h"
#include "user.h"
#include "fcntl.h"
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MAP_PRIVATE 0x02
#define MAP_SHARED 0x01
#define IPC_PRIVATE 0
#define IPC_CREAT 01000
static int failures;
static void
puts_(const char *s)
{
int n = 0;
while (s[n]) n++;
write(1, (void*)s, n);
}
static void
check(int ok, const char *what)
{
puts_(ok ? " [ok] " : " FAIL: ");
puts_(what);
puts_("\n");
if (!ok) failures++;
}
int
main(void)
{
// --- shared memory ----------------------------------------------------
int id = shmget(IPC_PRIVATE, 8192, IPC_CREAT | 0600);
check(id >= 0, "shmget created a segment");
if (id < 0) { puts_("shmtest: FAILED\n"); return 1; }
char *p = shmat(id, 0, 0);
check((long)p > 0, "shmat mapped it");
if ((long)p <= 0) { puts_("shmtest: FAILED\n"); return 1; }
// A fresh segment must be zeroed, or it leaks whatever the previous
// tenant left in those pages to whoever gets them next.
int zeroed = 1;
for (int i = 0; i < 8192; i++)
if (p[i] != 0) { zeroed = 0; break; }
check(zeroed, "a new segment reads as zeros");
p[0] = 'P';
p[1] = 0;
int pid = fork();
if (pid == 0) {
// The child inherited the attachment through fork. If the pages had
// been copied instead of shared, the parent would never see this.
p[0] = 'C';
p[100] = 'X';
exit();
}
wait();
check(p[0] == 'C', "a write by the child is visible in the parent");
check(p[100] == 'X', "and so is one further into the segment");
// --- file-backed mmap --------------------------------------------------
// Written and compared through one constant, and never by hand-counted
// offsets. Those offsets used to spell out SCHUNIX-MMAP-OK a character at a
// time -- m[3]=='U' and m[14]=='K' -- with the length 15 written out
// separately. Renaming the marker to SCHOS shortened it to 13 and left both
// behind: the write ran two bytes off the end of the literal and the
// compare read past the data, which failed a file-backed mmap that was
// working correctly.
static const char MARK[] = "SCHOS-MMAP-OK";
const int MARKLEN = (int)(sizeof(MARK) - 1);
int fd = open("/tmp/shmtest.dat", O_CREATE | O_RDWR);
check(fd >= 0, "created a file to map");
if (fd >= 0) {
write(fd, MARK, MARKLEN);
close(fd);
}
fd = open("/tmp/shmtest.dat", O_RDONLY);
if (fd >= 0) {
char *m = mmap(0, 4096, PROT_READ, MAP_PRIVATE, fd, 0);
int ok = ((long)m > 0);
for (int i = 0; ok && i < MARKLEN; i++)
ok = (m[i] == MARK[i]);
check(ok, "mmap of a file returns the file, not zeros");
close(fd);
} else {
check(0, "mmap of a file returns the file, not zeros");
}
// MAP_SHARED + PROT_WRITE on a file cannot be honoured without a page
// cache, and is refused rather than quietly downgraded to a private copy.
fd = open("/tmp/shmtest.dat", O_RDWR);
if (fd >= 0) {
void *m = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
check((long)m < 0, "writable MAP_SHARED on a file is refused, not faked");
close(fd);
}
check(shmdt(p) == 0, "shmdt released the attachment");
puts_(failures ? "shmtest: FAILED\n" : "shmtest: all checks passed\n");
return failures ? 1 : 0;
}