Files
Sprinter-SDCC/tests/filetest/filetest.c
T
snark13 057dd615ba libc: квирки DSS — возврат WRITE и лимит манипуляторов; тесты fdmax/fbench
- ESTEX WRITE ($14) на успехе возвращает DE=0, а НЕ счётчик записанного
  (вопреки докам; solid-c в своём fflush тоже отключил сравнение по
  счётчику) — write() теперь судит по CF/A: CF=0&A=0 → n,
  CF=0&A!=0 → ENOSPC/-1
- DSS выдаёт 8 манипуляторов (fd 2..9; fd 1 держит шелл под запущенный
  exe), а 9-й OPEN не возвращает 06h — ВЕШАЕТ систему; предохранитель
  _fd_guard: счётчик в open()/close(), отказ EMFILE без захода в DSS
- tests/fdmax — эмпирика лимита (8 хендлов, затем EMFILE=6);
  tests/fbench — бенчмарк буферизации (floor 512-байтными read,
  оценка небуферизованного по 1-байтным, fgetc/fgets/fputc)
- filetest расширен: raw-probe возврата write, сценарий r+
  (чтение-запись-чтение с инвалидацией буфера), ungetc, fprintf

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:09:29 +03:00

123 lines
4.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* filetest — exercise the buffered FILE * stream API (variant B+).
*
* Steps:
* 0. RAW probe: open/write/close — печатает ГОЛЫЙ возврат write()
* (диагностика: что реально возвращает ESTEX WRITE в DE).
* 1. fopen("FILE.TXT","w"), fputs+fputc lines, fclose (с errno).
* 2. fopen("FILE.TXT","r"), fgets each line, fclose.
* 3. fopen("r"), fread block, fseek, ftell, feof.
* 4. fputs to stdout/stderr (console pseudo-streams).
* 5. "r+" mix: fgetc×10 → fputc×10 → fseek(0) → контроль, что
* чтение видит записанное (инвалидация буфера); ungetc; fprintf.
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
int main(void)
{
const char *path = "FILE.TXT";
/* ----- 0. RAW write() return probe ----- */
{
int fd = open("WRT.TMP", O_WRONLY | O_CREAT | O_TRUNC);
if (fd >= 0) {
errno = 0;
int w = write(fd, "12345", 5);
printf(" raw write(5) -> %d, errno=%d\n", w, errno);
close(fd);
unlink("WRT.TMP");
} else {
printf(" raw probe: open failed errno=%d\n", errno);
}
}
/* ----- 1. Write via fputs + fputc ----- */
{
FILE *fp = fopen(path, "w");
if (!fp) {
printf("fopen(w) failed: errno=%d (%s)\n", errno, strerror(errno));
return 1;
}
int r1 = fputs("Hello from FILE*\n", fp);
int r2 = fputs("Second line via fputs\n", fp);
if (r1 || r2) printf(" fputs ret: %d %d\n", r1, r2);
for (int i = '0'; i <= '9'; i++) fputc(i, fp);
fputc('\n', fp);
errno = 0;
if (fclose(fp) != 0)
printf("fclose: error, errno=%d (%s)\n", errno, strerror(errno));
}
/* ----- 2. Read via fgets ----- */
{
FILE *fp = fopen(path, "r");
if (!fp) {
printf("fopen(r) failed: errno=%d\n", errno);
return 1;
}
char buf[128];
int n = 0;
while (fgets(buf, sizeof buf, fp)) {
printf(" line %d: %s", ++n, buf);
if (buf[strlen(buf)-1] != '\n') putchar('\n');
}
printf(" total lines: %d, feof=%d\n", n, feof(fp));
fclose(fp);
}
/* ----- 3. fread / fseek / ftell ----- */
{
FILE *fp = fopen(path, "r");
if (!fp) return 1;
char buf[16];
size_t got = fread(buf, 1, 16, fp);
printf(" fread(16) -> %u bytes, ftell=%ld\n",
(unsigned)got, ftell(fp));
if (fseek(fp, 0L, SEEK_END) == 0) {
printf(" file size via fseek(END)+ftell = %ld\n", ftell(fp));
}
rewind(fp);
printf(" rewind: ftell=%ld, feof=%d\n", ftell(fp), feof(fp));
fclose(fp);
}
/* ----- 4. Console pseudo-streams ----- */
fputs(" fputs to stdout works\n", stdout);
fputs(" fputs to stderr works\n", stderr);
fputc('!', stdout); fputc('\n', stdout);
/* ----- 5. "r+": чтение→запись→чтение + ungetc + fprintf ----- */
{
FILE *fp = fopen(path, "r+");
if (!fp) { puts("fopen(r+) failed"); return 1; }
for (int i = 0; i < 10; i++) fgetc(fp); /* поз. 10, readahead жив */
for (int i = 0; i < 10; i++) fputc('X', fp); /* sync: запись на 10..19 */
fseek(fp, 0L, SEEK_SET);
char buf[24];
size_t got = fread(buf, 1, 20, fp);
int ok = (got == 20);
for (int i = 10; i < 20; i++) if (buf[i] != 'X') ok = 0;
printf(" r+ mix: %s (got=%u)\n", ok ? "OK" : "FAIL", (unsigned)got);
/* ungetc: прочитать байт, вернуть, прочитать снова */
int c1 = fgetc(fp);
ungetc(c1, fp);
int c2 = fgetc(fp);
printf(" ungetc: %s, ftell=%ld\n", c1 == c2 ? "OK" : "FAIL", ftell(fp));
/* fprintf в файл */
fseek(fp, 0L, SEEK_END);
int n = fprintf(fp, "num=%d hex=%04x\n", 42, 0xBEEF);
printf(" fprintf -> %d chars\n", n);
if (fclose(fp)) puts(" r+ fclose: error");
}
puts("filetest done.");
return 0;
}