Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion core/libs/prx/libc/src/StringExtensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ long long APS5_VABI strtonum_nid_postfix(const char* text, long long minimum, lo
}

char* APS5_VABI basename_r_nid_postfix(const char* path, char* buffer) {
if (buffer == nullptr) throw std::invalid_argument("basename_r: null buffer");
if (buffer == nullptr) {
errno = 22;
return nullptr;
}
std::string_view name = path && *path ? path : ".";
while (name.size() > 1 && name.back() == '/') name.remove_suffix(1);
if (name != "/") {
Expand Down
2 changes: 2 additions & 0 deletions core/libs/tests/GuestStrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ int main() {
Require(basename_r_nid_postfix(("/a/" + longest).c_str(), baseBuffer) == baseBuffer && std::strlen(baseBuffer) == 1023);
*__error_nid_postfix() = 0;
Require(basename_r_nid_postfix(longName.c_str(), baseBuffer) == nullptr && *__error_nid_postfix() == 63);
*__error_nid_postfix() = 0;
Require(basename_r_nid_postfix(path, nullptr) == nullptr && *__error_nid_postfix() == 22);
const unsigned char loopbackBytes[4] = {127, 0, 0, 1};
unsigned int loopback;
std::memcpy(&loopback, loopbackBytes, sizeof(loopback));
Expand Down
1 change: 1 addition & 0 deletions docs/dev/debt/libc.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
- [getw and putw](../../../core/libs/prx/libc/src/BinaryWordIo.cpp) (libc) follow FreeBSD 11.4 [getw.c](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/stdio/getw.c) and [putw.c](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/stdio/putw.c): one 32-bit little-endian word, `getw` returns -1 for EOF or an error, and `putw` returns 0 on success or -1 on error while holding the stream lock. They use the existing host-backed streams, so buffering and error timing follow the host CRT. Null streams throw and closed streams return -1 with `EBADF`, as existing byte I/O does. Console behavior is unverified.
- [vsnwprintf_s](../../../core/libs/prx/libc/src/FormattingWide.cpp) (libc) - `va_list` counterpart of `snwprintf_s` (C11 K.3.9.1.3): truncates to the buffer and returns the full length, with the same constraints and argument checks
- [strndup and strdup](../../../core/libs/prx/libc/src/AllocatingStrings.cpp) (libc) return null with `errno` set to `EINVAL` (22) when `source` is null, preventing a host segfault on invalid guest input. POSIX.1-2008 and FreeBSD 11.4 libc leave `strndup(NULL)` and `strdup(NULL)` undefined (faulting); exact console behavior on hardware is unverified.
- [basename_r](../../../core/libs/prx/libc/src/StringExtensions.cpp) (libc) returns null with `errno` set to `EINVAL` (22) when `buffer` is null, following POSIX reentrant conventions and preventing an unhandled crash on invalid guest input. Exact console behavior on hardware is unverified.
- [snprintf_s and vsnprintf_s](../../../core/libs/prx/libc/src/Formatting.cpp) (libc) - follow C11 K.3.5.3.5 and K.3.5.3.12 with `RSIZE_MAX` assumed to be `SIZE_MAX >> 1`, as `snwprintf_s` does: a null buffer or format, `size` of 0 or above `RSIZE_MAX`, any `%n` and a null `%s`, `%ls` or `%S` argument return a negative value and set `buffer[0]` to zero when the buffer and size allow it; otherwise the output is truncated to the buffer and the full length is returned. A violation only returns: the constraint handler is not invoked, and the console's error value is unverified. Not confirmed on a PS5 title
- [vsscanf_s](../../../core/libs/prx/libc/src/Formatting.cpp) (libc) - returns the count of items converted before an undersized `%s`/`%c`/`%[` destination (0 when it is the first), not EOF. Not confirmed on a PS5 title
- [localeconv](../../../core/libs/prx/libc/src/LocaleSupport.cpp) (libc, re-exported by libSceAmpr) - the 0x90-byte Dinkumware struct (empty monetary strings, `CHAR_MAX` for the 14 `char` fields, `decimal_point` ".", `_False`/`_True` "false"/"true") is read from the `libc.prx` that Astro's Playroom ships. It is a fixed C-locale table: whether the console changes it with `setlocale` is not known, and `_Frac_grouping`, `_Frac_sep`, `_No`, `_Yes` are empty strings as in that dump
Expand Down
Loading