diff -up ./src/programs/pkttyagent.c.ori ./src/programs/pkttyagent.c --- ./src/programs/pkttyagent.c.ori 2019-03-21 15:28:00.058408349 +0100 +++ ./src/programs/pkttyagent.c 2019-03-21 15:32:55.499744167 +0100 @@ -24,11 +24,44 @@ #endif #include +#include +#include #include #include #define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE #include + +static volatile sig_atomic_t tty_flags_saved; +struct termios ts; +FILE *tty = NULL; +struct sigaction savesigterm, savesigint, savesigtstp; + + +static void tty_handler(int signal) +{ + switch (signal) + { + case SIGTERM: + sigaction (SIGTERM, &savesigterm, NULL); + break; + case SIGINT: + sigaction (SIGINT, &savesigint, NULL); + break; + case SIGTSTP: + sigaction (SIGTSTP, &savesigtstp, NULL); + break; + } + + if (tty_flags_saved) + { + tcsetattr (fileno (tty), TCSAFLUSH, &ts); + } + + kill(getpid(), signal); +} + + int main (int argc, char *argv[]) { @@ -73,6 +106,8 @@ main (int argc, char *argv[]) GMainLoop *loop = NULL; guint ret = 126; GVariantBuilder builder; + struct sigaction sa; + const char *tty_name = NULL; g_type_init (); @@ -202,6 +237,27 @@ main (int argc, char *argv[]) } } +/* Bash leaves tty echo disabled if SIGINT/SIGTERM comes to polkitagenttextlistener.c::on_request(), + but due to threading the handlers cannot take care of the signal there. + Though if controlling terminal cannot be found, the world won't stop spinning. +*/ + tty_name = ctermid(NULL); + if (tty_name != NULL) + { + tty = fopen(tty_name, "r+"); + } + + if (tty != NULL && !tcgetattr (fileno (tty), &ts)) + { + tty_flags_saved = TRUE; + } + + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = &tty_handler; + sigaction (SIGTERM, &sa, &savesigterm); + sigaction (SIGINT, &sa, &savesigint); + sigaction (SIGTSTP, &sa, &savesigtstp); + loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop);