Move process handling to a separate source file

This commit is contained in:
Konstantin Pereiaslov
2023-09-04 01:19:21 -05:00
parent 8ba84e47ec
commit f32da29ab9
5 changed files with 117 additions and 63 deletions

View File

@@ -4,7 +4,7 @@ CC=gcc
ifeq ($(PREFIX),)
PREFIX := /usr
endif
SOURCES = time_utils.c sleep_utils.c tty_utils.c main.c
SOURCES = time_utils.c sleep_utils.c tty_utils.c main.c process_handling.c
OBJECTS = $(SOURCES:.c=.o)
all: executable

64
main.c
View File

@@ -1,9 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <sys/wait.h>
#include <X11/extensions/scrnsaver.h>
#include <getopt.h>
@@ -14,6 +11,7 @@
#include "sleep_utils.h"
#include "time_utils.h"
#include "tty_utils.h"
#include "process_handling.h"
#ifndef VERSION
#define VERSION 'unkown'
@@ -41,44 +39,6 @@ volatile sig_atomic_t interruption_received = 0;
volatile sig_atomic_t command_paused = 0;
pid_t pid;
void handle_kill_error(char *signal_name, pid_t pid) {
const char *reason;
if (errno == EPERM) {
reason = "Operation not permitted";
} else if (errno == EINVAL) {
reason = "Invalid signal number";
} else if (errno == ESRCH) {
reason = "No such process";
}
printf("Failed to send %s signal to PID %i: %s\n", signal_name, pid, reason);
}
void send_signal_to_pid(pid_t pid, int signal, char *signal_name) {
if (debug) {
printf("Sending %s to %i\n",signal_name, pid);
}
int kill_result = kill(pid, signal);
if (kill_result == -1) {
handle_kill_error(signal_name, pid);
exit(1);
} else {
if (debug) fprintf(stderr, "kill function sending %s returned %i\n",signal_name, kill_result);
}
}
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");
}
void resume_command(pid_t pid) {
if (!quiet) {
printf("Resuming PID %i\n", pid);
}
send_signal_to_pid(pid, SIGCONT, "SIGCONT");
}
void print_usage(char *binary_name) {
printf("Usage: %s [OPTIONS] shell_command_to_run [shell_command_arguments]\n", binary_name);
@@ -94,26 +54,6 @@ void print_version() {
printf("runwhenidle %s\n", VERSION);
}
pid_t run_shell_command(const char *shell_command_to_run, pid_t pid) {
if (verbose) {
printf("Starting \"%s\"\n", shell_command_to_run);
}
pid = fork();
if (pid < 0) {
perror("fork");
exit(1);
} else if (pid == 0) {
// Child process
execl("/bin/sh", "sh", "-c", shell_command_to_run, (char *) NULL);
perror("execl");
exit(1);
}
if (!quiet) {
printf("Started \"%s\" with PID %i\n", shell_command_to_run, pid);
}
return pid;
}
void exit_if_pid_has_finished(pid_t pid) {
int status;
if (debug) fprintf(stderr, "Checking if PID %i has finished\n", pid);
@@ -370,7 +310,7 @@ int main(int argc, char *argv[]) {
fprintf_error("No available method for detecting user idle time on the system, user will be considered idle to allow the command to finish.");
}
pid = run_shell_command(shell_command_to_run, pid);
pid = run_shell_command(shell_command_to_run);
free(shell_command_to_run);
struct timespec time_when_command_started;
clock_gettime(CLOCK_MONOTONIC, &time_when_command_started);

7
output_settings.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef RUNWHENIDLE_OUTPUT_SETTINGS_H
#define RUNWHENIDLE_OUTPUT_SETTINGS_H
extern int verbose;
extern int quiet;
extern int debug;
#endif //RUNWHENIDLE_OUTPUT_SETTINGS_H

74
process_handling.c Normal file
View File

@@ -0,0 +1,74 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include "process_handling.h"
#include "output_settings.h"
pid_t run_shell_command(const char *shell_command_to_run) {
if (verbose) {
printf("Starting \"%s\"\n", shell_command_to_run);
}
pid_t pid = fork();
if (pid < 0) {
perror("fork");
exit(1);
} else if (pid == 0) {
// Child process
execl("/bin/sh", "sh", "-c", shell_command_to_run, (char *) NULL);
perror("execl");
exit(1);
}
if (!quiet) {
printf("Started \"%s\" with PID %i\n", shell_command_to_run, pid);
}
return pid;
}
/**
* Handles errors that may occur while sending a signal to a process.
*
* @param signal_name The name of the signal being sent.
* @param pid The process ID of the target process.
*/
void handle_kill_error(char *signal_name, pid_t pid) {
const char *reason;
if (errno == EPERM) {
reason = "Operation not permitted";
} else if (errno == EINVAL) {
reason = "Invalid signal number";
} else if (errno == ESRCH) {
reason = "No such process";
}
fprintf(stderr, "Failed to send %s signal to PID %i: %s\n", signal_name, pid, reason);
}
void send_signal_to_pid(pid_t pid, int signal, char *signal_name) {
if (debug) {
printf("Sending %s to %i\n",signal_name, pid);
}
int kill_result = kill(pid, signal);
if (kill_result == -1) {
handle_kill_error(signal_name, pid);
exit(1);
} else {
if (debug) fprintf(stderr, "kill function sending %s returned %i\n",signal_name, kill_result);
}
}
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");
}
void resume_command(pid_t pid) {
if (!quiet) {
printf("Resuming PID %i\n", pid);
}
send_signal_to_pid(pid, SIGCONT, "SIGCONT");
}

33
process_handling.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef RUNWHENIDLE_PROCESS_HANDLING_H
#define RUNWHENIDLE_PROCESS_HANDLING_H
/**
* Sends a signal to a specified process and handles any errors that occur during the process.
*
* @param pid The process ID of the target process.
* @param signal The signal to send.
* @param signal_name The name of the signal being sent.
*/
void send_signal_to_pid(pid_t pid, int signal, char *signal_name);
/**
* Pauses a specified process by sending the SIGTSTP signal.
*
* @param pid The process ID of the target process.
*/
void pause_command(pid_t pid);
/**
* Resumes a specified process by sending the SIGCONT signal.
*
* @param pid The process ID of the target process.
*/
void resume_command(pid_t pid);
/**
* Executes a shell command in a new process and returns the process ID of the child process.
* On failure will exit.
*
* @param shell_command_to_run The shell command to execute.
* @return The PID of the child process on success,
*/
pid_t run_shell_command(const char *shell_command_to_run);
#endif //RUNWHENIDLE_PROCESS_HANDLING_H