File
Description
Cross-platform file handle. Replaces stdio FILE * in the project: Linux uses an fd through direct syscalls, macOS uses an fd through libSystem, Windows uses a HANDLE. The API surface (FileOpen / Close / Read / Write / Seek / Tell / Flush / Eof) is identical across platforms.
Value type – caller stack-allocates and passes by pointer. A failed open leaves fd (or handle) negative / INVALID; check with FileIsValid before doing anything else with the handle.
Open modes are libc-compatible ("r", "w", "a", "r+", "w+", "a+"), "b" suffix is accepted and ignored – the implementation is always binary. No buffering today.
Usage example (Cross-references)
Usage examples (Cross-references)
#include <Misra/Parsers/Elf.h>
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>
#include <Misra/Sys/SymbolResolver.h>- In
File.c:6:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>
#include <Misra/Std/Memory.h>- In
File.c:135:
int main(void) {
WriteFmt("[INFO] Starting File tests\n\n");
TestFunction tests[] = {- In
File.c:142:
};
return run_test_suite(tests, sizeof(tests) / sizeof(tests[0]), NULL, 0, "File");
}- In
Sys.c:165:
#ifdef EEXIST
case EEXIST :
return "File exists";
#endif
#ifdef EXDEV- In
Sys.c:201:
#ifdef EFBIG
case EFBIG :
return "File too large";
#endif
#ifdef ENOSPC- In
Sys.c:233:
#ifdef ENAMETOOLONG
case ENAMETOOLONG :
return "File name too long";
#endif
#ifdef ENOTEMPTY- In
PdbCache.c:14:
#include <Misra/Std.h>
#include <Misra/Std/Container/Str.h>
#include <Misra/Std/File.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>- In
PdbCache.c:15:
#include <Misra/Std/Container/Str.h>
#include <Misra/Std/File.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>
#include <Misra/Std/Memory.h>- In
PdbCache.c:24:
static bool path_exists(const char *path) {
File f = FileOpen(path, "rb");
if (!FileIsValid(&f)) {
return false;- In
MachoCache.c:15:
#include <Misra/Std/Container/Str.h>
#include <Misra/Std/Log.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Memory.h>- In
MachoCache.c:23:
static bool path_exists(const char *path) {
File f = FileOpen(path, "rb");
if (!FileIsValid(&f)) {
return false;
#include <Misra/Std.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>
#include <Misra/Std/Memory.h>
#include <stdint.h>
#include <Misra/Std/File.h>
// ---------------------------------------------------------------------------
// Check whether `path` exists and is non-empty.
static bool path_exists(const char *path) {
File f = FileOpen(path, "rb");
if (!FileIsValid(&f)) {
return false;- In
ProcMaps.c:30:
#include <Misra/Std/Memory.h>
#include <Misra/Std/File.h>
// ---------------------------------------------------------------------------
- In
ProcMaps.c:171:
// buffer size and short-circuits to empty — we have to loop-read
// into a growing buffer ourselves.
File f = FileOpen("/proc/self/maps", "rb");
if (!FileIsValid(&f)) {
LOG_ERROR("ProcMapsLoad: FileOpen(/proc/self/maps) failed");- In
Dir.c:35:
return "Unknown";
case SYS_DIR_ENTRY_TYPE_REGULAR_FILE :
return "Regular File";
case SYS_DIR_ENTRY_TYPE_DIRECTORY :
return "Directory";- In
Pe.c:18:
#include <Misra/Parsers/Pe.h>
#include <Misra/Std.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>
#include <Misra/Std/Memory.h>- In
Http.c:11:
#if MISRA_HAVE_FILE
# include <Misra/Std/File.h>
#endif- In
Elf.c:17:
#include <Misra/Std.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Io.h>
#include <Misra/Std/Log.h>- In
MachO.c:11:
#include <Misra/Parsers/MachO.h>
#include <Misra/Std.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>
#include <Misra/Std/Memory.h>- In
Io.c:48:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Io.h>
#include <Misra/Std/Log.h>- In
Io.c:494:
}
bool f_write_fmt(File *stream, const char *fmtstr, TypeSpecificIO *argv, u64 argc, bool append_newline) {
Str out;
bool ok = true;- In
Io.c:756:
}
void f_read_fmt(File *file, const char *fmtstr, TypeSpecificIO *argv, u64 argc) {
DefaultAllocator scratch = DefaultAllocatorInit();- In
Log.c:30:
#include <Misra/Std/Allocator/Heap.h>
#include <Misra/Std/Container/Str.h>
#include <Misra/Std/File.h>
#include <Misra/Std/Io.h>
#include <Misra/Std/Log.h>- In
Log.c:56:
StrWriteFmt(&full, "[{}] [{}:{}] {}\n", (const char *)NAMES[type], (const char *)tag, line, (const char *)msg);
File out = (type == LOG_MESSAGE_TYPE_INFO) ? FileFromFd(1) : FileFromFd(2);
(void)FileWrite(&out, full.data, full.length);- In
File.c:10:
/// CreateFile / ReadFile / WriteFile / SetFilePointer / CloseHandle.
#include <Misra/Std/File.h>
#include <Misra/Std/Log.h>
#include <Misra/Sys.h>- In
File.c:74:
// ---------------------------------------------------------------------------
File FileOpen(const char *path, const char *mode) {
File f = {0};
#ifdef _WIN32- In
File.c:75:
File FileOpen(const char *path, const char *mode) {
File f = {0};
#ifdef _WIN32
f.handle = INVALID_HANDLE_VALUE;- In
File.c:144:
}
File FileFromFd(i32 fd) {
File f = {0};
#ifdef _WIN32- In
File.c:145:
File FileFromFd(i32 fd) {
File f = {0};
#ifdef _WIN32
(void)fd;- In
File.c:156:
}
File FileStdin(void) {
#ifdef _WIN32
File f = {.handle = GetStdHandle(STD_INPUT_HANDLE), .owns = false};- In
File.c:158:
File FileStdin(void) {
#ifdef _WIN32
File f = {.handle = GetStdHandle(STD_INPUT_HANDLE), .owns = false};
return f;
#else- In
File.c:165:
}
File FileStdout(void) {
#ifdef _WIN32
File f = {.handle = GetStdHandle(STD_OUTPUT_HANDLE), .owns = false};- In
File.c:167:
File FileStdout(void) {
#ifdef _WIN32
File f = {.handle = GetStdHandle(STD_OUTPUT_HANDLE), .owns = false};
return f;
#else- In
File.c:174:
}
File FileStderr(void) {
#ifdef _WIN32
File f = {.handle = GetStdHandle(STD_ERROR_HANDLE), .owns = false};- In
File.c:176:
File FileStderr(void) {
#ifdef _WIN32
File f = {.handle = GetStdHandle(STD_ERROR_HANDLE), .owns = false};
return f;
#else- In
File.c:183:
}
bool FileClose(File *f) {
if (!f) {
return false;- In
File.c:211:
}
bool FileIsValid(const File *f) {
if (!f) {
return false;- In
File.c:226:
// ---------------------------------------------------------------------------
i64 FileRead(File *f, void *buf, u64 n) {
if (!FileIsValid(f) || !buf) {
return -1;- In
File.c:263:
}
i64 FileWrite(File *f, const void *buf, u64 n) {
if (!FileIsValid(f) || !buf) {
return -1;- In
File.c:291:
}
i64 FileSeek(File *f, i64 offset, FileWhence whence) {
if (!FileIsValid(f)) {
return -1;- In
File.c:320:
}
i64 FileTell(File *f) {
return FileSeek(f, 0, FILE_SEEK_CUR);
}- In
File.c:324:
}
bool FileFlush(File *f) {
if (!FileIsValid(f)) {
return false;- In
File.c:338:
}
bool FileIsEof(const File *f) {
return f && f->at_eof;
}- In
File.c:342:
}
i32 FileFd(const File *f) {
#ifdef _WIN32
(void)f;- In
File.c:383:
}
File f = FileOpen(filename, "rb");
if (!FileIsValid(&f)) {
return false;- In
Std.h:37:
#if MISRA_HAVE_FILE
# include <Misra/Std/File.h>
#endif- In
File.h:45:
bool at_eof; // last read returned 0 bytes
bool owns; // true when FileClose should release the handle
} File;
///
- In
File.h:67:
/// FAILURE : Returns a File where `FileIsValid(&out)` is false.
///
File FileOpen(const char *path, const char *mode);
///
- In
File.h:75:
/// elsewhere.
///
File FileFromFd(i32 fd);
///
- In
File.h:81:
/// 0/1/2 on POSIX, the GetStdHandle() values on Windows.
///
File FileStdin(void);
File FileStdout(void);
File FileStderr(void);- In
File.h:82:
///
File FileStdin(void);
File FileStdout(void);
File FileStderr(void);- In
File.h:83:
File FileStdin(void);
File FileStdout(void);
File FileStderr(void);
///
- In
File.h:93:
/// FAILURE : Returns false if the close syscall failed (logged).
///
bool FileClose(File *f);
///
- In
File.h:98:
/// True if the underlying handle is valid (open).
///
bool FileIsValid(const File *f);
///
- In
File.h:109:
/// FAILURE : Returns -1 on error.
///
i64 FileRead(File *f, void *buf, u64 n);
///
- In
File.h:118:
/// FAILURE : Returns -1 on error.
///
i64 FileWrite(File *f, const void *buf, u64 n);
///
- In
File.h:126:
/// FAILURE : Returns -1 on error (typically ESPIPE for a pipe/tty).
///
i64 FileSeek(File *f, i64 offset, FileWhence whence);
///
- In
File.h:134:
/// FAILURE : Returns -1 on error.
///
i64 FileTell(File *f);
///
- In
File.h:146:
/// FAILURE : Returns false.
///
bool FileFlush(File *f);
///
- In
File.h:151:
/// True if a previous FileRead returned 0 bytes.
///
bool FileIsEof(const File *f);
///
- In
File.h:157:
/// Useful for syscalls that need a raw fd (e.g. isatty checks).
///
i32 FileFd(const File *f);
/// Snake_case runtime helper. Users call `ReadCompleteFile(...)`; the
- In
Io.h:11:
#include <Misra/Std/Container.h>
#include <Misra/Std/File.h>
#include <Misra/Types.h>- In
Io.h:486:
#define WriteFmt(...) \
do { \
File __misra_out__ = FileStdout(); \
FWriteFmt(&__misra_out__, __VA_ARGS__); \
} while (0)- In
Io.h:508:
#define WriteFmtLn(...) \
do { \
File __misra_out__ = FileStdout(); \
FWriteFmtLn(&__misra_out__, __VA_ARGS__); \
} while (0)- In
Io.h:531:
#define ReadFmt(...) \
do { \
File __misra_in__ = FileStdin(); \
FReadFmt(&__misra_in__, __VA_ARGS__); \
} while (0)- In
MisraDoc.c:171:
int main(int argc, char **argv) {
if (argc != 2) {
File err_ = FileStderr();
FWriteFmtLn(&err_, "USAGE : {} config.json", argc == 0 ? "MisraDoc" : argv[0]);
return 1;- In
MisraEnum.c:253:
if (argc < 2 || argc > 3) {
File err_ = FileStderr();
FWriteFmtLn(&err_, "USAGE : {} <enum-json-spec> [output-file-name]", argc == 0 ? "MisraEnum" : argv[0]);
return 1;- In
ElfInfo.c:342:
}
File elf = FileOpen(argv[1], "rb");
if (!FileIsValid(&elf)) {
LOG_ERROR("Failed to open file for reading.");
Last updated on