Skip to content

FileOpen

Description

Open a file. mode accepts: "r"/"rb", "w"/"wb", "a"/"ab", "r+", "w+", "a+". Binary is always implied; the "b" suffix is accepted but has no effect on the implementation.

Parameters

Name Direction Description
path in Path to open. Prefer Str * (carries length, can’t silently drop the NUL terminator). Zstr is accepted as a literal / borrowed-buffer convenience.

Success

Returns a File where FileIsOpen(&out) is true.

Failure

Returns a File where FileIsOpen(&out) is false.

Usage example (Cross-references)

Usage examples (Cross-references)
        (void)mode;
        (void)out_flags;
        return false; // Windows uses a different mode encoding (see FileOpen).
    #else
        if (!mode || !*mode) {
        HANDLE h = CreateFileA(path, access, FILE_SHARE_READ, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL);
        if (h == INVALID_HANDLE_VALUE) {
            LOG_ERROR("FileOpen: CreateFileA(\"{}\") failed (err {})", path, (u32)GetLastError());
            return f;
        }
        int flags;
        if (!parse_open_mode(mode, &flags)) {
            LOG_ERROR("FileOpen: invalid mode \"{}\"", mode);
            return f;
        }
            // 256-byte slot. Until that pipeline learns a default-allocator
            // fall-through, surface the errno number directly here.
            LOG_ERROR("FileOpen: open(\"{}\") failed (errno {})", path, ErrnoOf(fd));
            return f;
        }
    // with an empty Str.
    static bool slurp_file(Zstr path, Str *out) {
        File f = FileOpen(path, "rb");
        if (!FileIsOpen(&f)) {
            // Missing config file is fine -- resolver just won't know about it.
    /// callers (cache lookups, sidecar discovery).
    static inline bool sys_path_exists(Zstr path) {
        File f = FileOpen(path, "rb");
        if (!FileIsOpen(&f)) {
            return false;
        // `/proc/self/maps` reports stat-size 0 because it's generated by the
        // kernel on read, so we loop-read into a growing buffer ourselves.
        File f = FileOpen("/proc/self/maps", "rb");
        if (!FileIsOpen(&f)) {
            LOG_ERROR("ProcMapsLoad: FileOpen(/proc/self/maps) failed");
        File f = FileOpen("/proc/self/maps", "rb");
        if (!FileIsOpen(&f)) {
            LOG_ERROR("ProcMapsLoad: FileOpen(/proc/self/maps) failed");
            ProcMapsDeinit(out);
            return false;
        }
    
        File f = FileOpen(&path, "rb");
        if (!FileIsOpen(&f)) {
            FileRemove(&path);
        }
    
        File f = FileOpen(&path, "rb");
        if (!FileIsOpen(&f)) {
            FileRemove(&path);
        }
    
        File f = FileOpen(&path, "rb");
        ok     = ok && FileIsOpen(&f);
        FileClose(&f);
    // An invalid mode string yields a File that reports not-open.
    bool test_open_invalid_mode(void) {
        WriteFmt("Testing FileOpen with an invalid mode returns a not-open file\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
    
        // "q" is not a recognised mode.
        File f = FileOpen(&path, "q");
        ok     = ok && !FileIsOpen(&f);
        FileClose(&f);
    
        // An empty mode is also rejected.
        File g = FileOpen(&path, "");
        ok     = ok && !FileIsOpen(&g);
        FileClose(&g);
        }
    
        File f = FileOpen(&path, "rb");
        ok     = ok && FileIsOpen(&f);
        }
    
        File w = FileOpen(&path, "w");
        ok     = ok && FileIsOpen(&w);
        ok     = ok && (FileWrite(&w, "new", 3) == 3);
        FileClose(&w);
    
        File r   = FileOpen(&path, "rb");
        ok       = ok && FileIsOpen(&r);
        Str body = StrInit(alloc_base);
        }
    
        File a = FileOpen(&path, "a");
        ok     = ok && FileIsOpen(&a);
        ok     = ok && (FileWrite(&a, "tail", 4) == 4);
        FileClose(&a);
    
        File r    = FileOpen(&path, "rb");
        Str  body = StrInit(alloc_base);
        i64  got  = FileRead(&r, &body);
        }
    
        File f = FileOpen(&path, "r");
        ok     = ok && FileIsOpen(&f);
        // A read-only handle must reject writes.
        }
    
        File f = FileOpen(&path, "r+");
        ok     = ok && FileIsOpen(&f);
        // "r+" must permit writes (does not truncate). Overwrite first 3 bytes.
        // Confirm the write landed.
        Str  body = StrInit(alloc_base);
        File r    = FileOpen(&path, "rb");
        i64  got  = FileRead(&r, &body);
        FileClose(&r);
        }
    
        File f      = FileOpen(&path, "r");
        ok          = ok && FileIsOpen(&f);
        char buf[8] = {0};
        }
    
        File f      = FileOpen(&path, "rb");
        ok          = ok && FileIsOpen(&f);
        char buf[4] = {0};
        }
    
        File f      = FileOpen(&path, "rb");
        ok          = ok && FileIsOpen(&f);
        char buf[8] = {0};
        }
    
        File f = FileOpen(&path, "rb");
        ok     = ok && FileIsOpen(&f);
        // Move the cursor to offset 10; remaining size must be 16 - 10 = 6.
        }
    
        File f   = FileOpen(&path, "rb");
        ok       = ok && FileIsOpen(&f);
        Str body = StrInit(alloc_base);
        FileClose(&f);
    
        File r  = FileOpen(&path, "rb");
        ok      = ok && FileIsOpen(&r);
        Buf dst = BufInit(alloc_base);
    static bool roundtrip_eq(Zstr path, Zstr expect) {
        DefaultAllocator alloc = DefaultAllocatorInit();
        File             f     = FileOpen(path, "r");
        bool             ok    = false;
        if (FileIsOpen(&f)) {
    static bool test_m28_fwrite_roundtrip_string(void) {
        Zstr path = "io_mutants28_str.txt"; // CWD-relative: portable (no /tmp on Windows)
        File f    = FileOpen(path, "w");
        if (!FileIsOpen(&f)) {
            return false;
    static bool test_m28_fwrite_roundtrip_int(void) {
        Zstr path = "io_mutants28_int.txt"; // CWD-relative: portable (no /tmp on Windows)
        File f    = FileOpen(path, "w");
        if (!FileIsOpen(&f)) {
            return false;
    static bool test_m28_fwriteln_roundtrip(void) {
        Zstr path = "io_mutants28_ln.txt"; // CWD-relative: portable (no /tmp on Windows)
        File f    = FileOpen(path, "w");
        if (!FileIsOpen(&f)) {
            return false;
            ok = ok && FWriteFmtLn(&f, "n={}", LVAL((i32)42));
            FileClose(&f);
            File r = FileOpen(StrBegin(&path), "r");
            if (FileIsOpen(&r)) {
                Str back = StrInit(&alloc);
            ok = ok && FWriteFmt(&f, "X");
            FileClose(&f);
            File r = FileOpen(StrBegin(&path), "r");
            if (FileIsOpen(&r)) {
                Str back = StrInit(&alloc);
        // Use Misra's File API so this test runs under -nostdlib too
        // (no libc fopen/fwrite/fclose).
        File f = FileOpen(path, "w");
        if (!FileIsOpen(&f))
            return false;
    
    static bool write_file(Zstr path, const u8 *data, u64 size) {
        File f = FileOpen(path, "wb");
        if (!FileIsOpen(&f))
            return false;
    
    static bool mc_write_file(Zstr path, const u8 *data, u64 size) {
        File f = FileOpen(path, "wb");
        if (!FileIsOpen(&f))
            return false;
    
    static bool bl_write_file(Zstr path, const u8 *data, u64 size) {
        File f = FileOpen(path, "wb");
        if (!FileIsOpen(&f))
            return false;
        }
    
        File rf = FileOpen(&path, "rb");
        if (!FileIsOpen(&rf)) {
            FileRemove(&path);
    
        // A directory: open(2) succeeds (FileIsOpen true) but read(2) returns -1.
        File dir = FileOpen("/proc/self", "rb");
        if (!FileIsOpen(&dir)) {
            DebugAllocatorDeinit(&dbg);
Last updated on