Improve builder and self-detection.

This commit is contained in:
TSnake41 2020-05-10 13:42:51 +02:00
parent 21f0a50f4d
commit 75a3b0033e
4 changed files with 81 additions and 44 deletions

View File

@ -40,6 +40,8 @@
static void append_file(FILE *dst, FILE *src)
{
rewind(src);
size_t count;
do {
uint8_t buffer[4096];
@ -55,7 +57,7 @@ typedef struct raylua_builder {
static int raylua_builder_new(lua_State *L)
{
const char *self_path = luaL_checkstring(L, -2);
FILE *self = lua_touserdata(L, -2);
const char *path = luaL_checkstring(L, -1);
raylua_builder *builder = malloc(sizeof(raylua_builder));
@ -69,20 +71,11 @@ static int raylua_builder_new(lua_State *L)
builder->file = f;
FILE *self = fopen(self_path, "rb");
if (!self) {
free(builder);
fclose(f);
return luaL_error(L, "Can't open self (%s)", self_path);
}
append_file(f, self);
fclose(self);
if (!mz_zip_writer_init_cfile(&builder->zip, f, 0)) {
free(builder);
fclose(f);
fclose(self);
return luaL_error(L, "Can't initialize miniz writer.");
}
@ -170,11 +163,17 @@ static int list_dir(lua_State *L)
return 1;
}
int raylua_builder_boot(lua_State *L)
int raylua_builder_boot(lua_State *L, FILE *self)
{
lua_pushcfunction(L, get_type);
lua_setglobal(L, "get_type");
lua_pushlightuserdata(L, append_file);
lua_setglobal(L, "append_file");
lua_pushlightuserdata(L, self);
lua_setglobal(L, "self");
lua_pushcfunction(L, list_dir);
lua_setglobal(L, "list_dir");

View File

@ -43,8 +43,8 @@
local ffi = require "ffi"
ffi.cdef "typedef struct FILE FILE;"
local append_file = ffi.cast("void (*)(FILE *, FILE *)", append_file)
local self_path = arg[0]
local input_path = arg[1]
print "BUILDER: Initialized builder"
@ -59,12 +59,6 @@ local function path_concat(...)
return table.concat({ ... }, "/")
end
if ffi.os == "Windows" and self_path:sub("-4") ~= ".exe" then
self_path = self_path .. ".exe"
end
print("BUILDER: Self is " .. self_path)
if t == "directory" then
print "BUILDER: Building from folder."
@ -82,7 +76,7 @@ if t == "directory" then
print("BUILDER: Building " .. output)
local builder = builder_new(self_path, output)
local builder = builder_new(self, output)
assert(builder, "Can't initialize builder")
local have_main = false
@ -145,19 +139,17 @@ elseif t == "file" then
print "BUILDER: Building from zip file."
local dest = assert(io.open(path, "wb"), "Can't open destination file.")
local source = assert(io.open(self_path, "rb"), "Can't open self file.")
local input = assert(io.open(input_path, "rb"), "Can't open zip file.")
append_file(dest, source)
append_file(dest, self)
append_file(dest, input)
dest:close()
source:close()
input:close()
elseif ext == ".lua" then
print "BUILDER: Building from lua file."
local builder = builder_new(self_path, path)
local builder = builder_new(self, path)
builder_add(builder, input_path, "main.lua")
builder_close(builder)
else

View File

@ -28,8 +28,10 @@
#include "raylua.h"
#include "lib/miniz.h"
FILE *raylua_open_self(const char *argv0);
#ifndef RAYLUA_NO_BUILDER
int raylua_builder_boot(lua_State *L);
int raylua_builder_boot(lua_State *L, FILE *self);
#endif
static mz_zip_archive zip_file;
@ -140,11 +142,11 @@ char *raylua_loadFileText(const char *path)
return buffer;
}
static bool raylua_init_payload(const char *path)
static bool raylua_init_payload(FILE *self)
{
mz_zip_zero_struct(&zip_file);
return mz_zip_reader_init_file(&zip_file, path, 0);
return mz_zip_reader_init_cfile(&zip_file, self, 0, 0);
}
int main(int argc, const char **argv)
@ -154,7 +156,7 @@ int main(int argc, const char **argv)
if (L == NULL) {
puts("RAYLUA: Unable to initialize Lua.");
return 0;
return 1;
}
luaL_openlibs(L);
@ -172,32 +174,24 @@ int main(int argc, const char **argv)
lua_setglobal(L, "arg");
const char *path = argv[0];
#ifdef WIN32
/* Executable name translation. */
size_t path_len = strlen(path);
char new_path[path_len + 5];
if (path_len > 4 && stricmp(path + path_len - 4, ".exe")) {
strcpy(new_path, path);
strcpy(new_path + path_len, ".exe");
printf("RAYLUA: Translated self executable name from %s to %s.\n", path, new_path);
path = new_path;
}
#endif
SetFilesystemOverride((FilesystemOverride){
.loadFileData = &raylua_loadFileData,
.loadFileText = &raylua_loadFileText,
});
if (!raylua_init_payload(path)) {
FILE *self = raylua_open_self(argv[0]);
if (self == NULL) {
puts("RAYLUA: Can't open self, cannot continue.");
return 1;
}
if (!raylua_init_payload(self)) {
#ifdef RAYLUA_NO_BUILDER
puts("RAYLUA: No payload.");
#else
puts("RAYLUA: No payload, use internal builder.");
raylua_builder_boot(L);
raylua_builder_boot(L, self);
#endif
} else {
/* Boot on payload. */

52
src/raylua_self.c Normal file
View File

@ -0,0 +1,52 @@
/*
Copyright (C) 2020 Astie Teddy
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Procedures to open the current process executable. */
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
/* Use platform specific functions. */
static inline FILE *open_self_platform(void)
{
#ifdef WIN32
char path[MAX_PATH + 1];
memset(path, '\0', sizeof(path));
GetModuleFileName(NULL, path, MAX_PATH);
return fopen(path, "rb");
#elif defined(__linux__)
return fopen("/proc/self/exe", "r");
#else
/* TODO: Implement for Darwin and BSD hosts. */
return NULL; /* fallback to argv0 */
#endif
}
FILE *raylua_open_self(const char *argv0)
{
FILE *self = open_self_platform();
if (self == NULL)
self = fopen(argv0, "rb");
return self;
}