aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-07-17 11:04:28 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-17 11:04:28 +0200
commit137a18719ce8006697bb104c9ea94115557b7966 (patch)
tree4ba3c05be44d9ea89b3a3d624e3329b75dd79304
parent2647edb121b2ad11b839fd5edb92247645597263 (diff)
Fix automedia.pid always being overwritten
-rwxr-xr-xautomediabin112552 -> 112552 bytes
-rw-r--r--src/main.c63
2 files changed, 47 insertions, 16 deletions
diff --git a/automedia b/automedia
index 3e5fb01..92f3f31 100755
--- a/automedia
+++ b/automedia
Binary files differ
diff --git a/src/main.c b/src/main.c
index e5c5321..c9a9bb3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include <assert.h>
#include <dirent.h>
#include <libgen.h>
@@ -273,6 +274,12 @@ int is_program_running() {
/* plugin is NULL for rss */
typedef int (*IterateTrackedItemCallback)(char *title, char *link, char *plugin, char *config_dir, struct json_object_s *json_data, void *userdata);
static void iterate_tracked_items(char *config_dir, IterateTrackedItemCallback iterate_callback, void *userdata) {
+ /*
+ TODO: Only iterate updated items. To make that work, sync_rss and sync_html need to be updated to update
+ the json_object with new downloaded items (and not only temporary downloaded items) and then also only
+ clean them up!
+ */
+
char tracked_dir[PATH_MAX];
strcpy(tracked_dir, config_dir);
strcat(tracked_dir, "/tracked");
@@ -458,8 +465,9 @@ static void sync_rss_html(char *rss_config_dir, char *html_config_dir, char *pro
free(unfinished_torrents.items);
}
-static int cmdline_contains_str(const char *cmdline, const char *str) {
- for(;;) {
+static int cmdline_contains_str(const char *cmdline, int cmdline_len, const char *str) {
+ const char *start = cmdline;
+ while(cmdline - start < cmdline_len) {
int arg_len = strlen(cmdline);
if(arg_len == 0)
return -1;
@@ -467,8 +475,35 @@ static int cmdline_contains_str(const char *cmdline, const char *str) {
if(strstr(cmdline, str))
return 0;
- cmdline += arg_len;
+ cmdline += arg_len + 1;
+ }
+ return -1;
+}
+
+/* We can't use file_get_content because reading the size of /proc/<pid>/cmdline fails (returns 0) because its not a regular file */
+static int proc_read_cmdline(const char *pid_str, char *cmdline_data, int cmdline_data_size, int *cmdline_data_size_output) {
+ assert(cmdline_data_size > 0);
+
+ char cmdline_file_path[128];
+ sprintf(cmdline_file_path, "/proc/%s/cmdline", pid_str);
+
+ int cmdline_fd = open(cmdline_file_path, O_RDONLY);
+ if(cmdline_fd == -1) {
+ fprintf(stderr, "Process %s doesn't exist\n", pid_str);
+ return -1;
+ }
+
+ ssize_t bytes_read = read(cmdline_fd, cmdline_data, cmdline_data_size - 1);
+ if(bytes_read == -1) {
+ fprintf(stderr, "Failed to read %s\n", cmdline_file_path);
+ close(cmdline_fd);
+ return -1;
}
+
+ cmdline_data[bytes_read] = '\0';
+ *cmdline_data_size_output = bytes_read;
+ close(cmdline_fd);
+ return 0;
}
static void command_sync(int argc, char **argv, char *rss_config_dir, char *html_config_dir, char *program_dir) {
@@ -483,6 +518,7 @@ static void command_sync(int argc, char **argv, char *rss_config_dir, char *html
exit(1);
}
+ /* Create a pid file because we only want to allow one instance of automedia to run at once */
int pid_file = open(automedia_pid_path, O_CREAT | O_EXCL | O_SYNC | O_RDWR, 0666);
if(pid_file == -1 && errno == EEXIST) {
char *running_automedia_pid;
@@ -492,23 +528,18 @@ static void command_sync(int argc, char **argv, char *rss_config_dir, char *html
We have to check the cmdline because another process could theoretically receive the pid
that an old automedia process had
*/
- char cmdline_file_path[128];
- sprintf(cmdline_file_path, "/proc/%s/cmdline", running_automedia_pid);
- free(running_automedia_pid);
-
- char *cmdline;
- long cmdline_size;
- if(file_get_content(cmdline_file_path, &cmdline, &cmdline_size) == 0
- && cmdline_contains_str(cmdline, "automedia") == 0
- && cmdline_contains_str(cmdline, "sync") == 0) {
- fprintf(stderr, "Automedia is already running with sync");
- free(cmdline);
+ char cmdline[1024];
+ int cmdline_size;
+ if(proc_read_cmdline(running_automedia_pid, cmdline, sizeof(cmdline), &cmdline_size) == 0
+ && cmdline_contains_str(cmdline, cmdline_size, "automedia") == 0
+ && cmdline_contains_str(cmdline, cmdline_size, "sync") == 0) {
+ fprintf(stderr, "Automedia is already running with sync\n");
+ free(running_automedia_pid);
exit(0);
}
- free(cmdline);
+ free(running_automedia_pid);
} else {
fprintf(stderr, "Failed to get content of %s\n", automedia_pid_path);
- free(running_automedia_pid);
exit(1);
}