/* This file is part of genrc Copyryght (C) 2018 Sergey Poznyakoff License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. */ #include "genrc.h" struct file_pid_closure { struct genrc_pid_closure generic; char *filename; }; pid_t file_read_pid(char const *filename) { FILE *fp; char buf[256]; int n, ec, ok; unsigned long pid; char *end; fp = fopen(filename, "r"); if (!fp) { if (errno == ENOENT) return 0; system_error(errno, "can't open file %s", filename); return -1; } ok = fgets(buf, sizeof(buf), fp) != NULL; ec = errno; fclose(fp); if (!ok) { system_error(ec, "error reading from %s", filename); return -1; } n = strlen(buf); if (n == 0) { genrc_error("invalid line read from %s", filename); return -1; } if (buf[n-1] == '\n') buf[n-1] = 0; errno = 0; pid = strtoul(buf, &end, 10); if (errno || *end) { genrc_error("invalid line read from %s", filename); return -1; } return pid_is_running(pid) ? pid : 0; } static int pid_file_get(GENRC_PID_CLOSURE *clos, PIDLIST *plist) { struct file_pid_closure *file_clos = (struct file_pid_closure *)clos; pid_t pid = file_read_pid(file_clos->filename); if (pid == -1) return -1; if (pid > 0) pidlist_add(plist, pid); return 0; } GENRC_PID_CLOSURE * genrc_pid_file_init(int argc, char **argv) { struct file_pid_closure *clos; if (argc != 2) usage_error("%s: expected format: FILE:", argv[0]); clos = xmalloc(sizeof(*clos)); clos->generic.pid = pid_file_get; clos->filename = xstrdup(argv[1]); return (GENRC_PID_CLOSURE *)clos; }