diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 873d0e9..765ea72 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 182 +#define MONTAUK_BUILD_NUMBER 184 diff --git a/kernel/src/Fs/Ext2.cpp b/kernel/src/Fs/Ext2.cpp index 9ae8d1f..0bf7db4 100644 --- a/kernel/src/Fs/Ext2.cpp +++ b/kernel/src/Fs/Ext2.cpp @@ -1202,6 +1202,13 @@ namespace Fs::Ext2 { Inode inode; if (!TraversePath(self, path, &inodeNum, &inode)) return -1; + // Directories are not openable as files, matching the ramdisk. A + // handle on one would fail every read/write anyway, and userspace + // stat() falls back to open() when it cannot get real metadata: + // succeeding here classified every directory as a regular file and + // GCC's include-path setup then rejected them as "not a directory". + if ((inode.i_mode & IMODE_TYPE_MASK) == IMODE_DIR) return -1; + for (int i = 0; i < MaxFilesPerInstance; i++) { if (!self.files[i].inUse) { self.files[i].inUse = true; diff --git a/kernel/src/Fs/Fat32.cpp b/kernel/src/Fs/Fat32.cpp index 8ed8ac5..514135f 100644 --- a/kernel/src/Fs/Fat32.cpp +++ b/kernel/src/Fs/Fat32.cpp @@ -955,6 +955,10 @@ namespace Fs::Fat32 { ParsedEntry entry; if (!TraversePath(inst, path, &entry)) return -1; + // Directories are not openable as files; see the matching note in + // Ext2::OpenImpl (userspace stat() falls back to open()). + if ((entry.attributes & ATTR_DIRECTORY) != 0) return -1; + // Find a free file handle auto& self = g_instances[inst]; for (int i = 0; i < MaxFilesPerInstance; i++) { diff --git a/programs/include/libc/wchar.h b/programs/include/libc/wchar.h index cd90739..45c8baf 100644 --- a/programs/include/libc/wchar.h +++ b/programs/include/libc/wchar.h @@ -21,6 +21,7 @@ typedef struct { /* Byte-oriented C locale only: one byte, one character. */ size_t mbstowcs(wchar_t *dst, const char *src, size_t n); int mblen(const char *s, size_t n); +size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps); #ifdef __cplusplus } diff --git a/programs/lib/libc/libc.c b/programs/lib/libc/libc.c index 21440be..b1c45da 100644 --- a/programs/lib/libc/libc.c +++ b/programs/lib/libc/libc.c @@ -25,6 +25,7 @@ #include #include #include +#include /* ======================================================================== Raw syscall wrappers (C versions matching kernel ABI) @@ -3622,6 +3623,20 @@ int mbtowc(wchar_t *pwc, const char *s, size_t n) { return 1; } +/* Restartable form of mbtowc. The C locale carries no shift state, so ps is + ignored; binutils reaches for this once configure sees mbstate_t. */ +size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) { + (void)ps; + if (s == NULL) return 0; /* query: the C locale is stateless */ + if (n == 0) return (size_t)-2; /* incomplete: no bytes to examine */ + if (*s == '\0') { + if (pwc != NULL) *pwc = 0; + return 0; + } + if (pwc != NULL) *pwc = (wchar_t)(unsigned char)*s; + return 1; +} + int wctomb(char *s, wchar_t wc) { if (s == NULL) return 0; *s = (char)wc;