1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#include "../../../plugins/utils/UniqueProcess.hpp"
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
namespace QuickMedia {
static bool is_process_running_program(pid_t pid, const char *program_name) {
char filepath[256];
snprintf(filepath, sizeof(filepath), "/proc/%ld/cmdline", (long)pid);
int fd = open(filepath, O_RDONLY);
if(fd == -1)
return false;
char buffer[PATH_MAX + 1];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
if(bytes_read == -1) {
close(fd);
return false;
}
buffer[bytes_read] = '\0';
char resolved_path[PATH_MAX + 1];
if(!realpath(buffer, resolved_path)) {
close(fd);
return false;
}
bytes_read = strlen(resolved_path);
resolved_path[bytes_read] = '\0';
const char *end = resolved_path + bytes_read;
const char *start = (const char*)memrchr(resolved_path, '/', bytes_read);
if(start)
start += 1;
else
start = buffer;
const size_t cmd_arg0_len = end - start;
const size_t program_name_len = strlen(program_name);
bool running = (cmd_arg0_len == program_name_len && memcmp(start, program_name, program_name_len) == 0);
close(fd);
return running;
}
bool is_quickmedia_instance_already_running(const char *pid_file_dir, const char *plugin_name) {
char pid_file[PATH_MAX];
snprintf(pid_file, sizeof(pid_file), "%s/quickmedia.%s.pid", pid_file_dir, plugin_name);
char buffer[256];
int fd = open(pid_file, O_RDONLY);
if(fd == -1)
return false;
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
if(bytes_read < 0) {
perror("failed to read quickmedia pid file");
close(fd);
return false;
}
buffer[bytes_read] = '\0';
close(fd);
bool running = false;
long pid = 0;
if(sscanf(buffer, "%ld", &pid) == 1) {
if(is_process_running_program(pid, "quickmedia")) {
fprintf(stderr, "Error: quickmedia %s is already running\n", plugin_name);
running = true;
}
} else {
fprintf(stderr, "Warning: quickmedia pid file is in incorrect format, it's possible that its corrupt. Replacing file and continuing...\n");
running = false;
}
if(!running)
unlink(pid_file);
return running;
}
bool set_quickmedia_instance_unique(const char *pid_file_dir, const char *plugin_name) {
char pid_file[PATH_MAX];
snprintf(pid_file, sizeof(pid_file), "%s/quickmedia.%s.pid", pid_file_dir, plugin_name);
int fd = open(pid_file, O_WRONLY|O_CREAT|O_TRUNC, 0777);
if(fd == -1) {
perror("failed to create quickmedia pid file");
return false;
}
bool success = true;
char buffer[256];
const int buffer_size = snprintf(buffer, sizeof(buffer), "%ld", (long)getpid());
if(write(fd, buffer, buffer_size) == -1) {
perror("failed to write quickmedia pid file");
success = false;
}
close(fd);
if(!success)
unlink(pid_file);
return success;
}
void remove_quickmedia_instance_lock(const char *pid_file_dir, const char *plugin_name) {
char pid_file[PATH_MAX];
snprintf(pid_file, sizeof(pid_file), "%s/quickmedia.%s.pid", pid_file_dir, plugin_name);
unlink(pid_file);
}
}
|