Avoid closing stdin/stdout/stderr standard streams

This commit is contained in:
Rangi
2026-07-13 13:02:46 -04:00
parent 8ab6190f96
commit e9fa1e4e94
11 changed files with 42 additions and 22 deletions
+2 -1
View File
@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "helpers.hpp" // assume #include "helpers.hpp" // assume
#include "util.hpp" // xfclose
enum MissingInclude { enum MissingInclude {
INC_ERROR, // A missing included file is an error that halts assembly INC_ERROR, // A missing included file is an error that halts assembly
@@ -32,7 +33,7 @@ struct Options {
~Options() { ~Options() {
if (dependFile) { if (dependFile) {
fclose(dependFile); xfclose(dependFile);
} }
} }
+5
View File
@@ -8,6 +8,7 @@
#include <optional> #include <optional>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <string_view> #include <string_view>
#include <unordered_map> #include <unordered_map>
@@ -21,6 +22,10 @@ enum NumberBase {
BASE_16 = 16, BASE_16 = 16,
}; };
// File-closing functions that will not close standard streams
int xfclose(FILE *file);
int xclose(int fd);
// Locale-independent character class functions // Locale-independent character class functions
bool isNewline(int c); bool isNewline(int c);
bool isBlankSpace(int c); bool isBlankSpace(int c);
+2 -1
View File
@@ -18,6 +18,7 @@
#include "extern/utf8decoder.hpp" #include "extern/utf8decoder.hpp"
#include "helpers.hpp" #include "helpers.hpp"
#include "linkdefs.hpp" #include "linkdefs.hpp"
#include "util.hpp" // xfclose
#include "asm/charmap.hpp" #include "asm/charmap.hpp"
#include "asm/format.hpp" #include "asm/format.hpp"
@@ -147,7 +148,7 @@ std::optional<std::string> act_ReadFile(std::string const &name, uint32_t maxLen
} }
return ""; return "";
} }
Defer closeFile{[&] { fclose(file); }}; Defer closeFile{[&] { xfclose(file); }};
size_t readSize = maxLen; size_t readSize = maxLen;
if (fseek(file, 0, SEEK_END) == 0) { if (fseek(file, 0, SEEK_END) == 0) {
+1 -5
View File
@@ -405,11 +405,7 @@ void LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
if (fd >= 0) { if (fd >= 0) {
// If the file is stdin, or if measuring its size failed, read it in pieces // If the file is stdin, or if measuring its size failed, read it in pieces
Defer closeFile{[&] { Defer closeFile{[&] { xclose(fd); }};
if (fd != STDIN_FILENO) {
close(fd);
}
}};
// Reasonably large buffer size for `read` performance // Reasonably large buffer size for `read` performance
char buf[8192]; char buf[8192];
+3 -2
View File
@@ -17,6 +17,7 @@
#include "helpers.hpp" // assume, Defer #include "helpers.hpp" // assume, Defer
#include "linkdefs.hpp" #include "linkdefs.hpp"
#include "platform.hpp" #include "platform.hpp"
#include "util.hpp" // xfclose
#include "asm/charmap.hpp" #include "asm/charmap.hpp"
#include "asm/fstack.hpp" #include "asm/fstack.hpp"
@@ -210,7 +211,7 @@ void out_WriteObject() {
fatal("Failed to open object file \"%s\": %s", objectFileName, strerror(errno)); fatal("Failed to open object file \"%s\": %s", objectFileName, strerror(errno));
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
Defer closeFile{[&] { fclose(file); }}; Defer closeFile{[&] { xfclose(file); }};
// Also write symbols that weren't written above // Also write symbols that weren't written above
sym_ForEach(out_RegisterSymbol); sym_ForEach(out_RegisterSymbol);
@@ -389,7 +390,7 @@ void out_WriteState(std::string name, std::vector<StateFeature> const &features)
fatal("Failed to open state file \"%s\": %s", name.c_str(), strerror(errno)); fatal("Failed to open state file \"%s\": %s", name.c_str(), strerror(errno));
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
Defer closeFile{[&] { fclose(file); }}; Defer closeFile{[&] { xfclose(file); }};
static char const *dumpHeadings[NB_STATE_FEATURES] = { static char const *dumpHeadings[NB_STATE_FEATURES] = {
"Numeric constants", "Numeric constants",
+3 -2
View File
@@ -21,6 +21,7 @@
#include "helpers.hpp" #include "helpers.hpp"
#include "itertools.hpp" // InsertionOrderedMap #include "itertools.hpp" // InsertionOrderedMap
#include "linkdefs.hpp" #include "linkdefs.hpp"
#include "util.hpp" // xfclose
#include "asm/fstack.hpp" #include "asm/fstack.hpp"
#include "asm/lexer.hpp" #include "asm/lexer.hpp"
@@ -974,7 +975,7 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos) {
if (!file) { if (!file) {
return fstk_FileError(name, "`INCBIN`"); return fstk_FileError(name, "`INCBIN`");
} }
Defer closeFile{[&] { fclose(file); }}; Defer closeFile{[&] { xfclose(file); }};
if (fseek(file, 0, SEEK_END) == 0) { if (fseek(file, 0, SEEK_END) == 0) {
if (unsigned long fsize = ftell(file); if (unsigned long fsize = ftell(file);
@@ -1035,7 +1036,7 @@ bool sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t l
if (!file) { if (!file) {
return fstk_FileError(name, "`INCBIN`"); return fstk_FileError(name, "`INCBIN`");
} }
Defer closeFile{[&] { fclose(file); }}; Defer closeFile{[&] { xfclose(file); }};
if (fseek(file, 0, SEEK_END) == 0) { if (fseek(file, 0, SEEK_END) == 0) {
if (unsigned long fsize = ftell(file); if (unsigned long fsize = ftell(file);
+4 -5
View File
@@ -15,6 +15,7 @@
#include "diagnostics.hpp" #include "diagnostics.hpp"
#include "helpers.hpp" #include "helpers.hpp"
#include "platform.hpp" #include "platform.hpp"
#include "util.hpp" // xclose, xfclose
#include "fix/main.hpp" #include "fix/main.hpp"
#include "fix/mbc.hpp" #include "fix/mbc.hpp"
@@ -463,7 +464,6 @@ bool fix_ProcessFile(char const *name, char const *outputName) {
} }
int output = -1; int output = -1;
bool openedOutput = false;
if (outputName) { if (outputName) {
if (!strcmp(outputName, "-")) { if (!strcmp(outputName, "-")) {
output = STDOUT_FILENO; output = STDOUT_FILENO;
@@ -476,12 +476,11 @@ bool fix_ProcessFile(char const *name, char const *outputName) {
return true; return true;
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
openedOutput = true;
} }
} }
Defer closeOutput{[&] { Defer closeOutput{[&] {
if (openedOutput) { if (outputName) {
close(output); xclose(output);
} }
}}; }};
@@ -497,7 +496,7 @@ bool fix_ProcessFile(char const *name, char const *outputName) {
// operations may fail, all of which we handle. // operations may fail, all of which we handle.
error("Failed to open \"%s\" for reading+writing: %s", name, strerror(errno)); error("Failed to open \"%s\" for reading+writing: %s", name, strerror(errno));
} else { } else {
Defer closeInput{[&] { close(input); }}; Defer closeInput{[&] { xclose(input); }};
struct stat stat; struct stat stat;
if (fstat(input, &stat) == -1) { if (fstat(input, &stat) == -1) {
error("Failed to stat \"%s\": %s", name, strerror(errno)); // LCOV_EXCL_LINE error("Failed to stat \"%s\": %s", name, strerror(errno)); // LCOV_EXCL_LINE
+1 -1
View File
@@ -308,7 +308,7 @@ static void initLogo() {
fatal("Failed to open \"%s\" for reading: %s", logoFilename, strerror(errno)); fatal("Failed to open \"%s\" for reading: %s", logoFilename, strerror(errno));
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
Defer closeLogo{[&] { fclose(logoFile); }}; Defer closeLogo{[&] { xfclose(logoFile); }};
uint8_t logoBpp[sizeof(options.logo)]; uint8_t logoBpp[sizeof(options.logo)];
if (size_t nbRead = fread(logoBpp, 1, sizeof(logoBpp), logoFile); if (size_t nbRead = fread(logoBpp, 1, sizeof(logoBpp), logoFile);
+2 -1
View File
@@ -19,6 +19,7 @@
#include "helpers.hpp" #include "helpers.hpp"
#include "linkdefs.hpp" #include "linkdefs.hpp"
#include "platform.hpp" #include "platform.hpp"
#include "util.hpp" // xfclose
#include "verbosity.hpp" #include "verbosity.hpp"
#include "version.hpp" #include "version.hpp"
@@ -446,7 +447,7 @@ void obj_ReadFile(std::string const &filePath, size_t fileID) {
if (!file) { if (!file) {
fatal("Failed to open file \"%s\": %s", fileName, strerror(errno)); fatal("Failed to open file \"%s\": %s", fileName, strerror(errno));
} }
Defer closeFile{[&] { fclose(file); }}; Defer closeFile{[&] { xfclose(file); }};
// First, check if the object is a RGBDS object, a SDCC one, or neither. // First, check if the object is a RGBDS object, a SDCC one, or neither.
// A single `ungetc` is guaranteed to work. // A single `ungetc` is guaranteed to work.
+4 -4
View File
@@ -218,7 +218,7 @@ static void writeROM() {
} }
Defer closeOutputFile{[&] { Defer closeOutputFile{[&] {
if (outputFile) { if (outputFile) {
fclose(outputFile); xfclose(outputFile);
} }
}}; }};
@@ -237,7 +237,7 @@ static void writeROM() {
} }
Defer closeOverlayFile{[&] { Defer closeOverlayFile{[&] {
if (overlayFile) { if (overlayFile) {
fclose(overlayFile); xfclose(overlayFile);
} }
}}; }};
@@ -556,7 +556,7 @@ static void writeSym() {
if (!symFile) { if (!symFile) {
fatal("Failed to open sym file \"%s\": %s", symFileName, strerror(errno)); fatal("Failed to open sym file \"%s\": %s", symFileName, strerror(errno));
} }
Defer closeSymFile{[&] { fclose(symFile); }}; Defer closeSymFile{[&] { xfclose(symFile); }};
fputs("; File generated by rgblink\n", symFile); fputs("; File generated by rgblink\n", symFile);
@@ -607,7 +607,7 @@ static void writeMap() {
if (!mapFile) { if (!mapFile) {
fatal("Failed to open map file \"%s\": %s", mapFileName, strerror(errno)); fatal("Failed to open map file \"%s\": %s", mapFileName, strerror(errno));
} }
Defer closeMapFile{[&] { fclose(mapFile); }}; Defer closeMapFile{[&] { xfclose(mapFile); }};
writeMapSummary(); writeMapSummary();
+15
View File
@@ -9,6 +9,21 @@
#include <string.h> // strspn #include <string.h> // strspn
#include "helpers.hpp" // assume #include "helpers.hpp" // assume
#include "platform.hpp"
int xfclose(FILE *file) {
if (file == stdin || file == stdout || file == stderr) {
return 0;
}
return fclose(file);
}
int xclose(int fd) {
if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) {
return 0;
}
return close(fd);
}
bool isNewline(int c) { bool isNewline(int c) {
return c == '\r' || c == '\n'; return c == '\r' || c == '\n';