From 6c4de929dab820c2a169abaae1f200265cc9d63a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 May 2026 19:05:53 +0000 Subject: [PATCH 1/5] limit_process: remove unnecessary EINTR retry on kill() kill() is a non-blocking system call that cannot be interrupted by signals, so it never returns EINTR per POSIX. Remove the do/while loop and call kill() directly to simplify the code. --- src/limit_process.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/limit_process.c b/src/limit_process.c index fe53e960..9456e7b7 100644 --- a/src/limit_process.c +++ b/src/limit_process.c @@ -187,9 +187,7 @@ static void send_signal_to_processes(struct process_group *proc_group, int sig, continue; } pid = ((const struct process *)node->data)->pid; - do { - kill_result = kill(pid, sig); - } while (kill_result != 0 && errno == EINTR); + kill_result = kill(pid, sig); if (kill_result != 0) { /* @@ -197,8 +195,9 @@ static void send_signal_to_processes(struct process_group *proc_group, int sig, * - ESRCH: Process no longer exists * - EPERM: Permission denied (rare in this context) * - * EINTR is transient and retried above, so all failures here - * indicate a process that can no longer be reliably controlled. + * kill() is non-blocking and cannot fail with EINTR, so any + * failure here indicates a process that can no longer be + * reliably controlled. * Save errno before any other calls that may clobber it. */ int saved_errno = errno; From 2fb8a04315e14fdadf8c7af11b0e2f86151c08a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 May 2026 19:06:52 +0000 Subject: [PATCH 2/5] list: reuse init_list() to reset state in clear_list/destroy_list Both clear_list() and destroy_list() manually reset first, last, and count after freeing nodes. Replace the manual reset with a call to init_list() which performs the equivalent operation via memset, reducing code duplication and ensuring consistency if the struct layout changes in the future. --- src/list.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/list.c b/src/list.c index 5b729874..7c807f39 100644 --- a/src/list.c +++ b/src/list.c @@ -246,8 +246,7 @@ void clear_list(struct list *lst) { free(current_node); } /* Reset list to empty state */ - lst->first = lst->last = NULL; - lst->count = 0; + init_list(lst); } /** @@ -273,6 +272,5 @@ void destroy_list(struct list *lst) { free(current_node); } /* Reset list to empty state */ - lst->first = lst->last = NULL; - lst->count = 0; + init_list(lst); } From d636bfa635e0f4c26b937776612272d09c736af5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 May 2026 19:07:05 +0000 Subject: [PATCH 3/5] process_table: remove unnecessary (void *) cast in free() call In C, any object pointer type implicitly converts to void * when passed to free(). The explicit cast adds visual noise without any semantic benefit. --- src/process_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/process_table.c b/src/process_table.c index 557f745b..1c93fb46 100644 --- a/src/process_table.c +++ b/src/process_table.c @@ -256,7 +256,7 @@ void destroy_process_table(struct process_table *proc_table) { } } /* Free the bucket array itself */ - free((void *)proc_table->buckets); + free(proc_table->buckets); proc_table->buckets = NULL; proc_table->hash_size = 0; } From cb1ceeb8ce203f023c1450e8df36cff6f20e8eca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 May 2026 19:08:05 +0000 Subject: [PATCH 4/5] limiter: remove unnecessary EINTR retry on access() access() is a non-blocking filesystem metadata operation that is not specified to return EINTR per POSIX. Remove the do/while loop and call access() directly, also removing the now-unused access_result variable. --- src/limiter.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/limiter.c b/src/limiter.c index aaa540c0..3a1cf609 100644 --- a/src/limiter.c +++ b/src/limiter.c @@ -98,7 +98,6 @@ */ static int is_script_inaccessible_interpreter(const char *path) { int fd; - int access_result; int saved_errno; char buf[256]; ssize_t n; @@ -147,10 +146,7 @@ static int is_script_inaccessible_interpreter(const char *path) { } /* Interpreter path is inaccessible -> report 126 */ - do { - access_result = access(p, F_OK); - } while (access_result != 0 && errno == EINTR); - return access_result != 0; + return access(p, F_OK) != 0; } /** From 2875d051fcea8237598e57225d471151086934a2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 May 2026 19:11:04 +0000 Subject: [PATCH 5/5] ci: add missing check target to gcc/clang build loops --- .github/workflows/CI.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5c1ee790..75a221d8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -160,6 +160,7 @@ jobs: -DCMAKE_BUILD_TYPE=Release \ -B build cmake --build build + cmake --build build --target check done rm -rf build @@ -234,6 +235,7 @@ jobs: -DCMAKE_BUILD_TYPE=Release \ -B build cmake --build build + cmake --build build --target check done rm -rf build