diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 4b1cad4..64d8e93 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 92 +#define MONTAUK_BUILD_NUMBER 94 diff --git a/kernel/src/Drivers/Net/Wifi/IwxReg.hpp b/kernel/src/Drivers/Net/Wifi/IwxReg.hpp index 731a260..e0404c7 100644 --- a/kernel/src/Drivers/Net/Wifi/IwxReg.hpp +++ b/kernel/src/Drivers/Net/Wifi/IwxReg.hpp @@ -5,7 +5,9 @@ * Register offsets, firmware command IDs and wire-format structures follow * Intel's dual BSD/GPLv2-licensed iwlwifi API headers, as consolidated in * OpenBSD's if_iwxreg.h (ISC/BSD). Only the subset used by this driver is - * kept. See 0:/os/licenses/NOTICES.txt for the full attribution. + * kept. MontaukOS relies on the BSD license option; see + * montaukos.org/THIRD-PARTY-NOTICES.txt and 0:/os/licenses/NOTICES.txt for + * the full attribution and license terms. * * Copyright (c) 2026 Daniel Hammer * Portions Copyright (c) 2017 Intel Deutschland GmbH diff --git a/kernel/src/Ipc/Ipc.cpp b/kernel/src/Ipc/Ipc.cpp index cdaf2ee..63dd51d 100644 --- a/kernel/src/Ipc/Ipc.cpp +++ b/kernel/src/Ipc/Ipc.cpp @@ -714,8 +714,17 @@ namespace Ipc { g_handleTableLocks[slot].Acquire(); uint64_t& bm0 = g_handleBitmaps[slot][0]; uint64_t& bm1 = g_handleBitmaps[slot][1]; - // Find first zero bit in bitmap (free slot) - uint64_t bits0 = ~bm0; + // Find first zero bit in bitmap (free slot). + // + // Handles 0, 1 and 2 are never allocated: to POSIX code those numbers + // ARE stdin/stdout/stderr, and the libc routes read()/write() on them + // to the terminal (SYS_GETCHAR/SYS_PUTCHAR) rather than to this table. + // Handing them out as file handles makes the two meanings collide -- + // a program's third open() would own "stderr", and every write(2, ...) + // it made would land in that file instead of on screen. Reserving them + // here rather than at process setup keeps the rule in one place and + // immune to a stale bitmap. + uint64_t bits0 = ~bm0 & ~0x7ULL; uint64_t bits1 = ~bm1; if (bits0) { int i = __builtin_ctzll(bits0); diff --git a/montaukos.org/THIRD-PARTY-NOTICES.txt b/montaukos.org/THIRD-PARTY-NOTICES.txt index c14923f..b43300b 100644 --- a/montaukos.org/THIRD-PARTY-NOTICES.txt +++ b/montaukos.org/THIRD-PARTY-NOTICES.txt @@ -356,7 +356,64 @@ License: Intel redistributable firmware license ================================================================================ -14. Default wallpaper photograph +14. Intel iwlwifi register definitions +================================================================================ +The register offsets, firmware command identifiers, and wire-format structures +in kernel/src/Drivers/Net/Wifi/IwxReg.hpp are an adapted subset of the Intel +iwlwifi API definitions as consolidated in OpenBSD's if_iwxreg.h. MontaukOS +relies on the BSD license option of the upstream dual BSD/GPLv2 license. + + Copyright (c) 2017 Intel Deutschland GmbH + Copyright (c) 2018-2019 Intel Corporation + Copyright (c) 2026 Daniel Hammer + + This file is provided under a dual BSD/GPLv2 license. When using or + redistributing the upstream material, you may do so under either license. + MontaukOS relies on the BSD license option for the adapted material. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Intel Corporation nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + +================================================================================ +15. Intel iwlwifi firmware +================================================================================ +Shipped as binary firmware payloads in the bootable image: + + programs/data/firmware/intel/iwlwifi-so-a0-gf-a0-89.ucode + programs/data/firmware/intel/iwlwifi-so-a0-gf-a0.pnvm + +These files are redistributable Intel iwlwifi firmware obtained from the +linux-firmware project. The files remain Intel property and are not licensed +under the MontaukOS Software License. The full license text is included on +the MontaukOS ISO at 0:/os/licenses/Intel-iwlwifi-firmware.txt. + + +================================================================================ +16. Default wallpaper photograph ================================================================================ Shipped as the default login-screen wallpaper on the ISO (0:/os/wallpapers/default.jpg): a photograph of blossoms against misty hills. @@ -374,7 +431,7 @@ License: Unsplash License (https://unsplash.com/license) similar or competing service. ================================================================================ -15. Flanterm (text renderer for kernel debug log) +17. Flanterm (text renderer for kernel debug log) ================================================================================ Compiled into the MontaukOS kernel (see kernel/src/Libraries/flanterm). The files are taken unmodified from the flanterm project. @@ -410,7 +467,7 @@ License: BSD-2-Clause license (https://raw.githubusercontent.com/Mintsuki/Flante ================================================================================ -16. GNU Compiler Collection (GCC) and GNU Binutils (Montauk SDK) +18. GNU Compiler Collection (GCC) and GNU Binutils (Montauk SDK) ================================================================================ The MontaukOS SDK includes native ports of GCC 14.2.0 and GNU Binutils 2.43.1 at 0:/sdk/. The GCC tools include gcc, g++, cpp, cc1, and cc1plus. The Binutils diff --git a/programs/data/licenses/Intel-iwlwifi-firmware.txt b/programs/data/licenses/Intel-iwlwifi-firmware.txt new file mode 100644 index 0000000..2f19654 --- /dev/null +++ b/programs/data/licenses/Intel-iwlwifi-firmware.txt @@ -0,0 +1,39 @@ +Copyright (c) 2006-2015, Intel Corporation. +All rights reserved. + +Redistribution. Redistribution and use in binary form, without +modification, are permitted provided that the following conditions are +met: + +* Redistributions must reproduce the above copyright notice and the + following disclaimer in the documentation and/or other materials + provided with the distribution. +* Neither the name of Intel Corporation nor the names of its suppliers + may be used to endorse or promote products derived from this software + without specific prior written permission. +* No reverse engineering, decompilation, or disassembly of this software + is permitted. + +Limited patent license. Intel Corporation grants a world-wide, +royalty-free, non-exclusive license under patents it now or hereafter +owns or controls to make, have made, use, import, offer to sell and +sell ("Utilize") this software, but solely to the extent that any +such patent is necessary to Utilize the software alone, or in +combination with an operating system licensed under an approved Open +Source license as listed by the Open Source Initiative at +http://opensource.org/licenses. The patent license shall not apply to +any other combinations which include this software. No hardware per +se is licensed hereunder. + +DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/programs/include/libc/inttypes.h b/programs/include/libc/inttypes.h index e2a01b5..73e4502 100644 --- a/programs/include/libc/inttypes.h +++ b/programs/include/libc/inttypes.h @@ -34,8 +34,11 @@ #define PRIxPTR "lx" #define PRIXPTR "lX" #define PRIdMAX "ld" +#define PRIiMAX "li" #define PRIuMAX "lu" +#define PRIoMAX "lo" #define PRIxMAX "lx" +#define PRIXMAX "lX" #define SCNd8 "d" #define SCNd16 "d" @@ -56,5 +59,10 @@ #define SCNdPTR "ld" #define SCNuPTR "lu" #define SCNxPTR "lx" +#define SCNdMAX "ld" +#define SCNiMAX "li" +#define SCNuMAX "lu" +#define SCNoMAX "lo" +#define SCNxMAX "lx" #endif /* _LIBC_INTTYPES_H */ diff --git a/programs/include/libc/montauk.h b/programs/include/libc/montauk.h index 7b762cb..fd4d607 100644 --- a/programs/include/libc/montauk.h +++ b/programs/include/libc/montauk.h @@ -427,7 +427,7 @@ static inline int mtk_getargs(char *buf, unsigned long max_len) { } static inline int mtk_getexecpath(char *buf, unsigned long maxLen) { - return (int)mtk_syscall2(MTK_SYS_GETEXECPATH, (long)buf, (long)maxLen); + return (int)_mtk_syscall2(MTK_SYS_GETEXECPATH, (long)buf, (long)maxLen); } static inline int mtk_chdir(const char *path) { diff --git a/programs/include/libc/stdlib.h b/programs/include/libc/stdlib.h index 3c8f5d1..65d1e28 100644 --- a/programs/include/libc/stdlib.h +++ b/programs/include/libc/stdlib.h @@ -39,8 +39,8 @@ double atof(const char *s); int abs(int j); long labs(long j); -void exit(int status); -void abort(void); +void exit(int status) __attribute__((noreturn)); +void abort(void) __attribute__((noreturn)); int atexit(void (*func)(void)); char *getenv(const char *name); diff --git a/programs/lib/libc/crt/crt1.c b/programs/lib/libc/crt/crt1.c index 0a87d62..b1b6014 100644 --- a/programs/lib/libc/crt/crt1.c +++ b/programs/lib/libc/crt/crt1.c @@ -91,6 +91,14 @@ void _start(void) { argbuf[len] = '\0'; + /* Split on spaces, honouring '...' and "..." so an argument can + contain them: `git commit -m "two words"` has to reach main() + as two arguments, not three. The quotes are removed, and the + token is rewritten in place -- the unquoted form is never + longer than the quoted one, so it always fits. Quotes are the + only metacharacter: there is no escaping and no substitution, + which is deliberate. The kernel hands over one flat string + (SYS_GETARGS) and this is a tokenizer, not a shell. */ char* p = argbuf; while (*p != '\0' && argc < 255) { while (*p == ' ') { @@ -101,15 +109,27 @@ void _start(void) { break; } - argv[argc++] = p; + char* out = p; + argv[argc++] = out; - while (*p != '\0' && *p != ' ') { + char quote = 0; + while (*p != '\0' && (quote != 0 || *p != ' ')) { + if (quote == 0 && (*p == '"' || *p == '\'')) { + quote = *p++; + } else if (quote != 0 && *p == quote) { + quote = 0; + p++; + } else { + *out++ = *p++; + } + } + + /* Step over the separator before terminating: the write + below lands on the byte p is about to leave behind. */ + if (*p != '\0') { p++; } - - if (*p != '\0') { - *p++ = '\0'; - } + *out = '\0'; } } diff --git a/programs/lib/libc/crt1.o b/programs/lib/libc/crt1.o index ef5b27c..762ab27 100644 Binary files a/programs/lib/libc/crt1.o and b/programs/lib/libc/crt1.o differ diff --git a/programs/lib/libc/libc.c b/programs/lib/libc/libc.c index 94f5255..6450081 100644 --- a/programs/lib/libc/libc.c +++ b/programs/lib/libc/libc.c @@ -2081,8 +2081,35 @@ int open(const char *path, int flags, ...) { return h; } +/* + * The standard descriptors are the terminal, NOT file handles. + * + * 0/1/2 are not handles the kernel ever issued -- SYS_OPEN allocates from its + * own space and would have to return 0 for these to line up, which it does + * not. Passing them to SYS_READ/SYS_FWRITE addresses whatever handle happens + * to hold that number, or fails: before this, every write(2, ...) was + * silently discarded, so a POSIX program that reports errors with write() + * rather than fprintf() printed nothing at all. stdio already routes std + * streams to SYS_PUTCHAR (see fwrite/fprintf); these do the same, so the two + * paths agree. + */ int read(int fd, void *buf, size_t count) { if (buf == NULL) return -1; + + if (fd == STDIN_FILENO) { + /* Line-oriented, like the terminal itself: return as soon as a + line is complete rather than blocking for the full count. */ + char *dst = (char *)buf; + size_t i = 0; + while (i < count) { + int c = fgetc(stdin); + if (c == EOF) break; + dst[i++] = (char)c; + if (c == '\n') break; + } + return (int)i; + } + unsigned long pos = (fd >= 0 && fd < _FD_POS_MAX) ? _fd_pos[fd] : 0; int ret = (int)_zos_syscall4(SYS_READ, (long)fd, (long)buf, (long)pos, (long)count); if (ret > 0 && fd >= 0 && fd < _FD_POS_MAX) @@ -2092,6 +2119,14 @@ int read(int fd, void *buf, size_t count) { int write(int fd, const void *buf, size_t count) { if (buf == NULL) return -1; + + if (fd == STDOUT_FILENO || fd == STDERR_FILENO) { + const char *src = (const char *)buf; + for (size_t i = 0; i < count; i++) + _zos_syscall1(SYS_PUTCHAR, (long)(unsigned char)src[i]); + return (int)count; + } + unsigned long pos = (fd >= 0 && fd < _FD_POS_MAX) ? _fd_pos[fd] : 0; int ret = (int)_zos_syscall4(SYS_FWRITE, (long)fd, (long)buf, (long)pos, (long)count); if (ret > 0 && fd >= 0 && fd < _FD_POS_MAX) diff --git a/programs/lib/libc/obj/libc.o b/programs/lib/libc/obj/libc.o index 63b668a..7677457 100644 Binary files a/programs/lib/libc/obj/libc.o and b/programs/lib/libc/obj/libc.o differ diff --git a/template/sysroot/include/libc/inttypes.h b/template/sysroot/include/libc/inttypes.h index e2a01b5..73e4502 100644 --- a/template/sysroot/include/libc/inttypes.h +++ b/template/sysroot/include/libc/inttypes.h @@ -34,8 +34,11 @@ #define PRIxPTR "lx" #define PRIXPTR "lX" #define PRIdMAX "ld" +#define PRIiMAX "li" #define PRIuMAX "lu" +#define PRIoMAX "lo" #define PRIxMAX "lx" +#define PRIXMAX "lX" #define SCNd8 "d" #define SCNd16 "d" @@ -56,5 +59,10 @@ #define SCNdPTR "ld" #define SCNuPTR "lu" #define SCNxPTR "lx" +#define SCNdMAX "ld" +#define SCNiMAX "li" +#define SCNuMAX "lu" +#define SCNoMAX "lo" +#define SCNxMAX "lx" #endif /* _LIBC_INTTYPES_H */ diff --git a/template/sysroot/include/libc/montauk.h b/template/sysroot/include/libc/montauk.h index a58800d..66b95ca 100644 --- a/template/sysroot/include/libc/montauk.h +++ b/template/sysroot/include/libc/montauk.h @@ -426,7 +426,7 @@ static inline int mtk_getargs(char *buf, unsigned long max_len) { } static inline int mtk_getexecpath(char *buf, unsigned long maxLen) { - return (int)mtk_syscall2(MTK_SYS_GETEXECPATH, (long)buf, (long)maxLen); + return (int)_mtk_syscall2(MTK_SYS_GETEXECPATH, (long)buf, (long)maxLen); } static inline int mtk_chdir(const char *path) { diff --git a/template/sysroot/include/libc/stdlib.h b/template/sysroot/include/libc/stdlib.h index 3c8f5d1..65d1e28 100644 --- a/template/sysroot/include/libc/stdlib.h +++ b/template/sysroot/include/libc/stdlib.h @@ -39,8 +39,8 @@ double atof(const char *s); int abs(int j); long labs(long j); -void exit(int status); -void abort(void); +void exit(int status) __attribute__((noreturn)); +void abort(void) __attribute__((noreturn)); int atexit(void (*func)(void)); char *getenv(const char *name);