From 34f502fb2c4bd7f9731c89684594ebbcec4d9d74 Mon Sep 17 00:00:00 2001 From: Konstantin Pereiaslov Date: Mon, 4 Sep 2023 21:01:30 -0500 Subject: [PATCH] Add pause method argument and support SIGSTOP --- README.md | 2 +- arguments_parsing.c | 28 +++++++++++++++++++++++++--- main.c | 9 ++++++++- pause_methods.h | 16 ++++++++++++++++ process_handling.c | 13 ++++++++++++- 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 pause_methods.h diff --git a/README.md b/README.md index 4cf646a..0dc2ca3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ runwhenidle is a Linux utility that can be used to run a computationally or IO-i in front of the computer, pausing it once the user is back, resuming once the user left, often without requiring adaptation from the program being ran. -runwhenidle runs a command given to it, pauses it if the user is active by sending SIGTSTP to the command, +runwhenidle runs a command given to it, pauses it if the user is active by sending SIGTSTP (or optionally SIGSTOP) to the command, when the user activity stops, runwhenidle resumes the command by sending it SIGCONT signal. It then checks once per second if user activity has resumed, and once it is, pauses the command again. diff --git a/arguments_parsing.c b/arguments_parsing.c index 689db3a..db0e1f5 100644 --- a/arguments_parsing.c +++ b/arguments_parsing.c @@ -82,7 +82,7 @@ char *parse_command_line_arguments(int argc, char *argv[]) { // Parse command line options int option; - while ((option = getopt_long(argc, argv, "+hvqt:a:V", long_options, NULL)) != -1) { + while ((option = getopt_long(argc, argv, "+hvqt:a:m:V", long_options, NULL)) != -1) { switch (option) { case 't': long timeout_arg_value = strtol(optarg, NULL, 10); @@ -106,7 +106,29 @@ char *parse_command_line_arguments(int argc, char *argv[]) { exit(1); } break; - } + case 'm': + char *method = strdup(optarg); + for (int i = 0; i= argc) { print_usage(argv[0]); exit(1); diff --git a/main.c b/main.c index 42a9a4f..109d2e9 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,7 @@ #include "tty_utils.h" #include "process_handling.h" #include "arguments_parsing.h" +#include "pause_methods.h" #ifndef VERSION #define VERSION 'unkown' @@ -19,11 +20,17 @@ int verbose = 0; int quiet = 0; int debug = 0; int monitoring_started = 0; +enum pause_method pause_method; long start_monitor_after_ms = 300; long unsigned user_idle_timeout_ms = 300000; long long polling_interval_ms = 1000; const long long POLLING_INTERVAL_BEFORE_STARTING_MONITORING_MS = 100; - +const char *pause_method_string[] = { + //order must match order in pause_method enum + [PAUSE_METHOD_SIGTSTP] = "SIGTSTP", + [PAUSE_METHOD_SIGSTOP] = "SIGSTOP", + NULL // Sentinel value to indicate the end of the array +}; int xscreensaver_is_available; Display *x_display; XScreenSaverInfo *xscreensaver_info; diff --git a/pause_methods.h b/pause_methods.h new file mode 100644 index 0000000..7c61ca8 --- /dev/null +++ b/pause_methods.h @@ -0,0 +1,16 @@ +// +// Created by perk11 on 9/5/23. +// + +#ifndef RUNWHENIDLE_PAUSE_METHODS_H +#define RUNWHENIDLE_PAUSE_METHODS_H + +enum pause_method { + //order must match order in pause_method_string + PAUSE_METHOD_SIGTSTP = 1, + PAUSE_METHOD_SIGSTOP = 2, +}; + +extern const char *pause_method_string[]; +extern enum pause_method pause_method; +#endif //RUNWHENIDLE_PAUSE_METHODS_H diff --git a/process_handling.c b/process_handling.c index 93160f1..404e507 100644 --- a/process_handling.c +++ b/process_handling.c @@ -7,6 +7,7 @@ #include "process_handling.h" #include "output_settings.h" +#include "pause_methods.h" pid_t run_shell_command(const char *shell_command_to_run) { if (verbose) { @@ -64,7 +65,17 @@ void pause_command(pid_t pid) { if (!quiet) { printf("User activity is detected, pausing PID %i\n", pid); } - send_signal_to_pid(pid, SIGTSTP, "SIGTSTP"); + switch (pause_method) { + case PAUSE_METHOD_SIGTSTP: + send_signal_to_pid(pid, SIGTSTP, "SIGTSTP"); + break; + case PAUSE_METHOD_SIGSTOP: + send_signal_to_pid(pid, SIGSTOP, "SIGSTOP"); + break; + default: + fprintf_error("Unsupported paused method: %i", pause_method ); + exit(1); + } } void resume_command(pid_t pid) {