diff --git a/programs/GNUmakefile b/programs/GNUmakefile index 82a2b59..42dcb26 100644 --- a/programs/GNUmakefile +++ b/programs/GNUmakefile @@ -216,8 +216,8 @@ login: bearssl libc shell: $(MAKE) -C src/shell -# Build desktop via its own Makefile (depends on libc, libjpeg, and bearssl for user.h). -desktop: libc libjpeg bearssl +# Build desktop via its own Makefile (depends on libc, libjpeg, bearssl for user.h, and dialogs for duplicate-session warnings). +desktop: libc libjpeg bearssl libloader dialogs $(MAKE) -C src/desktop # Copy SVG icons for the desktop into bin/icons/. diff --git a/programs/src/desktop/Makefile b/programs/src/desktop/Makefile index 681de9a..6446377 100644 --- a/programs/src/desktop/Makefile +++ b/programs/src/desktop/Makefile @@ -19,6 +19,7 @@ PROG_INC := ../../include JPEG_LIB := ../../lib/libjpeg LIBC_LIB := ../../lib/libc BEARSSL := ../../lib/bearssl +LOADER_LIB := ../../bin/liblibloader.a LINK_LD := ../../link.ld BINDIR := ../../bin OBJDIR := obj @@ -82,7 +83,7 @@ all: $(TARGET) # ---- Libraries ---- -LIBS := $(JPEG_LIB)/libjpeg.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a +LIBS := $(LOADER_LIB) $(JPEG_LIB)/libjpeg.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a $(TARGET): $(OBJS) $(LIBS) $(LINK_LD) Makefile mkdir -p $(BINDIR)/os diff --git a/programs/src/desktop/main.cpp b/programs/src/desktop/main.cpp index ae555a3..dace1bb 100644 --- a/programs/src/desktop/main.cpp +++ b/programs/src/desktop/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include // ============================================================================ // App Manifest Scanning @@ -642,7 +643,46 @@ void gui::desktop_run(DesktopState* ds) { static DesktopState* g_desktop; +static constexpr const char kDesktopBinaryName[] = "desktop.elf"; +static constexpr int DESKTOP_PROC_SCAN_MAX = 256; + +static bool desktop_proc_alive(const Montauk::ProcInfo& proc) { + return proc.state == 1 || proc.state == 2 || proc.state == 3; +} + +static bool proc_name_is_desktop(const char* name) { + int name_len = montauk::slen(name); + int binary_len = (int)sizeof(kDesktopBinaryName) - 1; + if (name_len < binary_len) return false; + + const char* suffix = name + name_len - binary_len; + if (!montauk::streq(suffix, kDesktopBinaryName)) return false; + return name_len == binary_len || suffix[-1] == '/'; +} + +static bool existing_desktop_running() { + static Montauk::ProcInfo procs[DESKTOP_PROC_SCAN_MAX]; + int count = montauk::proclist(procs, DESKTOP_PROC_SCAN_MAX); + if (count <= 0) return false; + + int self_pid = montauk::getpid(); + for (int i = 0; i < count; i++) { + if (procs[i].pid == self_pid) continue; + if (!desktop_proc_alive(procs[i])) continue; + if (proc_name_is_desktop(procs[i].name)) return true; + } + return false; +} + extern "C" void _start() { + if (existing_desktop_running()) { + gui::dialogs::message_box( + "Desktop Already Running", + "Cannot spawn new desktop process whilst an existing desktop session is active.", + gui::dialogs::MESSAGE_BOX_OK); + montauk::exit(0); + } + DesktopState* ds = (DesktopState*)montauk::malloc(sizeof(DesktopState)); montauk::memset(ds, 0, sizeof(DesktopState));