/
Dengit-man
/
CustomLocaleKeyShortcut
Обзор
Документация
Войти
/
Dengit-man
/
CustomLocaleKeyShortcut
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
7
CI/CD
Аналитика
Безопасность
AddMacOS
Classes/S_BlockStdIn.cpp
115 строк
3 KB
Dengit-man
Поправлен `LICENSE.md` и соответствующие упоминания в нужных файлах.
25 май 2026, 23:32
Верифицирован
25 май 2026, 23:32
79c96dd
Код
Авторство
О чём код?
// // Created by Den on вт,26.05.2026. // #include "S_BlockStdIn.h" // #include "block_stdin.h" #include <cstdio> #include <iostream> #if defined(_WIN32) #include <io.h> #include <fcntl.h> #else #include <unistd.h> #include <fcntl.h> #endif int S_BlockStdIn::saved_stdin_fd = -1; S_BlockStdIn::S_BlockStdIn() : f_IsSuccess(S_BlockStdIn::block_stdin()) { if (f_IsSuccess) { std::cout << "Standard input is locked" << std::endl; } else { std::cout << "Standard input is not locked" << std::endl; } } bool S_BlockStdIn::block_stdin() { #if defined(_WIN32) // Сохраняем текущий дескриптор stdin (CRT) saved_stdin_fd = _dup(_fileno(stdin)); if (saved_stdin_fd < 0) return false; // Открываем NUL и дублируем на stdin int nul_fd = _open("NUL", _O_RDONLY | _O_BINARY); if (nul_fd < 0) { _close(saved_stdin_fd); saved_stdin_fd = -1; return false; } if (_dup2(nul_fd, _fileno(stdin)) != 0) { _close(nul_fd); _close(saved_stdin_fd); saved_stdin_fd = -1; return false; } if (nul_fd > 2) _close(nul_fd); // Защитить C++ поток std::cin.setstate(std::ios::eofbit | std::ios::failbit); std::cin.rdbuf(nullptr); fflush(nullptr); return true; #else // POSIX (для полноты) int orig = dup(STDIN_FILENO); if (orig < 0) return false; saved_stdin_fd = orig; int nul = open("/dev/null", O_RDONLY); if (nul < 0) { close(saved_stdin_fd); saved_stdin_fd = -1; return false; } if (dup2(nul, STDIN_FILENO) < 0) { close(nul); close(saved_stdin_fd); saved_stdin_fd = -1; return false; } if (nul > STDIN_FILENO) close(nul); std::cin.setstate(std::ios::eofbit | std::ios::failbit); std::cin.rdbuf(nullptr); fflush(nullptr); return true; #endif } bool S_BlockStdIn::restore_stdin() { #if defined(_WIN32) if (saved_stdin_fd < 0) return false; if (_dup2(saved_stdin_fd, _fileno(stdin)) != 0) { _close(saved_stdin_fd); saved_stdin_fd = -1; return false; } _close(saved_stdin_fd); saved_stdin_fd = -1; std::cin.clear(); // Восстановление rdbuf: переназначаем на стандартный буфер CRT. // Создадим поток-контейнер для получения rdbuf у stdin через FILE* не тривиально, // поэтому просто сбрасываем состояние; в большинстве реализаций std::cin снова будет работать. std::cin.rdbuf(std::cin.rdbuf()); return true; #else if (saved_stdin_fd < 0) return false; if (dup2(saved_stdin_fd, STDIN_FILENO) < 0) { close(saved_stdin_fd); saved_stdin_fd = -1; return false; } close(saved_stdin_fd); saved_stdin_fd = -1; std::cin.clear(); std::cin.rdbuf(std::cin.rdbuf()); return true; #endif } bool S_BlockStdIn::IsSuccess() { return this->f_IsSuccess; }