diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index 6b3984ad4..0264105e3 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -26,6 +26,9 @@ #include "comms.h" #include "util_posix.h" // msleep +#if defined(__MACH__) && defined(__APPLE__) +# include "pthread_spin_lock_shim.h" +#endif #define MAX_PM3_INPUT_ARGS_LENGTH 4096 @@ -220,14 +223,16 @@ void CmdsHelp(const command_t Commands[]) { PrintAndLogEx(NORMAL, ""); } -pthread_spinlock_t sycmd_spinlock; - static int execute_system_command(const char *command) { + pthread_spinlock_t sycmd_spinlock; + pthread_spin_init(&sycmd_spinlock, 0); + pthread_spin_lock(&sycmd_spinlock); + + int ret; - pthread_spin_lock(&sycmd_spinlock); -#if defined(_WIN32) + #if defined(_WIN32) char wrapped_command[255]; strncat(wrapped_command, "cmd /C \"", 9); strncat(wrapped_command, command, strlen(command)); @@ -238,6 +243,7 @@ static int execute_system_command(const char *command) { ret = system(command); #endif pthread_spin_unlock(&sycmd_spinlock); + pthread_spin_destroy(&sycmd_spinlock); return ret; } @@ -291,10 +297,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { } if (Cmd[0] == '!') { - pthread_spin_init(&sycmd_spinlock, 0); - int res = execute_system_command(Cmd + 1); - pthread_spin_destroy(&sycmd_spinlock); - return res; + return execute_system_command(Cmd + 1); } char cmd_name[128] = {0}; diff --git a/client/src/pthread_spin_lock_shim.h b/client/src/pthread_spin_lock_shim.h new file mode 100644 index 000000000..16d1dc09d --- /dev/null +++ b/client/src/pthread_spin_lock_shim.h @@ -0,0 +1,55 @@ +/* + +Required imports: +#include + +*/ + +#ifndef PTHREAD_SPIN_LOCK_SHIM +#define PTHREAD_SPIN_LOCK_SHIM + +typedef int pthread_spinlock_t; + +#ifndef PTHREAD_PROCESS_SHARED +# define PTHREAD_PROCESS_SHARED 1 +#endif +#ifndef PTHREAD_PROCESS_PRIVATE +# define PTHREAD_PROCESS_PRIVATE 2 +#endif + +static inline int pthread_spin_init(pthread_spinlock_t *lock, int pshared) { + __asm__ __volatile__ ("" ::: "memory"); + *lock = 0; + return 0; +} + +static inline int pthread_spin_destroy(pthread_spinlock_t *lock) { + return 0; +} + +static inline int pthread_spin_lock(pthread_spinlock_t *lock) { + while (1) { + int i; + for (i=0; i < 10000; i++) { + if (__sync_bool_compare_and_swap(lock, 0, 1)) { + return 0; + } + } + sched_yield(); + } +} + +static inline int pthread_spin_trylock(pthread_spinlock_t *lock) { + if (__sync_bool_compare_and_swap(lock, 0, 1)) { + return 0; + } + return EBUSY; +} + +static inline int pthread_spin_unlock(pthread_spinlock_t *lock) { + __asm__ __volatile__ ("" ::: "memory"); + *lock = 0; + return 0; +} + +#endif