Add pause method argument and support SIGSTOP

This commit is contained in:
Konstantin Pereiaslov
2023-09-04 21:01:30 -05:00
parent d61c15ab0f
commit 34f502fb2c
5 changed files with 62 additions and 6 deletions

View File

@@ -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.

View File

@@ -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<sizeof(method); i++) {
method[i] = toupper(method[i]);
}
for (int i = 1; pause_method_string[i] != NULL; i++) {
if (strcmp(pause_method_string[i], method) == 0) {
pause_method = i;
break;
}
}
if (!pause_method) {
fprintf_error("Invalid value for --pause-method|m argument: \"%s\". Supported values: ", optarg);
for (int i=1; pause_method_string[i] != NULL; i++) {
fprintf_error(pause_method_string[i]);
if (pause_method_string[i+1] != NULL) {
fprintf_error(", ");
}
}
fprintf_error("\n");
exit(1);
}
break;
case 'V':
print_version();
exit(0);
@@ -128,7 +150,7 @@ char *parse_command_line_arguments(int argc, char *argv[]) {
exit(1);
}
}
if (debug) fprintf(stderr, "verbose: %i, debug: %i, quiet: %i, user_idle_timeout_ms: %i, start_monitoring_after_ms: %lld\n", verbose, debug, quiet, user_idle_timeout_ms, start_monitor_after_ms);
if (debug) fprintf(stderr, "verbose: %i, debug: %i, quiet: %i, pause_method:%i, user_idle_timeout_ms: %i, start_monitoring_after_ms: %lld\n", verbose, debug, quiet, pause_method, user_idle_timeout_ms, start_monitor_after_ms);
if (optind >= argc) {
print_usage(argv[0]);
exit(1);

9
main.c
View File

@@ -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;

16
pause_methods.h Normal file
View File

@@ -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

View File

@@ -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) {