#include #include #include #include #include #include /* * Exercises the new open() state machine + ESTEX env API. * * Touches the floppy: creates TMP1.TXT and TMP2.TXT, writes a few bytes, * verifies O_CREAT / O_EXCL / O_TRUNC / O_APPEND behaviour, then deletes. */ static void show_errno(const char *label) { printf(" %s: errno=%d \"%s\"\n", label, errno, strerror(errno)); } int main(void) { puts("Sprinter open() + env API test"); puts(""); /* --- open() state machine ------------------------------------- */ /* 1. O_CREAT|O_EXCL: must succeed first time, must fail on retry. */ unlink("TMP1.TXT"); /* clean slate */ errno = 0; int fd = open("TMP1.TXT", O_WRONLY | O_CREAT | O_EXCL); printf("create-new TMP1.TXT (1st): fd=%d\n", fd); show_errno(" after 1st"); if (fd >= 0) { write(fd, "abcdef", 6); close(fd); } errno = 0; fd = open("TMP1.TXT", O_WRONLY | O_CREAT | O_EXCL); printf("create-new TMP1.TXT (2nd, should fail with EEXIST): fd=%d\n", fd); show_errno(" after 2nd"); /* 2. O_CREAT|O_TRUNC: file is reset. */ errno = 0; fd = open("TMP1.TXT", O_WRONLY | O_CREAT | O_TRUNC); printf("create-trunc TMP1.TXT: fd=%d\n", fd); if (fd >= 0) { write(fd, "XYZ", 3); close(fd); } /* Read back to confirm truncation overwrote "abcdef". */ char buf[16]; fd = open("TMP1.TXT", O_RDONLY); int n = read(fd, buf, sizeof(buf) - 1); if (n < 0) n = 0; buf[n] = 0; close(fd); printf("contents after trunc+write: \"%s\" (expect \"XYZ\")\n", buf); /* 3. O_APPEND: writes go to end. */ fd = open("TMP1.TXT", O_WRONLY | O_APPEND); if (fd >= 0) { write(fd, "+APP", 4); close(fd); } fd = open("TMP1.TXT", O_RDONLY); n = read(fd, buf, sizeof(buf) - 1); if (n < 0) n = 0; buf[n] = 0; close(fd); printf("contents after append: \"%s\" (expect \"XYZ+APP\")\n", buf); /* 4. O_CREAT alone (no EXCL/TRUNC): existing file opens, new file is * created. We open TMP1 (must succeed without truncating) then * TMP2 (must be created fresh). */ fd = open("TMP1.TXT", O_RDONLY | O_CREAT); n = read(fd, buf, sizeof(buf) - 1); if (n < 0) n = 0; buf[n] = 0; close(fd); printf("O_CREAT on existing TMP1: \"%s\" (expect \"XYZ+APP\")\n", buf); unlink("TMP2.TXT"); fd = open("TMP2.TXT", O_WRONLY | O_CREAT); printf("O_CREAT on missing TMP2: fd=%d\n", fd); if (fd >= 0) { write(fd, "fresh", 5); close(fd); } /* cleanup */ unlink("TMP1.TXT"); unlink("TMP2.TXT"); /* --- env API -------------------------------------------------- */ puts(""); puts("env API:"); errno = 0; char *v = getenv("PATH"); printf(" getenv(\"PATH\") = %p", v); if (v) { printf(" -> \"%s\"", v); } else { printf(" (NULL, errno=%d)", errno); } putchar('\n'); errno = 0; int rc = putenv("SPRINTER_HELLO=world"); printf(" putenv(\"SPRINTER_HELLO=world\"): rc=%d\n", rc); if (rc != 0) show_errno(" after putenv"); errno = 0; v = getenv("SPRINTER_HELLO"); printf(" getenv(\"SPRINTER_HELLO\") = %p", v); if (v) { printf(" -> \"%s\"", v); } else { printf(" (NULL, errno=%d)", errno); } putchar('\n'); /* --- sysenv: dump the whole environment block ----------------- */ puts(""); puts("sysenv:"); { static char envbuf[512]; errno = 0; char *r = sysenv(envbuf); if (r == (char *)-1) { show_errno(" sysenv failed"); } else { printf(" sysenv(%p) returned %p\n", envbuf, r); int n = 0; for (char *p = r; *p; p += strlen(p) + 1) { printf(" [%d] %s\n", n++, p); } printf(" total: %d variable(s)\n", n); } } puts(""); puts("Press any key to exit."); (void)getchar(); return 0; }