#include extern struct uwsgi_server uwsgi; void uwsgi_systemd_notify(char *message) { struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object; struct iovec *iovec = msghdr->msg_iov; iovec[0].iov_base = "STATUS="; iovec[0].iov_len = 7; iovec[1].iov_base = message; iovec[1].iov_len = strlen(message); iovec[2].iov_base = "\n"; iovec[2].iov_len = 1; msghdr->msg_iovlen = 3; if (sendmsg(uwsgi.notification_fd, msghdr, 0) < 0) { uwsgi_error("sendmsg()"); } } void uwsgi_systemd_notify_ready(void) { struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object; struct iovec *iovec = msghdr->msg_iov; iovec[0].iov_base = "STATUS=uWSGI is ready\nREADY=1\n"; iovec[0].iov_len = 30; msghdr->msg_iovlen = 1; if (sendmsg(uwsgi.notification_fd, msghdr, 0) < 0) { uwsgi_error("sendmsg()"); } } void uwsgi_systemd_init(char *systemd_socket) { struct sockaddr_un *sd_sun; struct msghdr *msghdr; uwsgi.notification_fd = socket(AF_UNIX, SOCK_DGRAM, 0); if (uwsgi.notification_fd < 0) { uwsgi_error("socket()"); return; } size_t len = strlen(systemd_socket); sd_sun = uwsgi_malloc(sizeof(struct sockaddr_un)); memset(sd_sun, 0, sizeof(struct sockaddr_un)); sd_sun->sun_family = AF_UNIX; strncpy(sd_sun->sun_path, systemd_socket, UMIN(len, sizeof(sd_sun->sun_path))); if (sd_sun->sun_path[0] == '@') sd_sun->sun_path[0] = 0; msghdr = uwsgi_malloc(sizeof(struct msghdr)); memset(msghdr, 0, sizeof(struct msghdr)); msghdr->msg_iov = uwsgi_malloc(sizeof(struct iovec) * 3); memset(msghdr->msg_iov, 0, sizeof(struct iovec) * 3); msghdr->msg_name = sd_sun; msghdr->msg_namelen = sizeof(struct sockaddr_un) - (sizeof(sd_sun->sun_path) - len); uwsgi.notification_object = msghdr; uwsgi.notify = uwsgi_systemd_notify; uwsgi.notify_ready = uwsgi_systemd_notify_ready; } int uwsgi_notify_socket_manage(int fd) { char buf[8192]; ssize_t rlen = read(fd, buf, 8192); if (rlen < 0) { if (uwsgi_is_again()) return 0; uwsgi_error("uwsgi_notify_socket_manage()/read()"); exit(1); } if (rlen > 0) { uwsgi_log_verbose("[notify-socket] %.*s\n", rlen, buf); } return 0; } int uwsgi_notify_msg(char *dst, char *msg, size_t len) { static int notify_fd = -1; if (notify_fd < 0) { notify_fd = socket(AF_UNIX, SOCK_DGRAM, 0); if (notify_fd < 0) { uwsgi_error("uwsgi_notify_msg()/socket()"); return -1; } } struct sockaddr_un un_addr; memset(&un_addr, 0, sizeof(struct sockaddr_un)); un_addr.sun_family = AF_UNIX; // use 102 as the magic number strncat(un_addr.sun_path, dst, 102); if (sendto(notify_fd, msg, len, 0, (struct sockaddr *) &un_addr, sizeof(un_addr)) < 0) { return -1; } return 0; }