Skip to content
Merged
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
6 changes: 6 additions & 0 deletions src/devices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ void devices_reset_ext(int hardreset)
void devices_reset(int hardreset)
{
memset(device_reset_done, 0, sizeof(device_reset_done));
#ifdef AMIBERRY
uaelib_host_cleanup();
#endif
// must be first
init_eventtab();
init_shm();
Expand Down Expand Up @@ -385,6 +388,9 @@ void devices_update_sync(float svpos, float syncadjust)

void virtualdevice_free(void)
{
#ifdef AMIBERRY
uaelib_host_cleanup();
#endif
#ifdef WITH_PPC
// must be first
uae_ppc_free();
Expand Down
1 change: 1 addition & 0 deletions src/include/uae.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ void filesys_addexternals (void);
#ifdef AMIBERRY
extern std::vector<std::string> get_cd_drives();
extern int add_filesys_unit(struct uaedev_config_info* ci, bool custom);
extern void uaelib_host_cleanup();
#endif

#endif /* UAE_UAE_H */
10 changes: 8 additions & 2 deletions src/osdep/gfx_prefs_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ int check_prefs_changed_gfx()
int c = 0;
bool monitors[MAX_AMIGAMONITORS]{};

const bool native_code_changed = currprefs.native_code != changed_prefs.native_code;
if (native_code_changed) {
if (currprefs.native_code && !changed_prefs.native_code)
uaelib_host_cleanup();
currprefs.native_code = changed_prefs.native_code;
Comment thread
midwan marked this conversation as resolved.
}

if (!config_changed && !display_change_requested)
return 0;

Expand Down Expand Up @@ -535,7 +542,7 @@ int check_prefs_changed_gfx()
currprefs.minimized_pause != changed_prefs.minimized_pause ||
currprefs.minimized_input != changed_prefs.minimized_input ||
currprefs.capture_always != changed_prefs.capture_always ||
currprefs.native_code != changed_prefs.native_code ||
native_code_changed ||
currprefs.alt_tab_release != changed_prefs.alt_tab_release ||
currprefs.ctrl_alt_release != changed_prefs.ctrl_alt_release ||
currprefs.use_retroarch_quit != changed_prefs.use_retroarch_quit ||
Expand Down Expand Up @@ -569,7 +576,6 @@ int check_prefs_changed_gfx()
currprefs.minimized_pause = changed_prefs.minimized_pause;
currprefs.minimized_input = changed_prefs.minimized_input;
currprefs.capture_always = changed_prefs.capture_always;
currprefs.native_code = changed_prefs.native_code;
currprefs.alt_tab_release = changed_prefs.alt_tab_release;
currprefs.ctrl_alt_release = changed_prefs.ctrl_alt_release;
currprefs.use_retroarch_quit = changed_prefs.use_retroarch_quit;
Expand Down
98 changes: 81 additions & 17 deletions src/uaelib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,35 @@ static const uae_u32 HOST_SHELL_STATUS_INVALID = 0;
static const uae_u32 HOST_SHELL_STATUS_RUNNING = 1;
static const uae_u32 HOST_SHELL_STATUS_EXITED = 0x80000000;
static const uae_u32 HOST_SHELL_IO_MAX = 4096;
#if !defined(_WIN32)
static const int HOST_SHELL_WAIT_INTERVAL_MS = 10;
static const int HOST_SHELL_TERM_TIMEOUT_MS = 1000;
static const int HOST_SHELL_KILL_TIMEOUT_MS = 1000;
#endif

static constexpr bool uaelib_host_trap_requires_native_code(uae_u32 trap)
{
return trap >= 88 && trap <= 95 && trap != 93;
}

static constexpr uae_u32 uaelib_host_trap_denied_result(uae_u32 trap)
{
return trap == 91 || trap == 92 ? static_cast<uae_u32>(-1) : 0;
}

static_assert(uaelib_host_trap_requires_native_code(88));
static_assert(uaelib_host_trap_requires_native_code(89));
static_assert(uaelib_host_trap_requires_native_code(90));
static_assert(uaelib_host_trap_requires_native_code(91));
static_assert(uaelib_host_trap_requires_native_code(92));
static_assert(!uaelib_host_trap_requires_native_code(93));
static_assert(uaelib_host_trap_requires_native_code(94));
static_assert(uaelib_host_trap_requires_native_code(95));
static_assert(!uaelib_host_trap_requires_native_code(96));
static_assert(uaelib_host_trap_denied_result(90) == 0);
static_assert(uaelib_host_trap_denied_result(91) == static_cast<uae_u32>(-1));
static_assert(uaelib_host_trap_denied_result(92) == static_cast<uae_u32>(-1));
static_assert(uaelib_host_trap_denied_result(94) == HOST_SHELL_STATUS_INVALID);

#if !defined(_WIN32)
static int host_shell_exit_code(int status)
Expand Down Expand Up @@ -497,6 +526,34 @@ static uae_u32 host_shell_update_status(ShellSession& session)
#endif
}

#if !defined(_WIN32)
static bool host_shell_wait_for_exit(ShellSession& session, int timeout_ms)
{
for (int elapsed = 0; elapsed < timeout_ms; elapsed += HOST_SHELL_WAIT_INTERVAL_MS) {
if ((host_shell_update_status(session) & HOST_SHELL_STATUS_EXITED) != 0)
return true;
sleep_millis(HOST_SHELL_WAIT_INTERVAL_MS);
}
return (host_shell_update_status(session) & HOST_SHELL_STATUS_EXITED) != 0;
}

static void host_shell_terminate(ShellSession& session)
{
if ((host_shell_update_status(session) & HOST_SHELL_STATUS_EXITED) != 0)
return;

if (kill(session.pid, SIGTERM) < 0 && errno != ESRCH)
write_log("Failed to terminate host shell process %d: %s\n", session.pid, strerror(errno));
if (host_shell_wait_for_exit(session, HOST_SHELL_TERM_TIMEOUT_MS))
return;

if (kill(session.pid, SIGKILL) < 0 && errno != ESRCH)
write_log("Failed to kill host shell process %d: %s\n", session.pid, strerror(errno));
if (!host_shell_wait_for_exit(session, HOST_SHELL_KILL_TIMEOUT_MS))
write_log("Timed out waiting for host shell process %d to exit\n", session.pid);
}
#endif

static uae_u32 uaelib_host_open(TrapContext* ctx, uaecptr command)
{
char cmd[HOST_SHELL_CMD_MAX];
Expand Down Expand Up @@ -856,16 +913,19 @@ static uae_u32 uaelib_host_close(TrapContext* ctx, uae_u32 handle)
close(session.outfd);
session.outfd = -1;
}
if ((host_shell_update_status(session) & HOST_SHELL_STATUS_EXITED) == 0) {
kill(session.pid, SIGTERM);
waitpid(session.pid, NULL, 0);
}
host_shell_terminate(session);

shell_sessions.erase(handle);
return 1;
#endif
}

void uaelib_host_cleanup()
{
while (!shell_sessions.empty())
uaelib_host_close(nullptr, shell_sessions.begin()->first);
Comment thread
midwan marked this conversation as resolved.
}

// Host platform ids reported by trap 96; 0 (unknown trap on older
// builds) means the guest should assume a POSIX host.
static uae_u32 uaelib_host_get_platform(void)
Expand All @@ -882,15 +942,11 @@ static uae_u32 uaelib_host_get_platform(void)
static uae_u32 uaelib_host_status(TrapContext* ctx, uae_u32 handle)
{
(void)ctx;
#if defined(_WIN32)
return HOST_SHELL_STATUS_INVALID;
#else
if (shell_sessions.find(handle) == shell_sessions.end())
return HOST_SHELL_STATUS_INVALID;

ShellSession& session = shell_sessions[handle];
return host_shell_update_status(session);
#endif
}

static std::string quote_path(const char* path) {
Expand Down Expand Up @@ -1033,6 +1089,11 @@ static uae_u32 uaelib_midi(TrapContext *ctx, uae_u32 op, uae_u32 index, uaecptr
static uae_u32 uaelib_demux_common(TrapContext *ctx, uae_u32 ARG0, uae_u32 ARG1, uae_u32 ARG2, uae_u32 ARG3, uae_u32 ARG4, uae_u32 ARG5)
{
write_log("%ld\n",ARG0);

#ifdef AMIBERRY
if (!currprefs.native_code && uaelib_host_trap_requires_native_code(ARG0))
return uaelib_host_trap_denied_result(ARG0);
#endif

switch (ARG0) {
case 0: return emulib_GetVersion();
Expand Down Expand Up @@ -1090,17 +1151,20 @@ static uae_u32 uaelib_demux_common(TrapContext *ctx, uae_u32 ARG0, uae_u32 ARG1,
}
#ifdef AMIBERRY
case 88:
if (currprefs.native_code)
return emulib_execute_on_host(ctx, ARG1);
return 0;
case 89: return uaelib_host_view(ctx, ARG1);

case 90: return uaelib_host_open(ctx, ARG1);
case 91: return uaelib_host_read(ctx, ARG1, ARG2, ARG3);
case 92: return uaelib_host_write(ctx, ARG1, ARG2, ARG3);
case 89:
return uaelib_host_view(ctx, ARG1);
case 90:
return uaelib_host_open(ctx, ARG1);
case 91:
return uaelib_host_read(ctx, ARG1, ARG2, ARG3);
case 92:
return uaelib_host_write(ctx, ARG1, ARG2, ARG3);
case 93: return uaelib_host_close(ctx, ARG1);
case 94: return uaelib_host_status(ctx, ARG1);
case 95: return uaelib_host_open_pipe(ctx, ARG1);
case 94:
return uaelib_host_status(ctx, ARG1);
case 95:
return uaelib_host_open_pipe(ctx, ARG1);
case 96: return uaelib_host_get_platform();

case 100:
Expand Down
Loading