diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp index 8d864cf7..db6aa584 100644 --- a/src/dev/posix/hasp_posix.cpp +++ b/src/dev/posix/hasp_posix.cpp @@ -246,6 +246,12 @@ bool PosixDevice::is_system_pin(uint8_t pin) return false; } +void Win32Device::run_thread(void (*func)(void*), void* arg) +{ + pthread_t thread; + pthread_create(&thread, NULL, (void* (*)(void*))func, arg); +} + #ifndef TARGET_OS_MAC long PosixDevice::get_uptime() { diff --git a/src/dev/posix/hasp_posix.h b/src/dev/posix/hasp_posix.h index 439d4c12..70f62695 100644 --- a/src/dev/posix/hasp_posix.h +++ b/src/dev/posix/hasp_posix.h @@ -58,6 +58,8 @@ class PosixDevice : public BaseDevice { bool is_system_pin(uint8_t pin) override; + void run_thread(void (*func)(void*), void* arg); + public: std::string backlight_device; int backlight_max = 0; diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp index 6f7576de..591ccb75 100644 --- a/src/dev/win32/hasp_win32.cpp +++ b/src/dev/win32/hasp_win32.cpp @@ -187,6 +187,11 @@ bool Win32Device::is_system_pin(uint8_t pin) return false; } +void Win32Device::run_thread(void (*func)(void*), void* arg) +{ + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL); +} + long Win32Device::get_uptime() { return GetTickCount64() / 1000; diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h index 1a25106d..09f56773 100644 --- a/src/dev/win32/hasp_win32.h +++ b/src/dev/win32/hasp_win32.h @@ -45,6 +45,8 @@ class Win32Device : public BaseDevice { bool is_system_pin(uint8_t pin) override; + void run_thread(void (*func)(void*), void* arg); + private: std::string _hostname; std::string _core_version; diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 0b58089f..42cc1750 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -822,6 +822,48 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source) #endif } +#if HASP_TARGET_PC +static void shell_command_thread(char* cmdline) +{ + // run the command + FILE* pipe = popen(cmdline, "r"); + // free the string duplicated previously + free(cmdline); + if(!pipe) { + LOG_ERROR(TAG_MSGR, F("Couldn't execute system command")); + return; + } + // read each line, up to 1023 chars long + char command[1024]; + while(fgets(command, sizeof(command), pipe) != NULL) { + // strip newline character + char* temp = command; + while(*temp) { + if(*temp == '\r' || *temp == '\n') { + *temp = '\0'; + break; + } + temp++; + } + // run the command + LOG_INFO(TAG_MSGR, F("Running '%s'"), command); + dispatch_text_line(command, TAG_MSGR); + } + // close the pipe, check return code + int status_code = pclose(pipe); + if(status_code) { + LOG_ERROR(TAG_MSGR, F("Process exited with non-zero return code %d"), status_code); + } +} + +void dispatch_shell_execute(const char*, const char* payload, uint8_t source) +{ + // must duplicate the string for thread's own usage + char* command = strdup(payload); + haspDevice.run_thread((void (*)(void*))shell_command_thread, (void*)command); +} +#endif + void dispatch_current_page() { char topic[8]; @@ -1495,6 +1537,9 @@ void dispatchSetup() dispatch_add_command(PSTR("sensors"), dispatch_send_sensordata); dispatch_add_command(PSTR("theme"), dispatch_theme); dispatch_add_command(PSTR("run"), dispatch_run_script); +#if HASP_TARGET_PC + dispatch_add_command(PSTR("shell"), dispatch_shell_execute); +#endif dispatch_add_command(PSTR("service"), dispatch_service); dispatch_add_command(PSTR("antiburn"), dispatch_antiburn); dispatch_add_command(PSTR("calibrate"), dispatch_calibrate); diff --git a/src/sys/svc/hasp_console.cpp b/src/sys/svc/hasp_console.cpp index 17612d2d..04ab243f 100644 --- a/src/sys/svc/hasp_console.cpp +++ b/src/sys/svc/hasp_console.cpp @@ -108,7 +108,7 @@ static void console_process_line(const char* input) } #elif HASP_TARGET_PC static bool console_running = true; -static int console_thread(void* arg) +static void console_thread(void* arg) { while(console_running) { std::string input; @@ -145,12 +145,7 @@ void consoleStart() } #elif HASP_TARGET_PC LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING)); -#if defined(WINDOWS) - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)console_thread, NULL, 0, NULL); -#elif defined(POSIX) - pthread_t thread; - pthread_create(&thread, NULL, (void* (*)(void*))console_thread, NULL); -#endif + haspDevice.run_thread(console_thread, NULL); #endif } @@ -202,7 +197,7 @@ IRAM_ATTR void consoleLoop() case 0: case -1: break; - + default: { update = true; }