mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-03 11:15:20 +02:00
GetStringErrorMsg had the strerror_r result test backwards. The XSI variant returns 0 on success, so every successful lookup returned "Unknown error"; and under glibc with _GNU_SOURCE the GNU variant is selected instead, which returns the message by pointer and typically leaves the buffer untouched, so it returned an empty string. Either way GetLastErrorMsg() was useless on Linux, Android and macOS. Pick the right handling by overload resolution rather than guessing which signature we got. KeyMap's "no gamepad button mapped to cancel" fallback pushed into confirmKeys instead of cancelKeys - and pushed the confirm button. So unmapping cancel left no gamepad way out of menus, and duplicated an entry in the confirm list. ControlMapper::AddListener mutated listeners_ without taking mutex_, while RemoveListener takes it and the input thread iterates the vector under it. Opening a screen while an axis is moving could reallocate it mid-iteration. The comment about piggybacking on a screenmanager mutex was stale - there isn't one. Config's two std::stof calls on PostShaderSetting values ran on user-editable ini text with no try/catch, so a malformed entry called std::terminate during startup config load. Use the same checked sscanf that LoadGameConfig already uses. (CmdLine.cpp and Compatibility.cpp have the same pattern; not touched here.) The screenshot downscale path leaked its final buffer on every downscaled shot, which savestate thumbnails hit on every save at 3x and above. HandleUploadPost is registered unconditionally, so closing the Upload screen left an unauthenticated file-write endpoint live for as long as anything else kept the server up. Check the flag in the handler. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DCPmm7FoQUoqrbMdhfqhQ2
78 lines
2.4 KiB
C++
78 lines
2.4 KiB
C++
// Copyright (C) 2003 Dolphin Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
// http://code.google.com/p/dolphin-emu/
|
|
|
|
#include <cstring>
|
|
#include <string>
|
|
|
|
#include "Common/Data/Encoding/Utf8.h"
|
|
#include "SysError.h"
|
|
|
|
#ifdef _WIN32
|
|
#include "CommonWindows.h"
|
|
#else
|
|
#include <errno.h>
|
|
|
|
// See the comment at the call site.
|
|
static std::string StrErrorResult(char *result, const char *buf) {
|
|
return result ? result : "Unknown error";
|
|
}
|
|
|
|
static std::string StrErrorResult(int result, const char *buf) {
|
|
return result == 0 ? buf : "Unknown error";
|
|
}
|
|
#endif
|
|
|
|
// Generic function to get last error message.
|
|
// Call directly after the command or use the error num.
|
|
// This function might change the error code.
|
|
std::string GetLastErrorMsg() {
|
|
#ifdef _WIN32
|
|
return GetStringErrorMsg(GetLastError());
|
|
#else
|
|
return GetStringErrorMsg(errno);
|
|
#endif
|
|
}
|
|
|
|
std::string GetStringErrorMsg(int errCode) {
|
|
static const size_t buff_size = 1023;
|
|
|
|
#ifdef _WIN32
|
|
wchar_t err_strw[buff_size] = {};
|
|
|
|
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errCode,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
err_strw, buff_size, NULL);
|
|
|
|
char err_str[buff_size] = {};
|
|
snprintf(err_str, buff_size, "%s", ConvertWStringToUTF8(err_strw).c_str());
|
|
|
|
std::string err_string = err_str;
|
|
// Trim the trailing line breaks which can mess up the logs
|
|
while (!err_string.empty() && (err_string.back() == '\n' || err_string.back() == '\r')) {
|
|
err_string.pop_back();
|
|
}
|
|
return err_string;
|
|
#else
|
|
char err_str[buff_size] = {};
|
|
|
|
// strerror_r has two incompatible signatures: the XSI one returns int (0 on success and the
|
|
// message is in the buffer), the GNU one returns a char * that may not be the buffer at all.
|
|
// Which one we get depends on _GNU_SOURCE, so let overload resolution sort it out.
|
|
return StrErrorResult(strerror_r(errCode, err_str, buff_size), err_str);
|
|
#endif
|
|
}
|