return fd;
}
-static int pakfire_cgroup_access(struct pakfire_cgroup* cgroup, const char* path,
- int mode, int flags) {
- return faccessat(cgroup->fd, path, mode, flags);
-}
-
-static FILE* pakfire_cgroup_open_file(struct pakfire_cgroup* cgroup,
- const char* path, const char* mode) {
- FILE* f = NULL;
-
- // Open cgroup.procs
- int fd = openat(cgroup->fd, "cgroup.procs", O_CLOEXEC);
- if (fd < 0) {
- ERROR(cgroup->ctx, "%s: Could not open %s: %m\n",
- pakfire_cgroup_name(cgroup), path);
- goto ERROR;
- }
-
- // Convert into file handle
- f = fdopen(fd, mode);
- if (!f)
- goto ERROR;
-
-ERROR:
- if (fd > 0)
- close(fd);
-
- return f;
-}
-
static ssize_t pakfire_cgroup_read(struct pakfire_cgroup* cgroup, const char* path,
char* buffer, size_t length) {
ssize_t bytes_read = -1;
return pakfire_cgroup_open(child, cgroup->ctx, p, flags);
}
-static int pakfire_cgroup_procs_callback(struct pakfire_cgroup* cgroup,
- int (*callback)(struct pakfire_cgroup* cgroup, pid_t pid, void* data), void* data) {
- int r = 0;
-
- // Check if we have a callback
- if (!callback) {
- errno = EINVAL;
- return 1;
- }
-
- // Open cgroup.procs
- FILE* f = pakfire_cgroup_open_file(cgroup, "cgroup.procs", "r");
- if (!f)
- return 1;
-
- char* line = NULL;
- size_t l = 0;
-
- // Walk through all PIDs
- while (1) {
- ssize_t bytes_read = getline(&line, &l, f);
- if (bytes_read < 0)
- break;
-
- // Parse PID
- pid_t pid = strtol(line, NULL, 10);
-
- // Call callback function
- r = callback(cgroup, pid, data);
- if (r)
- break;
- }
-
- // Cleanup
- if (line)
- free(line);
- if (f)
- fclose(f);
-
- return r;
-}
-
-static int send_sigkill(struct pakfire_cgroup* cgroup, const pid_t pid, void* data) {
- DEBUG(cgroup->ctx, "Sending signal SIGKILL to PID %d\n", pid);
-
- int r = kill(pid, SIGKILL);
- if (r < 0 && errno != ESRCH) {
- ERROR(cgroup->ctx, "Could not send signal SIGKILL to PID %d: %m\n", pid);
- return r;
- }
-
- return r;
-}
-
/*
Immediately kills all processes in this cgroup
*/
static int pakfire_cgroup_killall(struct pakfire_cgroup* cgroup) {
DEBUG(cgroup->ctx, "%s: Killing all processes\n", pakfire_cgroup_name(cgroup));
- // Do we have support for cgroup.kill?
- int r = pakfire_cgroup_access(cgroup, "cgroup.kill", F_OK, 0);
-
- // Fall back to the legacy version
- if (r && errno == ENOENT) {
- return pakfire_cgroup_procs_callback(cgroup, send_sigkill, NULL);
- }
-
return pakfire_cgroup_write(cgroup, "cgroup.kill", "1");
}