diff --git a/native/jni/su/pts.cpp b/native/jni/su/pts.cpp index 9a480b770..69ebe36ea 100644 --- a/native/jni/su/pts.cpp +++ b/native/jni/su/pts.cpp @@ -41,7 +41,7 @@ static int write_blocking(int fd, char *buf, ssize_t bufsz) { * Pump data from input FD to output FD. If close_output is * true, then close the output FD when we're done. */ -static void pump_ex(int input, int output, int close_output) { +static void pump(int input, int output, bool close_output = true) { char buf[4096]; int len; while ((len = read(input, buf, 4096)) > 0) { @@ -51,32 +51,19 @@ static void pump_ex(int input, int output, int close_output) { if (close_output) close(output); } -/** - * Pump data from input FD to output FD. Will close the - * output FD when done. - */ -static void pump(int input, int output) { - pump_ex(input, output, 1); -} - static void* pump_thread(void* data) { - int* files = (int*)data; - int input = files[0]; - int output = files[1]; - pump(input, output); - free(data); - return NULL; + int *fds = (int*) data; + pump(fds[0], fds[1]); + delete[] fds; + return nullptr; } static void pump_async(int input, int output) { pthread_t writer; - int* files = (int*)malloc(sizeof(int) * 2); - if (files == NULL) { - exit(-1); - } - files[0] = input; - files[1] = output; - pthread_create(&writer, NULL, pump_thread, files); + int *fds = new int[2]; + fds[0] = input; + fds[1] = output; + pthread_create(&writer, nullptr, pump_thread, fds); } @@ -190,7 +177,7 @@ int restore_stdin(void) { } // Flag indicating whether the sigwinch watcher should terminate. -static volatile int closing_time = 0; +static volatile bool close_sigwinch_watcher = false; /** * Thread process. Wait for a SIGWINCH to be received, then update @@ -198,29 +185,29 @@ static volatile int closing_time = 0; */ static void *watch_sigwinch(void *data) { sigset_t winch; + int *fds = (int *)data; int sig; - int master = ((int *)data)[0]; - int slave = ((int *)data)[1]; sigemptyset(&winch); sigaddset(&winch, SIGWINCH); + pthread_sigmask(SIG_UNBLOCK, &winch, nullptr); do { - if (closing_time) break; + if (close_sigwinch_watcher) + break; // Get the new terminal size struct winsize w; - if (ioctl(master, TIOCGWINSZ, &w) == -1) { + if (ioctl(fds[0], TIOCGWINSZ, &w) == -1) continue; - } // Set the new terminal size - ioctl(slave, TIOCSWINSZ, &w); + ioctl(fds[1], TIOCSWINSZ, &w); } while (sigwait(&winch, &sig) == 0); + delete[] fds; - free(data); - return NULL; + return nullptr; } /** @@ -247,27 +234,24 @@ static void *watch_sigwinch(void *data) { */ int watch_sigwinch_async(int master, int slave) { pthread_t watcher; - int *files = (int *) malloc(sizeof(int) * 2); - if (files == NULL) { - return -1; - } + int *fds = new int[2]; // Block SIGWINCH so sigwait can later receive it sigset_t winch; sigemptyset(&winch); sigaddset(&winch, SIGWINCH); - if (sigprocmask(SIG_BLOCK, &winch, NULL) == -1) { - free(files); + if (pthread_sigmask(SIG_BLOCK, &winch, nullptr) == -1) { + delete[] fds; return -1; } // Initialize some variables, then start the thread - closing_time = 0; - files[0] = master; - files[1] = slave; - int ret = pthread_create(&watcher, NULL, &watch_sigwinch, files); + close_sigwinch_watcher = 0; + fds[0] = master; + fds[1] = slave; + int ret = pthread_create(&watcher, nullptr, &watch_sigwinch, fds); if (ret != 0) { - free(files); + delete[] fds; errno = ret; return -1; } @@ -275,16 +259,6 @@ int watch_sigwinch_async(int master, int slave) { return 0; } -/** - * watch_sigwinch_cleanup - * - * Cause the SIGWINCH watcher thread to terminate - */ -void watch_sigwinch_cleanup(void) { - closing_time = 1; - raise(SIGWINCH); -} - /** * pump_stdin_async * @@ -309,9 +283,10 @@ void pump_stdin_async(int outfd) { */ void pump_stdout_blocking(int infd) { // Pump data from stdout to PTY - pump_ex(infd, STDOUT_FILENO, 0 /* Don't close output when done */); + pump(infd, STDOUT_FILENO, false /* Don't close output when done */); // Cleanup restore_stdin(); - watch_sigwinch_cleanup(); + close_sigwinch_watcher = true; + raise(SIGWINCH); } diff --git a/native/jni/su/pts.h b/native/jni/su/pts.h index 8f645562f..57900489d 100644 --- a/native/jni/su/pts.h +++ b/native/jni/su/pts.h @@ -78,13 +78,6 @@ int restore_stdin(void); */ int watch_sigwinch_async(int master, int slave); -/** - * watch_sigwinch_cleanup - * - * Cause the SIGWINCH watcher thread to terminate - */ -void watch_sigwinch_cleanup(void); - /** * pump_stdin_async * diff --git a/native/jni/su/su.cpp b/native/jni/su/su.cpp index 09dee5980..5b38dc27f 100644 --- a/native/jni/su/su.cpp +++ b/native/jni/su/su.cpp @@ -28,7 +28,7 @@ #include "pts.h" #include "flags.h" -#define quit_signals ((int []) { SIGALRM, SIGABRT, SIGHUP, SIGPIPE, SIGQUIT, SIGTERM, SIGINT, 0 }) +int quit_signals[] = { SIGALRM, SIGABRT, SIGHUP, SIGPIPE, SIGQUIT, SIGTERM, SIGINT, 0 }; static void usage(int status) { FILE *stream = (status == EXIT_SUCCESS) ? stdout : stderr; @@ -224,13 +224,10 @@ int su_client_main(int argc, char *argv[]) { // Send stderr send_fd(fd, (atty & ATTY_ERR) ? -1 : STDERR_FILENO); - if (atty & ATTY_IN) { + if (atty) { setup_sighandlers(sighandler); - pump_stdin_async(ptmx); - } - if (atty & ATTY_OUT) { - // Forward SIGWINCH watch_sigwinch_async(STDOUT_FILENO, ptmx); + pump_stdin_async(ptmx); pump_stdout_blocking(ptmx); }