Merge pull request #2324 from AchrafReyani/fix/libc-getcwd-application-heap
fix(libc): allocate getcwd's buffer from the application heap
This commit is contained in:
commit
ee364bf05f
|
|
@ -24,7 +24,7 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
#include "prx/libc/include/General.hpp"
|
||||
#include "prx/libc/include/GuestHeap.hpp"
|
||||
#include "prx/libc/include/ApplicationHeap.hpp"
|
||||
|
||||
namespace {
|
||||
// Guest prefixes (without leading slashes) mapped to host directories, e.g. save-data mount points:
|
||||
|
|
@ -304,7 +304,8 @@ extern "C" char* APS5_VABI getcwd_nid_postfix(char* buffer, std::size_t size) {
|
|||
const auto path = relative == "." ? std::string("/") : "/" + relative.generic_string();
|
||||
const auto required = path.size() + 1;
|
||||
if ((buffer || size) && size < required) { errno = 34; return nullptr; }
|
||||
if (!buffer) buffer = static_cast<char*>(GuestHeap::GuestHeapAllocate_nid_postfix(size ? size : required));
|
||||
if (!buffer) buffer = static_cast<char*>(ApplicationHeapAllocate_nid_no_patch(size ? size : required));
|
||||
if (!buffer) { errno = 12; return nullptr; }
|
||||
std::memcpy(buffer, path.c_str(), required);
|
||||
return buffer;
|
||||
} catch (const std::bad_alloc&) { errno = 12; return nullptr; }
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ void APS5_VABI _ZdlPvmSt11align_val_t_nid_postfix(void*, std::size_t, std::size_
|
|||
void* ApplicationHeapRealign_nid_no_patch(void*, std::size_t, std::size_t);
|
||||
char* APS5_VABI strdup_nid_postfix(const char*);
|
||||
char* APS5_VABI strndup_nid_postfix(const char*, std::size_t);
|
||||
char* APS5_VABI getcwd_nid_postfix(char*, std::size_t);
|
||||
int* APS5_VABI __error_nid_postfix();
|
||||
int APS5_VABI atexit_nid_postfix(void (APS5_VABI*)());
|
||||
}
|
||||
|
|
@ -260,6 +261,12 @@ int main(int argc, char** argv) {
|
|||
copy = strndup_nid_postfix(text, 5);
|
||||
require(lastSize == 6 && std::strcmp(copy, "guest") == 0);
|
||||
ApplicationHeapFree_nid_no_patch(copy);
|
||||
char* directory = getcwd_nid_postfix(nullptr, 0);
|
||||
require(directory == reinterpret_cast<char*>(storage.data()) && directory[0] == '/' && lastSize == std::strlen(directory) + 1);
|
||||
ApplicationHeapFree_nid_no_patch(directory);
|
||||
directory = getcwd_nid_postfix(nullptr, 200);
|
||||
require(directory == reinterpret_cast<char*>(storage.data()) && lastSize == 200);
|
||||
ApplicationHeapFree_nid_no_patch(directory);
|
||||
fail = true;
|
||||
*__error_nid_postfix() = 0;
|
||||
require(strdup_nid_postfix(text) == nullptr && *__error_nid_postfix() == 12);
|
||||
|
|
@ -267,5 +274,7 @@ int main(int argc, char** argv) {
|
|||
require(strdup_nid_postfix("") == nullptr && *__error_nid_postfix() == 12);
|
||||
*__error_nid_postfix() = 0;
|
||||
require(strndup_nid_postfix(text, 5) == nullptr && *__error_nid_postfix() == 12);
|
||||
*__error_nid_postfix() = 0;
|
||||
require(getcwd_nid_postfix(nullptr, 0) == nullptr && *__error_nid_postfix() == 12);
|
||||
fail = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "prx/libc/include/ApplicationHeap.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
#include "prx/libc/include/GuestHeap.hpp"
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
|
@ -10,7 +12,15 @@ char* APS5_VABI getcwd_nid_postfix(char*, std::size_t);
|
|||
int* APS5_VABI __error_nid_postfix();
|
||||
}
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
static int allocations = 0;
|
||||
static int releases = 0;
|
||||
static void* APS5_VABI Allocate(std::size_t bytes) { ++allocations; return GuestHeap::GuestHeapAllocate_nid_postfix(bytes); }
|
||||
static void APS5_VABI Release(void* pointer) { ++releases; GuestHeap::GuestHeapFree_nid_postfix(pointer); }
|
||||
static void* APS5_VABI Unused() { std::abort(); }
|
||||
int main() {
|
||||
const std::array<void*, 10> api{reinterpret_cast<void*>(&Allocate), reinterpret_cast<void*>(&Release), reinterpret_cast<void*>(&Unused),
|
||||
reinterpret_cast<void*>(&Unused), reinterpret_cast<void*>(&Unused), reinterpret_cast<void*>(&Unused), reinterpret_cast<void*>(&Unused)};
|
||||
ApplicationHeapRegister_nid_no_patch(api.data());
|
||||
const auto host = std::filesystem::canonical(std::filesystem::current_path());
|
||||
char path[1024];
|
||||
Require(getcwd_nid_postfix(path, sizeof(path)) == path && std::strcmp(path, "/") == 0);
|
||||
|
|
@ -28,8 +38,9 @@ int main() {
|
|||
Require(std::strcmp(tiny, "xyz") == 0);
|
||||
Require(getcwd_nid_postfix(path, 0) == nullptr && *__error_nid_postfix() == 22);
|
||||
char* allocated = getcwd_nid_postfix(nullptr, 0);
|
||||
Require(allocated && std::strcmp(allocated, path) == 0);
|
||||
GuestHeap::GuestHeapFree_nid_postfix(allocated);
|
||||
Require(allocated && std::strcmp(allocated, path) == 0 && allocations == 1);
|
||||
ApplicationHeapFree_nid_no_patch(allocated);
|
||||
Require(releases == 1);
|
||||
Require(chdir_nid_postfix("sample.txt") == -1 && *__error_nid_postfix() == 20);
|
||||
Require(chdir_nid_postfix("missing") == -1 && *__error_nid_postfix() == 2);
|
||||
Require(chdir_nid_postfix("..") == 0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue