1 #include "uwsgi.h"
2
3 extern struct uwsgi_server uwsgi;
4
5
6
uwsgi_systemd_notify(char * message)7 void uwsgi_systemd_notify(char *message) {
8
9 struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object;
10 struct iovec *iovec = msghdr->msg_iov;
11
12 iovec[0].iov_base = "STATUS=";
13 iovec[0].iov_len = 7;
14
15 iovec[1].iov_base = message;
16 iovec[1].iov_len = strlen(message);
17
18 iovec[2].iov_base = "\n";
19 iovec[2].iov_len = 1;
20
21 msghdr->msg_iovlen = 3;
22
23 if (sendmsg(uwsgi.notification_fd, msghdr, 0) < 0) {
24 uwsgi_error("sendmsg()");
25 }
26 }
27
uwsgi_systemd_notify_ready(void)28 void uwsgi_systemd_notify_ready(void) {
29
30 struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object;
31 struct iovec *iovec = msghdr->msg_iov;
32
33 iovec[0].iov_base = "STATUS=uWSGI is ready\nREADY=1\n";
34 iovec[0].iov_len = 30;
35
36 msghdr->msg_iovlen = 1;
37
38 if (sendmsg(uwsgi.notification_fd, msghdr, 0) < 0) {
39 uwsgi_error("sendmsg()");
40 }
41 }
42
43
uwsgi_systemd_init(char * systemd_socket)44 void uwsgi_systemd_init(char *systemd_socket) {
45
46 struct sockaddr_un *sd_sun;
47 struct msghdr *msghdr;
48
49 uwsgi.notification_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
50 if (uwsgi.notification_fd < 0) {
51 uwsgi_error("socket()");
52 return;
53 }
54
55 size_t len = strlen(systemd_socket);
56 sd_sun = uwsgi_malloc(sizeof(struct sockaddr_un));
57 memset(sd_sun, 0, sizeof(struct sockaddr_un));
58 sd_sun->sun_family = AF_UNIX;
59 strncpy(sd_sun->sun_path, systemd_socket, UMIN(len, sizeof(sd_sun->sun_path)));
60 if (sd_sun->sun_path[0] == '@')
61 sd_sun->sun_path[0] = 0;
62
63 msghdr = uwsgi_malloc(sizeof(struct msghdr));
64 memset(msghdr, 0, sizeof(struct msghdr));
65
66 msghdr->msg_iov = uwsgi_malloc(sizeof(struct iovec) * 3);
67 memset(msghdr->msg_iov, 0, sizeof(struct iovec) * 3);
68
69 msghdr->msg_name = sd_sun;
70 msghdr->msg_namelen = sizeof(struct sockaddr_un) - (sizeof(sd_sun->sun_path) - len);
71
72 uwsgi.notification_object = msghdr;
73
74 uwsgi.notify = uwsgi_systemd_notify;
75 uwsgi.notify_ready = uwsgi_systemd_notify_ready;
76
77 }
78
uwsgi_notify_socket_manage(int fd)79 int uwsgi_notify_socket_manage(int fd) {
80 char buf[8192];
81 ssize_t rlen = read(fd, buf, 8192);
82 if (rlen < 0) {
83 if (uwsgi_is_again()) return 0;
84 uwsgi_error("uwsgi_notify_socket_manage()/read()");
85 exit(1);
86 }
87
88 if (rlen > 0) {
89 uwsgi_log_verbose("[notify-socket] %.*s\n", rlen, buf);
90 }
91
92 return 0;
93 }
94
uwsgi_notify_msg(char * dst,char * msg,size_t len)95 int uwsgi_notify_msg(char *dst, char *msg, size_t len) {
96 static int notify_fd = -1;
97 if (notify_fd < 0) {
98 notify_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
99 if (notify_fd < 0) {
100 uwsgi_error("uwsgi_notify_msg()/socket()");
101 return -1;
102 }
103 }
104 struct sockaddr_un un_addr;
105 memset(&un_addr, 0, sizeof(struct sockaddr_un));
106 un_addr.sun_family = AF_UNIX;
107 // use 102 as the magic number
108 strncat(un_addr.sun_path, dst, 102);
109 if (sendto(notify_fd, msg, len, 0, (struct sockaddr *) &un_addr, sizeof(un_addr)) < 0) {
110 return -1;
111 }
112 return 0;
113 }
114