WIP: libc.obj: implement gets_s #438

Draft
Egor00f wants to merge 4 commits from Egor00f/kolibrios:add-`gets_s` into main
Collaborator

Changes

new functions:

  • gets_s

gets is defined as

#define gets(str) gets_s(str, STDIO_MAX_MEM)

and

char* _gets(char* str)
{
    return gets(str);
}

gets DIDN'T BECOME SAFE

## Changes ### new functions: + `gets_s` ### `gets` is defined as ```c #define gets(str) gets_s(str, STDIO_MAX_MEM) ``` and ```c char* _gets(char* str) { return gets(str); } ``` `gets` DIDN'T BECOME SAFE
Egor00f force-pushed add-`gets_s` from a80783a903 to d7adcd1caa 2026-05-02 09:50:05 +00:00 Compare
Egor00f force-pushed add-`gets_s` from d7adcd1caa to c3d1506c18 2026-05-19 06:18:00 +00:00 Compare
Egor00f force-pushed add-`gets_s` from c3d1506c18 to f814987094 2026-05-19 06:22:41 +00:00 Compare
Doczom approved these changes 2026-05-19 06:51:30 +00:00
Burer approved these changes 2026-05-19 11:15:24 +00:00
Dismissed
Burer left a comment
Owner

Problems I see:

  • 🟥 stdio.h's gets macro references STDIO_MAX_MEM.
    Fixed: stdio.h now #include <limits.h>, so STDIO_MAX_MEM is available wherever <stdio.h> is; the plain #include <stdio.h>; gets(buf); case compiles again.

  • 🟥 C89/C99 conformance & portability — only the ABI half is fixed.
    ABI part fixed: gets is exported again (libc.def keeps gets+gets_s; EXPORTS[] = { "gets", &_gets }), so pre-built binaries link.
    Still broken at C-source level: stdio.h has only #define gets(str) gets_s(...) and no real char *gets(char*) declaration (the function is the internal _gets, which user code can't portably name). The standard (C89 §4.1.6 / C99 §7.1.4) requires the actual function to stay reachable when masked by a macro. So &gets, (gets)(buf), #undef gets; gets(...), and extern char *gets(char*); redeclarations still fail to compile. This still hurts porting C89/C99 software to KolibriOS — the original concern.
    Fix: declare a real prototype in stdio.hDLLAPI char* gets(char* str); — and name the function gets (drop the _gets indirection); keep the macro alongside if safe-by-default is wanted. The _gets wrapper is exactly what keeps the source-level breakage.

  • 🟨 ABI note — resolved: gets symbol kept (via &_gets), pre-built binaries no longer break.

  • 🟨 The gets compat macro preserves the old unsafe behavior.
    gets(buf)gets_s(buf, STDIO_MAX_MEM=4096) regardless of the real buffer size — no added safety for existing callers; benefit exists only when code explicitly calls gets_s(buf, sizeof buf). Acceptable as a migration shim, but state it so it isn't mistaken for a fix of existing call sites.

  • 🟨 Not full C11 Annex K gets_s.
    Improved (now clears str[0] on EINVAL/EIO), but still no constraint handler. Acceptable for a minimal libc — it's "gets_s-like"; note it in the PR description.

  • 🟨 gets.c dropped its own #include <limits.h> while still using INT_MAX.
    n > (size_t)INT_MAX now relies on INT_MAX arriving transitively via stdio.h → limits.h. Include-what-you-use regression — re-add #include <limits.h> to gets.c; it depends on it directly.

  • 🟨 New sample gets_s_test.c is not wired into the build.
    Unlike abort_test/atexit_test in PR 340, it isn't added to Makefile/build_all.sh, so it won't be auto-built/tested. Also trailing whitespace on return 0;.

Problems I see: - [x] **🟥 `stdio.h`'s `gets` macro references `STDIO_MAX_MEM`.** Fixed: `stdio.h` now `#include <limits.h>`, so `STDIO_MAX_MEM` is available wherever `<stdio.h>` is; the plain `#include <stdio.h>; gets(buf);` case compiles again. - [ ] **🟥 C89/C99 conformance & portability — only the ABI half is fixed.** ABI part fixed: `gets` is exported again (`libc.def` keeps `gets`+`gets_s`; `EXPORTS[] = { "gets", &_gets }`), so pre-built binaries link. Still broken at C-source level: `stdio.h` has only `#define gets(str) gets_s(...)` and **no real `char *gets(char*)` declaration** (the function is the internal `_gets`, which user code can't portably name). The standard (C89 §4.1.6 / C99 §7.1.4) requires the actual function to stay reachable when masked by a macro. So `&gets`, `(gets)(buf)`, `#undef gets; gets(...)`, and `extern char *gets(char*);` redeclarations still fail to compile. This still hurts porting C89/C99 software to KolibriOS — the original concern. Fix: declare a real prototype in `stdio.h` — `DLLAPI char* gets(char* str);` — and name the function `gets` (drop the `_gets` indirection); keep the macro alongside if safe-by-default is wanted. The `_gets` wrapper is exactly what keeps the source-level breakage. - [x] **🟨 ABI note** — resolved: `gets` symbol kept (via `&_gets`), pre-built binaries no longer break. - [ ] **🟨 The `gets` compat macro preserves the old unsafe behavior.** `gets(buf)` → `gets_s(buf, STDIO_MAX_MEM=4096)` regardless of the real buffer size — no added safety for existing callers; benefit exists only when code explicitly calls `gets_s(buf, sizeof buf)`. Acceptable as a migration shim, but state it so it isn't mistaken for a fix of existing call sites. - [ ] **🟨 Not full C11 Annex K `gets_s`.** Improved (now clears `str[0]` on `EINVAL`/`EIO`), but still no constraint handler. Acceptable for a minimal libc — it's "gets_s-like"; note it in the PR description. - [ ] **🟨 `gets.c` dropped its own `#include <limits.h>` while still using `INT_MAX`.** `n > (size_t)INT_MAX` now relies on `INT_MAX` arriving transitively via `stdio.h → limits.h`. Include-what-you-use regression — re-add `#include <limits.h>` to `gets.c`; it depends on it directly. - [ ] **🟨 New sample `gets_s_test.c` is not wired into the build.** Unlike `abort_test`/`atexit_test` in PR 340, it isn't added to `Makefile`/`build_all.sh`, so it won't be auto-built/tested. Also trailing whitespace on ` return 0; `.
Burer requested changes 2026-05-19 11:15:34 +00:00
Burer left a comment
Owner

See comment above.

See comment above.
Egor00f requested review from Doczom 2026-05-19 16:42:19 +00:00
Egor00f requested review from Burer 2026-05-19 16:42:32 +00:00
Egor00f added 3 commits 2026-05-19 17:13:59 +00:00
return back gets as function && update gets_s && include limits.h in stdio.h && add gets_s test
Build system / Check kernel codestyle (pull_request) Successful in 25s
Build system / Build (pull_request) Successful in 14m54s
035ed0790b
add
```c
str[0] = '\0';
````
on error in `gets_s`
Egor00f force-pushed add-`gets_s` from 810204d56f to 035ed0790b 2026-05-19 17:13:59 +00:00 Compare
Egor00f added 1 commit 2026-05-19 17:17:11 +00:00
add test to tests build
Build system / Check kernel codestyle (pull_request) Successful in 32s
Build system / Build (pull_request) Successful in 14m49s
66da18501a
Egor00f marked the pull request as work in progress 2026-05-20 04:51:06 +00:00
Egor00f added the CCategory/Libraries
Priority
Low
labels 2026-06-08 17:01:58 +00:00
Some checks are pending
Build system / Check kernel codestyle (pull_request) Successful in 32s
Build system / Build (pull_request) Successful in 14m49s
Test PR / Build *
Required
This pull request has changes conflicting with the target branch.
  • programs/develop/ktcc/libc.obj/samples/Makefile
  • programs/develop/ktcc/libc.obj/samples/build_all.sh
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u http://git.kolibrios.org/Egor00f/kolibrios add-`gets_s`:Egor00f-add-`gets_s`
git checkout Egor00f-add-`gets_s`
Sign in to join this conversation.
No Reviewers
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KolibriOS/kolibrios#438