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
|
#include "../../../plugins/utils/UniqueProcess.hpp"
#include "../../../include/Storage.hpp"
#include <stdio.h>
#include <limits.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
namespace QuickMedia {
bool is_quickmedia_instance_already_running(const char *sock_file_dir, const char *plugin_name) {
char sock_file[PATH_MAX];
snprintf(sock_file, sizeof(sock_file), "%s/quickmedia.%s.sock", sock_file_dir, plugin_name);
std::string resolved_path;
if(file_get_content(sock_file, resolved_path) != 0)
return false;
resolved_path.resize(108); // sizeof(addr.sun_path) is 108
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(fd == -1) {
fprintf(stderr, "Error: failed to create unix domain socket, error: %s\n", strerror(errno));
return true;
}
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, resolved_path.c_str());
bool running = connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0;
int err = errno;
if(err == EAGAIN)
running = true;
else if(err == ENOENT)
running = false;
close(fd);
return running;
}
bool set_quickmedia_instance_unique(const char *sock_file_dir, const char *plugin_name) {
char socket_file[] = "/tmp/quickmedia.XXXXXX";
int tmp_file_fd = mkstemp(socket_file);
if(tmp_file_fd == -1) {
fprintf(stderr, "Error: failed to create temporary file for unix domain socket, error: %s\n", strerror(errno));
return false;
}
unlink(socket_file);
close(tmp_file_fd);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(fd == -1) {
fprintf(stderr, "Error: failed to create unix domain socket, error: %s\n", strerror(errno));
return false;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, socket_file);
if(bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
fprintf(stderr, "Error: failed to bind unix domain socket, error: %s\n", strerror(errno));
unlink(socket_file);
close(fd);
return false;
}
if(listen(fd, 0) == -1) {
fprintf(stderr, "Error: failed to listen to unix domain socket, error: %s\n", strerror(errno));
unlink(socket_file);
close(fd);
return false;
}
char sock_file[PATH_MAX];
snprintf(sock_file, sizeof(sock_file), "%s/quickmedia.%s.sock", sock_file_dir, plugin_name);
bool success = file_overwrite(sock_file, socket_file) == 0;
if(!success) {
fprintf(stderr, "Error: failed to create %s unix domain socket link file\n", sock_file);
unlink(socket_file);
close(fd);
}
return success;
}
void remove_quickmedia_instance_lock(const char *sock_file_dir, const char *plugin_name) {
char sock_file[PATH_MAX];
snprintf(sock_file, sizeof(sock_file), "%s/quickmedia.%s.sock", sock_file_dir, plugin_name);
std::string resolved_path;
if(file_get_content(sock_file, resolved_path) != 0) {
unlink(sock_file);
return;
}
resolved_path.resize(108); // sizeof(addr.sun_path) is 108
if(resolved_path.size() < 4 || memcmp(resolved_path.data(), "/tmp", 4) != 0) {
unlink(sock_file);
return;
}
unlink(sock_file);
unlink(resolved_path.c_str());
}
}
|