summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpankunull <panku_null@proton.me>2025-08-30 15:08:10 +0200
committerpankunull <panku_null@proton.me>2025-08-30 15:08:10 +0200
commit297e7abf41ec4be028b0a250c16c1ab800963d32 (patch)
tree9fdd00dc3a67f85f9cd8229caeee750ea22a79c2 /src
parent669fcb0b6be1085064267e817764fbb4f578a675 (diff)
Added feature 'all' (-a/--all) to show all processes running on the machine.
Instead of re-writing a new function, a simple flag was added (x->flag).
Diffstat (limited to 'src')
-rw-r--r--src/chproc.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/chproc.c b/src/chproc.c
new file mode 100644
index 0000000..46876a5
--- /dev/null
+++ b/src/chproc.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * chproc.c - simple process checker
+ *
+ * Iterate over /proc and print PIDs of processes matching the given name.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <getopt.h>
+#include <signal.h>
+#include <stdbool.h>
+
+#define PROGRAM_NAME "chproc"
+
+struct options {
+ int list;
+ int all;
+ int kill;
+ char *process_name;
+ char *process_pid;
+};
+
+
+static void options_init(struct options *x)
+{
+ x->list = false;
+ x->all = false;
+ x->kill = false;
+ x->process_pid = NULL;
+ x->process_name = NULL;
+}
+
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "Usage: %s <option> [process_name, pid]\n"
+ " -l, --list <name> list all pid for that process\n"
+ " -a, --all list all processes\n"
+ " -k, --kill <PID> kill a proces give then PID\n"
+ , PROGRAM_NAME);
+}
+
+
+
+static int process_list(DIR *dir,
+ const char *proc_name,
+ struct options *x)
+{
+ char path[PATH_MAX];
+ char buffer[256];
+ char *endptr;
+ FILE *f;
+ int count;
+ long pid;
+ struct dirent *entry;
+ size_t len;
+
+ count = 0;
+
+ while ((entry = readdir(dir)) != NULL) {
+ /* skip "." and ".." */
+ if (strcmp(entry->d_name, ".") == 0)
+ continue;
+ if (strcmp(entry->d_name, "..") == 0)
+ continue;
+
+
+ pid = strtol(entry->d_name, &endptr, 10);
+
+ if (*endptr != '\0') /* not a pure number */
+ continue;
+
+ snprintf(path, sizeof(path), "/proc/%ld/comm", pid);
+
+ f = fopen(path, "r");
+
+ if (!f) {
+ fprintf(stderr, "Failed to open %s: %s\n",
+ path, strerror(errno));
+ continue;
+ }
+
+ if (!(fgets(buffer, sizeof(buffer), f)))
+ continue;
+
+ len = strlen(buffer);
+
+ if (len > 0 && buffer[len-1] == '\n')
+ buffer[len-1] = '\0';
+
+ /* flag instead of re-writing a function */
+ if (x->list) {
+ if (strcmp(buffer, proc_name) == 0) {
+ printf("%s - %s\n", entry->d_name, buffer);
+ ++count;
+ }
+ } else {
+ printf("%s - %s\n", entry->d_name, buffer);
+ ++count;
+ }
+ fclose(f);
+ }
+
+ closedir(dir);
+
+ if (count == 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+static int process_kill(const char *process_id)
+{
+ pid_t pid;
+
+ if (atoi(process_id) < 1) {
+ fprintf(stderr, "'%s': not a pid or valid job\n", process_id);
+ usage();
+ return 1;
+ }
+
+ pid = (pid_t) atoi(process_id);
+
+ if (kill(pid, SIGTERM) == -1) {
+ perror("kill failed");
+ return 1;
+ }
+
+ printf("Process '%d' killed.\n", pid);
+ return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ DIR *dir_proc;
+
+ struct options x;
+
+ struct option long_options[] = {
+ {"list", required_argument, 0, 'l'},
+ {"all", no_argument, 0, 'a'},
+ {"kill", required_argument, 0, 'k'},
+ {0, 0, 0, 0}
+ };
+
+ options_init(&x);
+
+ /* /proc/ must to exist */
+ dir_proc = opendir("/proc");
+ if (dir_proc == NULL) {
+ fprintf(stderr, "/proc/ not found.\n");
+ return EXIT_FAILURE;
+ }
+
+ if (argc < 2) {
+ usage();
+ return 2;
+ }
+
+ while ((opt = getopt_long(argc, argv, "l:k:a",
+ long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'l':
+ x.list = true;
+ x.process_name = optarg;
+ break;
+ case 'a':
+ x.all = true;
+ break;
+ case 'k':
+ x.kill = true;
+ x.process_pid = optarg;
+ break;
+ default:
+ fprintf(stderr,
+ "Unknow option.\n");
+ usage();
+ exit(2);
+ }
+ }
+
+ if (x.list || x.all)
+ if (process_list(dir_proc, x.process_name, &x) == 1)
+ return 1;
+
+ if (x.kill)
+ if (process_kill(x.process_pid) == 1)
+ return 1;
+
+ return 0;
+}
+
+
+