2 #include "logger_internal.h"
5 * @brief Create a bound socket
6 * @details Creates a socket of given type under the given path
7 * @param[in] path The path to the socket
8 * @param[in] type Socket type (SOCK_DGRAM or SOCK_STREAM) with flags
9 * @return The socket FD, or negative errno
11 int bind_fd_create(const char *path, int type)
13 struct sockaddr_un server_addr;
16 sd = socket(AF_UNIX, type, 0);
20 memset(&server_addr, 0, sizeof(server_addr));
21 server_addr.sun_family = AF_UNIX;
22 strncpy(server_addr.sun_path, path, sizeof(server_addr.sun_path)-1);
23 unlink(server_addr.sun_path);
25 if (bind(sd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
36 * @brief Create a listening socket
37 * @details Creates a socket with given permissions under the given path
38 * @param[in] path The path to the socket
39 * @param[in] permissions File permissions (the internal representation)
40 * @return The socket FD, or negative errno
42 int listen_fd_create(const char *path, int permissions)
44 int sd = bind_fd_create(path, SOCK_STREAM);
49 if (chmod(path, permissions) < 0) // ideally, fchmod would be used, but that does not work
52 if (listen(sd, MAX_CONNECTION_Q) < 0)
63 * @brief Dispatch socket event
64 * @details Receives and handles an event
65 * @param[in] server The logger server
66 * @param[in] event The received event
68 void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata)
71 struct sock_data const *const sock = (struct sock_data const * const) userdata;
74 int sock_pipe = accept4(sock->fd_entity.fd, NULL, NULL, SOCK_NONBLOCK);
76 check_if_fd_limit_reached(server, errno);
80 struct writer *writer;
81 if (writer_create(&writer, sock_pipe, sock->buf_ptr, service_writer_socket, sock->service_socket) != 0) {
86 logger_add_writer(server, writer);
87 add_fd_entity(&server->epoll_socket, &writer->fd_entity);
91 * @brief Initialize a socket
92 * @details Initializes a socket
93 * @param[out] sock The socket to initialize
94 * @param[in] buffer The buffer to whom the socket belongs
95 * @param[in] type Type of the socket
96 * @param[in] data Socket config data
97 * @return 0 on success, else -errno
99 int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data)
102 int sock_fd = listen_fd_create(data->path, data->permissions);
106 init_fd_entity(&sock->fd_entity, dispatch_event_sock, sock);
107 sock->service_socket = service_socket;
108 sock->buf_ptr = buffer;
109 set_read_fd_entity(&sock->fd_entity, sock_fd);
115 * @brief Close socket that was initialized using socket_initialize function
116 * @details Closes socket entity fd
117 * @param[in] sock socet data to close
119 void socket_close(struct sock_data *sock)
122 if (sock->fd_entity.fd >= 0)
123 close(sock->fd_entity.fd);
126 int systemd_sock_get(const char *path, int type)
129 int n = sd_listen_fds(0);
132 for (i = SD_LISTEN_FDS_START; sock_fd < 0 && i < SD_LISTEN_FDS_START + n; i++)
133 if (sd_is_socket_unix(i, type, -1, path, 0) > 0)
139 /* TODO: move the path to the configuration */
140 static const char dev_log_sock[] = "/run/dlog/dev-log";
141 static const char dev_log_link[] = "/dev/log";
143 int dev_log_sock_get(void)
145 return systemd_sock_get(dev_log_sock, SOCK_DGRAM);
148 int dev_log_sock_create(void)
150 int fd = bind_fd_create(dev_log_sock, SOCK_DGRAM);
152 unlink(dev_log_link);
153 if (symlink(dev_log_sock, dev_log_link) == -1) {