Files
snark13 48d552bf3a libc: FILE* v2 — буферизация потоков (вариант B+)
- единый ленивый буфер BUFSIZ=512 на чтение и запись с
  автопереключением направления (_F_DIROUT, _file_sync: запись
  сбрасывается write()-ом, readahead откатывается lseek-ом)
- статическая таблица OPEN_MAX=8 слотов вместо malloc для FILE;
  _fclosall через atexit — exit() сбрасывает несброшенную запись
- fread/fwrite: мелкое через буфер (memcpy), блоки >= BUFSIZ — мимо
  буфера одним syscall; горячие пути fgetc/fputc и сканер строк
  fgets (LDI до '\n') — на asm, SDCC на эти цепочки генерит ~90
  инструкций с IX-фреймом
- новое: ungetc (1 байт через hold, работает и на stdin),
  fprintf/vfprintf (vsprintf+fwrite), fflush(NULL) = все потоки
- фиксы stdio-review: fwrite ставит _F_ERROR при короткой записи
  (issue 3), fgets(n=1) возвращает пустую строку (issue 4)
- замер (MAME, HDD, 100 КБ): небуферизованная оценка ~144 с →
  fgetc 5 с (×29), fgets ~1 с; дизайн и отвергнутые варианты —
  docs/file-buffering-design.md

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

28 lines
1.6 KiB
C
Raw Permalink 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.
/*
* std_streams — три предопределённых консольных псевдопотока.
*
* stdin/stdout/stderr — СТАТИЧЕСКИЕ FILE-заглушки с флагами
* _F_CONIN/_F_CONOUT; fputc/fgetc распознают флаги и зовут putchar()/
* getchar(), которые уже делают трансляцию CR/LF и вызовы ESTEX.
*
* Поля fd: 0 / -1 / -2. Отрицательные значения выбраны потому, что
* ESTEX OPEN возвращает маленькие положительные fd (1, 2, …) для
* обычных файлов — с fd=1/2 у stdout/stderr реальный файл мог бы
* совпасть с ними. fd=0 у stdin оставлен (POSIX-стиль), т.к. ESTEX
* не возвращает 0. В syscall эти fd всё равно не попадают —
* диспетчеризацию ведут флаги _F_CONIN/_F_CONOUT (и по ним же fclose()
* узнаёт псевдопотоки, не ссылаясь на адреса из этого модуля).
*/
#include <stdio.h>
/* Консольные потоки не буферизуются: buf/curp/level не используются.
* hold = EOF (пусто) — ungetc на stdin работает через это поле. */
static FILE _stdin = { 0, _F_READ | _F_CONIN, 0, 0, 0, EOF };
static FILE _stdout = { -1, _F_WRITE | _F_CONOUT, 0, 0, 0, EOF };
static FILE _stderr = { -2, _F_WRITE | _F_CONOUT, 0, 0, 0, EOF };
FILE *const stdin = &_stdin;
FILE *const stdout = &_stdout;
FILE *const stderr = &_stderr;