Optimizations & Fixes

This commit is contained in:
TheBrokenRail 2022-06-03 22:25:22 -04:00
parent 0dd0706f52
commit 211bf265ff
9 changed files with 205 additions and 104 deletions

View File

@ -254,6 +254,7 @@ void bootstrap(int argc, char *argv[]) {
} }
// Fix MCPI Dependencies // Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
{ {
// Log // Log
DEBUG("Patching ELF Dependencies..."); DEBUG("Patching ELF Dependencies...");
@ -273,7 +274,7 @@ void bootstrap(int argc, char *argv[]) {
#endif #endif
// Patch // Patch
patch_mcpi_elf_dependencies(resolved_path, linker); patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
// Free Linker Path // Free Linker Path
if (linker != NULL) { if (linker != NULL) {
@ -281,7 +282,7 @@ void bootstrap(int argc, char *argv[]) {
} }
// Verify // Verify
if (!starts_with(getenv("MCPI_EXECUTABLE_PATH"), "/tmp")) { if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
IMPOSSIBLE(); IMPOSSIBLE();
} }
} }
@ -391,7 +392,7 @@ void bootstrap(int argc, char *argv[]) {
new_args[argv_start + argc] = NULL; new_args[argv_start + argc] = NULL;
// Set Executable Argument // Set Executable Argument
new_args[argv_start] = getenv("MCPI_EXECUTABLE_PATH"); new_args[argv_start] = new_mcpi_exe_path;
// Non-ARM Systems Need QEMU // Non-ARM Systems Need QEMU
#ifndef __ARM_ARCH #ifndef __ARM_ARCH

View File

@ -8,23 +8,21 @@
#include "patchelf.h" #include "patchelf.h"
// Duplicate MCPI Executable Into /tmp // Duplicate MCPI Executable Into /tmp
#define TMP_DIR "/tmp/.minecraft-pi-patched" static void duplicate_mcpi_executable(const char *original_path, char *new_path) {
static void duplicate_mcpi_executable(const char *original_path) {
// Ensure Temporary Directory // Ensure Temporary Directory
{ {
// Check If It Exists // Check If It Exists
struct stat tmp_stat; struct stat tmp_stat;
int exists = stat(TMP_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode); int exists = stat(MCPI_PATCHED_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
if (!exists) { if (!exists) {
// Doesn't Exist // Doesn't Exist
if (mkdir(TMP_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) { if (mkdir(MCPI_PATCHED_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
ERR("Unable To Create Temporary Folder: %s", strerror(errno)); ERR("Unable To Create Temporary Folder: %s", strerror(errno));
} }
} }
} }
// Generate New File // Generate New File
char new_path[] = TMP_DIR "/XXXXXX";
int new_file_fd = mkstemp(new_path); int new_file_fd = mkstemp(new_path);
if (new_file_fd == -1) { if (new_file_fd == -1) {
ERR("Unable To Create Temporary File: %s", strerror(errno)); ERR("Unable To Create Temporary File: %s", strerror(errno));
@ -33,7 +31,6 @@ static void duplicate_mcpi_executable(const char *original_path) {
if (new_file == NULL) { if (new_file == NULL) {
ERR("Unable To Open Temporary File: %s", strerror(errno)); ERR("Unable To Open Temporary File: %s", strerror(errno));
} }
set_and_print_env("MCPI_EXECUTABLE_PATH", new_path);
// Copy Original File // Copy Original File
{ {
@ -76,7 +73,7 @@ static void duplicate_mcpi_executable(const char *original_path) {
"--remove-needed", "libX11.so.6", \ "--remove-needed", "libX11.so.6", \
"--remove-needed", "libEGL.so", \ "--remove-needed", "libEGL.so", \
"--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \ "--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \
exe, \ new_path, \
NULL \ NULL \
}; \ }; \
int _macro_return_code = 0; \ int _macro_return_code = 0; \
@ -86,12 +83,9 @@ static void duplicate_mcpi_executable(const char *original_path) {
} \ } \
_macro_return_code; \ _macro_return_code; \
}) })
void patch_mcpi_elf_dependencies(const char *original_path, const char *linker) { void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker) {
// Duplicate MCPI executable into /tmp so it can be modified. // Duplicate MCPI executable into /tmp so it can be modified.
duplicate_mcpi_executable(original_path); duplicate_mcpi_executable(original_path, new_path);
// Get Path
char *exe = getenv("MCPI_EXECUTABLE_PATH");
// Run patchelf // Run patchelf
int return_code; int return_code;
@ -107,8 +101,8 @@ void patch_mcpi_elf_dependencies(const char *original_path, const char *linker)
} }
// Fix Permissions // Fix Permissions
if (chmod(exe, S_IRUSR | S_IXUSR) != 0) { if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) {
ERR("Unable To Set File Permissions: %s: %s", exe, strerror(errno)); ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno));
} }
} }

View File

@ -4,7 +4,9 @@
extern "C" { extern "C" {
#endif #endif
void patch_mcpi_elf_dependencies(const char *original_path, const char *linker); #define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker);
char *patch_get_interpreter(const char *file); char *patch_get_interpreter(const char *file);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -6,6 +6,7 @@ extern "C" {
#define GL_FALSE 0 #define GL_FALSE 0
#define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ARRAY_BUFFER 0x8892
#define GL_TEXTURE_BINDING_2D 0x8069 #define GL_TEXTURE_BINDING_2D 0x8069
#define GL_UNSIGNED_BYTE 0x1401 #define GL_UNSIGNED_BYTE 0x1401
#define GL_FLOAT 0x1406 #define GL_FLOAT 0x1406

View File

@ -39,6 +39,21 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
#define CALL_GL_POINTER(unique_id, name) \ #define CALL_GL_POINTER(unique_id, name) \
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) { \ CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) { \
/* Check */ \
static int last_set = 0; \
static GLint last_size; \
static GLenum last_type; \
static GLsizei last_stride; \
static const void *last_pointer; \
if (last_set && last_size == size && last_type == type && last_stride == stride && last_pointer == pointer) { \
return; \
} else { \
last_set = 1; \
last_size = size; \
last_type = type; \
last_stride = stride; \
last_pointer = pointer; \
} \
/* Lock Proxy */ \ /* Lock Proxy */ \
start_proxy_call(); \ start_proxy_call(); \
\ \
@ -107,6 +122,31 @@ CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) {
#endif #endif
} }
// Track Bindings
#if defined(MEDIA_LAYER_PROXY_SERVER)
static GLuint bound_buffer = 0;
static GLuint bound_texture = 0;
static unsigned char vertex_array_enabled = 0;
static unsigned char color_array_enabled = 0;
static unsigned char tex_coord_array_enabled = 0;
static unsigned char *get_array_enabled_pointer(GLenum array) {
switch (array) {
case GL_VERTEX_ARRAY: {
return &vertex_array_enabled;
}
case GL_COLOR_ARRAY: {
return &color_array_enabled;
}
case GL_TEXTURE_COORD_ARRAY: {
return &tex_coord_array_enabled;
}
default: {
ERR("Unsupported Array Pointer: %i", array);
}
}
}
#endif
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) { CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy // Lock Proxy
@ -116,6 +156,13 @@ CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
write_int((uint32_t) mode); write_int((uint32_t) mode);
write_int((uint32_t) first); write_int((uint32_t) first);
write_int((uint32_t) count); write_int((uint32_t) count);
write_int(bound_buffer);
write_int(bound_texture);
if (!vertex_array_enabled) {
IMPOSSIBLE();
}
write_byte(color_array_enabled);
write_byte(tex_coord_array_enabled);
// Release Proxy // Release Proxy
end_proxy_call(); end_proxy_call();
@ -123,7 +170,17 @@ CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
GLenum mode = (GLenum) read_int(); GLenum mode = (GLenum) read_int();
GLint first = (GLint) read_int(); GLint first = (GLint) read_int();
GLsizei count = (GLsizei) read_int(); GLsizei count = (GLsizei) read_int();
GLuint bound_buffer = (GLuint) read_int();
GLuint bound_texture = (GLuint) read_int();
unsigned char color_array_enabled = read_byte();
unsigned char tex_coord_array_enabled = read_byte();
// Run // Run
glBindBuffer(GL_ARRAY_BUFFER, bound_buffer);
glBindTexture(GL_TEXTURE_2D, bound_texture);
glEnableClientState(GL_VERTEX_ARRAY);
#define set_array_enabled(condition, enum) condition ? glEnableClientState(enum) : glDisableClientState(enum);
set_array_enabled(color_array_enabled, GL_COLOR_ARRAY);
set_array_enabled(tex_coord_array_enabled, GL_TEXTURE_COORD_ARRAY);
glDrawArrays(mode, first, count); glDrawArrays(mode, first, count);
#endif #endif
} }
@ -187,6 +244,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
write_int((uint32_t) target); write_int((uint32_t) target);
write_int((uint32_t) size); write_int((uint32_t) size);
write_int((uint32_t) usage); write_int((uint32_t) usage);
write_int(bound_buffer);
// Write Data // Write Data
unsigned char is_null = data == NULL; unsigned char is_null = data == NULL;
write_byte(is_null); write_byte(is_null);
@ -200,6 +258,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
GLenum target = (GLenum) read_int(); GLenum target = (GLenum) read_int();
GLsizeiptr size = (GLsizeiptr) read_int(); GLsizeiptr size = (GLsizeiptr) read_int();
GLenum usage = (GLenum) read_int(); GLenum usage = (GLenum) read_int();
GLuint bound_buffer = (GLuint) read_int();
// Load Data // Load Data
void *data = NULL; void *data = NULL;
unsigned char is_null = read_byte(); unsigned char is_null = read_byte();
@ -223,6 +282,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
safe_read(data, (size_t) size); safe_read(data, (size_t) size);
} }
// Run // Run
glBindBuffer(GL_ARRAY_BUFFER, bound_buffer);
glBufferData(target, size, data, usage); glBufferData(target, size, data, usage);
#endif #endif
} }
@ -316,6 +376,7 @@ CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) {
write_int((uint32_t) target); write_int((uint32_t) target);
write_int((uint32_t) pname); write_int((uint32_t) pname);
write_int((uint32_t) param); write_int((uint32_t) param);
write_int(bound_texture);
// Release Proxy // Release Proxy
end_proxy_call(); end_proxy_call();
@ -323,7 +384,9 @@ CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) {
GLenum target = (GLenum) read_int(); GLenum target = (GLenum) read_int();
GLenum pname = (GLenum) read_int(); GLenum pname = (GLenum) read_int();
GLint param = (GLint) read_int(); GLint param = (GLint) read_int();
GLuint bound_texture = (GLuint) read_int();
// Run // Run
glBindTexture(GL_TEXTURE_2D, bound_texture);
glTexParameteri(target, pname, param); glTexParameteri(target, pname, param);
#endif #endif
} }
@ -383,6 +446,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
write_int((uint32_t) border); write_int((uint32_t) border);
write_int((uint32_t) format); write_int((uint32_t) format);
write_int((uint32_t) type); write_int((uint32_t) type);
write_int(bound_texture);
write_byte(is_null); write_byte(is_null);
if (!is_null) { if (!is_null) {
safe_write((void *) pixels, (size_t) size); safe_write((void *) pixels, (size_t) size);
@ -399,6 +463,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
GLint border = (GLint) read_int(); GLint border = (GLint) read_int();
GLenum format = (GLenum) read_int(); GLenum format = (GLenum) read_int();
GLenum type = (GLenum) read_int(); GLenum type = (GLenum) read_int();
GLuint bound_texture = (GLuint) read_int();
unsigned char is_null = read_byte(); unsigned char is_null = read_byte();
void *pixels = NULL; void *pixels = NULL;
if (!is_null) { if (!is_null) {
@ -408,6 +473,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
safe_read(pixels, (size_t) size); safe_read(pixels, (size_t) size);
} }
// Run // Run
glBindTexture(GL_TEXTURE_2D, bound_texture);
glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
// Free // Free
if (!is_null) { if (!is_null) {
@ -433,22 +499,17 @@ CALL(26, glEnable, void, (GLenum cap)) {
#endif #endif
} }
CALL(27, glEnableClientState, void, (GLenum array)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy void glEnableClientState(GLenum array) {
start_proxy_call(); // Set
unsigned char *enabled = get_array_enabled_pointer(array);
// Arguments if (*enabled) {
write_int((uint32_t) array); return;
} else {
// Release Proxy *enabled = 1;
end_proxy_call(); }
#else
GLenum array = (GLenum) read_int();
// Run
glEnableClientState(array);
#endif
} }
#endif
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) { CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
@ -469,22 +530,17 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) {
#endif #endif
} }
CALL(29, glDisableClientState, void, (GLenum array)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy void glDisableClientState(GLenum array) {
start_proxy_call(); // Set
unsigned char *enabled = get_array_enabled_pointer(array);
// Arguments if (!*enabled) {
write_int((uint32_t) array); return;
} else {
// Release Proxy *enabled = 0;
end_proxy_call(); }
#else
GLenum array = (GLenum) read_int();
// Run
glDisableClientState(array);
#endif
} }
#endif
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) { CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
@ -522,24 +578,16 @@ CALL(31, glDepthFunc, void, (GLenum func)) {
#endif #endif
} }
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy void glBindBuffer(GLenum target, GLuint buffer) {
start_proxy_call(); // Set
if (target == GL_ARRAY_BUFFER) {
// Arguments bound_buffer = buffer;
write_int((uint32_t) target); } else {
write_int((uint32_t) buffer); PROXY_ERR("Unsupported Buffer Binding: %u", target);
}
// Release Proxy
end_proxy_call();
#else
GLenum target = (GLenum) read_int();
GLuint buffer = (GLuint) read_int();
// Run
glBindBuffer(target, buffer);
#endif
} }
#endif
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) { CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
@ -748,6 +796,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
write_int((uint32_t) height); write_int((uint32_t) height);
write_int((uint32_t) format); write_int((uint32_t) format);
write_int((uint32_t) type); write_int((uint32_t) type);
write_int(bound_texture);
write_byte(is_null); write_byte(is_null);
if (!is_null) { if (!is_null) {
safe_write((void *) pixels, (size_t) size); safe_write((void *) pixels, (size_t) size);
@ -764,6 +813,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
GLsizei height = (GLsizei) read_int(); GLsizei height = (GLsizei) read_int();
GLenum format = (GLenum) read_int(); GLenum format = (GLenum) read_int();
GLenum type = (GLenum) read_int(); GLenum type = (GLenum) read_int();
GLuint bound_texture = (GLuint) read_int();
unsigned char is_null = read_byte(); unsigned char is_null = read_byte();
void *pixels = NULL; void *pixels = NULL;
if (!is_null) { if (!is_null) {
@ -773,6 +823,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
safe_read(pixels, (size_t) size); safe_read(pixels, (size_t) size);
} }
// Run // Run
glBindTexture(GL_TEXTURE_2D, bound_texture);
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
// Free // Free
if (!is_null) { if (!is_null) {
@ -887,24 +938,16 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) {
#endif #endif
} }
CALL(49, glBindTexture, void, (GLenum target, GLuint texture)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy void glBindTexture(GLenum target, GLuint texture) {
start_proxy_call(); // Set
if (target == GL_TEXTURE_2D) {
// Arguments bound_texture = texture;
write_int((uint32_t) target); } else {
write_int((uint32_t) texture); PROXY_ERR("Unsupported Texture Binding: %u", target);
}
// Release Proxy
end_proxy_call();
#else
GLenum target = (GLenum) read_int();
GLuint texture = (GLuint) read_int();
// Run
glBindTexture(target, texture);
#endif
} }
#endif
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) { CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)

View File

@ -9,18 +9,15 @@
#include "../common/common.h" #include "../common/common.h"
// Store Handlers // Store Handlers
__attribute__((const)) static std::vector<proxy_handler_t> &get_handlers() { static std::vector<proxy_handler_t> handlers;
static std::vector<proxy_handler_t> handlers;
return handlers;
}
void _add_handler(unsigned char unique_id, proxy_handler_t handler) { void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) { if (handlers.size() > unique_id && handlers[unique_id] != NULL) {
PROXY_ERR("Duplicate ID: %i", (int) unique_id); PROXY_ERR("Duplicate ID: %i", (int) unique_id);
} }
if (get_handlers().size() <= unique_id) { if (handlers.size() <= unique_id) {
get_handlers().resize(unique_id + 1); handlers.resize(unique_id + 1);
} }
get_handlers()[unique_id] = handler; handlers[unique_id] = handler;
} }
// Store Parent PID // Store Parent PID
@ -48,10 +45,7 @@ static void exit_handler(__attribute__((unused)) int signal_id) {
// Main // Main
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Install Signal Handlers // Install Signal Handlers
struct sigaction act_sigint; signal(SIGINT, SIG_IGN);
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
act_sigint.sa_handler = &exit_handler;
sigaction(SIGINT, &act_sigint, NULL);
struct sigaction act_sigterm; struct sigaction act_sigterm;
memset((void *) &act_sigterm, 0, sizeof (struct sigaction)); memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
act_sigterm.sa_handler = &exit_handler; act_sigterm.sa_handler = &exit_handler;
@ -84,9 +78,9 @@ int main(int argc, char *argv[]) {
int running = is_connection_open(); int running = is_connection_open();
while (running && !exit_requested) { while (running && !exit_requested) {
unsigned char unique_id = read_byte(); unsigned char unique_id = read_byte();
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) { if (handlers.size() > unique_id && handlers[unique_id] != NULL) {
// Run Method // Run Method
get_handlers()[unique_id](); handlers[unique_id]();
// Check If Connection Is Still Open // Check If Connection Is Still Open
if (!is_connection_open()) { if (!is_connection_open()) {
// Exit // Exit

View File

@ -1,6 +1,8 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <math.h>
#include <sys/ioctl.h>
#include "common.h" #include "common.h"
@ -12,23 +14,80 @@
PROXY_ERR("Attempting To Access Closed Connection"); \ PROXY_ERR("Attempting To Access Closed Connection"); \
} \ } \
} }
// Buffer Reads
static void *_read_cache = NULL;
__attribute__((destructor)) static void _free_read_cache() {
if (_read_cache != NULL) {
free(_read_cache);
}
}
static size_t _read_cache_size = 0;
static size_t _read_cache_actual_size = 0;
static size_t _read_cache_position = 0;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
void safe_read(void *buf, size_t len) { void safe_read(void *buf, size_t len) {
// Check Data // Check Data
if (buf == NULL) { if (buf == NULL) {
PROXY_ERR("Attempting To Read Into NULL Buffer"); PROXY_ERR("Attempting To Read Into NULL Buffer");
} }
// Setup
size_t to_read = len;
// Copy From Read Buffer
if (_read_cache != NULL && _read_cache_size > 0) {
char *read_cache = (void *) (((unsigned char *) _read_cache) + _read_cache_position);
size_t read_cache_size = _read_cache_size - _read_cache_position;
if (read_cache_size > 0) {
size_t to_copy = min(to_read, read_cache_size);
memcpy(buf, read_cache, to_copy);
to_read -= to_copy;
_read_cache_position += to_copy;
}
}
// Check If Done
if (to_read < 1) {
return;
}
if (_read_cache_position < _read_cache_size) {
IMPOSSIBLE();
}
// Flush Write Cache // Flush Write Cache
flush_write_cache(); flush_write_cache();
// Read // Read Remaining Data
size_t to_read = len; size_t to_read_to_cache;
while (to_read > 0) { {
int bytes_available;
if (ioctl(get_connection_read(), FIONREAD, &bytes_available) == -1) {
bytes_available = 0;
}
to_read_to_cache = max((size_t) bytes_available, to_read);
}
if (to_read_to_cache < 1) {
// Nothing To Read
return;
}
// Resize Buffer
_read_cache_position = 0;
_read_cache_size = to_read_to_cache;
if (_read_cache == NULL) {
_read_cache_actual_size = _read_cache_size;
_read_cache = malloc(_read_cache_actual_size);
} else if (_read_cache_size > _read_cache_actual_size) {
_read_cache_actual_size = _read_cache_size;
_read_cache = realloc(_read_cache, _read_cache_actual_size);
}
ALLOC_CHECK(_read_cache);
// Read Into Buffer
while (to_read_to_cache > 0) {
CHECK_CONNECTION(); CHECK_CONNECTION();
ssize_t x = read(get_connection_read(), (void *) (((unsigned char *) buf) + (len - to_read)), to_read); ssize_t x = read(get_connection_read(), (void *) (((unsigned char *) _read_cache) + (_read_cache_size - to_read_to_cache)), to_read_to_cache);
if (x == -1 && errno != EINTR) { if (x == -1 && errno != EINTR) {
PROXY_ERR("Failed Reading Data To Connection: %s", strerror(errno)); PROXY_ERR("Failed Reading Data To Connection: %s", strerror(errno));
} }
to_read -= x; to_read_to_cache -= x;
} }
// Copy Remaining Data
safe_read((void *) (((unsigned char *) buf) + (len - to_read)), to_read);
} }
// Buffer Writes // Buffer Writes
static void *_write_cache = NULL; static void *_write_cache = NULL;

View File

@ -133,14 +133,19 @@ void init_compat() {
__attribute__((destructor)) static void cleanup_temporary() { __attribute__((destructor)) static void cleanup_temporary() {
// Cleanup Executable // Cleanup Executable
{ {
const char *exe = getenv("MCPI_EXECUTABLE_PATH"); char *exe = realpath("/proc/self/exe", NULL);
// Check If Successful
if (exe != NULL) {
// Check If Executable Is Temporary // Check If Executable Is Temporary
if (exe != NULL && starts_with(exe, "/tmp")) { if (starts_with(exe, "/tmp")) {
// Cleanup Temporary File // Cleanup Temporary File
if (unlink(exe) != 0) { if (unlink(exe) != 0) {
ERR("Unable To Cleanup Temporary File: %s", strerror(errno)); ERR("Unable To Cleanup Temporary File: %s", strerror(errno));
} }
} }
// Free
free(exe);
}
} }
} }

View File

@ -38,6 +38,7 @@ if (mode === 'client') {
'libgtk-3-0', 'libgtk-3-0',
'libglib2.0-0', 'libglib2.0-0',
'libgdk-pixbuf2.0-0', 'libgdk-pixbuf2.0-0',
'librsvg2-common',
'shared-mime-info', 'shared-mime-info',
'libfreeimage3', 'libfreeimage3',
'libopenal1' 'libopenal1'
@ -59,7 +60,8 @@ const packageExclusions = [
'librest-*', 'librest-*',
'libcups2', 'libcups2',
'libcolord2', 'libcolord2',
'libmount1' 'libmount1',
'libwayland-*'
]; ];
// APT // APT