/*
 * fdmax — эмпирическая проверка лимита одновременно открытых файлов.
 *
 * ФАКТ (прогон 2026-07-06, DSS 1.71.57): DSS выдал 8 манипуляторов
 * (fd 2..9; fd 1 держит шелл DSS под запущенный .exe), а 9-й OPEN
 * НЕ вернул ошибку — ПОВЕСИЛ систему.  После этого в libc/io/open.c
 * добавлен предохранитель _fd_guard (отказ EMFILE на 9-м open без
 * захода в DSS), и этот тест снова безопасен.
 *
 * 1) Низкий уровень: open("TEST.TXT") в цикле — ожидание: 8 хендлов,
 *    затем EMFILE=6 от предохранителя libc (не от DSS!).
 * 2) Высокий уровень: fopen до NULL — таблица OPEN_MAX (8), EMFILE.
 *
 * Требует TEST.TXT на диске (без него обе фазы дадут ENOENT=3).
 */

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define TRY_MAX 32

int main(void)
{
    int  fds[TRY_MAX];
    int  n = 0;

    /* ----- 1. Голые манипуляторы DSS ----- */
    errno = 0;
    while (n < TRY_MAX) {
        int fd = open("TEST.TXT", O_RDONLY);
        if (fd < 0) break;
        fds[n++] = fd;
        printf("open #%d -> fd=%d\n", n, fd);
    }
    printf("low-level: %d handles, then errno=%d (%s)\n",
           n, errno, strerror(errno));
    for (int i = 0; i < n; i++) close(fds[i]);

    /* ----- 2. fopen / таблица FILE ----- */
    FILE *fps[TRY_MAX];
    int   m = 0;
    errno = 0;
    while (m < TRY_MAX) {
        FILE *fp = fopen("TEST.TXT", "r");
        if (!fp) break;
        fps[m++] = fp;
    }
    printf("fopen: %d streams (OPEN_MAX=%d), then errno=%d (%s)\n",
           m, OPEN_MAX, errno, strerror(errno));
    for (int i = 0; i < m; i++) fclose(fps[i]);

    puts("fdmax done.");
    return 0;
}
