src/logger/reader_common.c \
src/logger/reader_logger.c \
src/logger/reader_pipe.c \
+ src/logger/socket.c \
src/shared/backend_androidlogger.c \
src/shared/ptrs_list.c \
src/shared/logcommon.c \
*/
// function prototypes
-static int service_writer_socket(struct logger* server, struct writer* wr, struct epoll_event* event);
static int service_writer_pipe(struct logger* server, struct writer* wr, struct epoll_event* event);
int service_writer_kmsg(struct logger* server, struct writer* wr, struct epoll_event* event);
int service_writer_syslog(struct logger* server, struct writer* wr, struct epoll_event* event);
static int service_writer_handle_req_ctrl(struct logger *server, struct writer *wr, struct dlog_control_msg *msg);
static int service_writer_handle_req_pipe(struct logger *server, struct writer *wr, struct dlog_control_msg *msg);
void dispatch_event_writer(struct logger *server, struct epoll_event *event, void *userdata);
-void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata);
static void logger_free(struct logger* l);
-int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data);
static int initialize_epoll_size(struct epoll_event **events, unsigned *size);
/** global state when logger is not interrupted by any handled signals */
}
/**
- * @brief Create a bound socket
- * @details Creates a socket of given type under the given path
- * @param[in] path The path to the socket
- * @param[in] type Socket type (SOCK_DGRAM or SOCK_STREAM) with flags
- * @return The socket FD, or negative errno
- */
-int bind_fd_create(const char* path, int type)
-{
- struct sockaddr_un server_addr;
- int sd;
-
- sd = socket(AF_UNIX, type, 0);
- if (sd == -1)
- return -errno;
-
- memset(&server_addr, 0, sizeof(server_addr));
- server_addr.sun_family = AF_UNIX;
- strncpy(server_addr.sun_path, path, sizeof(server_addr.sun_path)-1);
- unlink(server_addr.sun_path);
-
- if (bind(sd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
- goto failure;
-
- return sd;
-
-failure:
- close(sd);
- return -errno;
-}
-
-/**
- * @brief Create a listening socket
- * @details Creates a socket with given permissions under the given path
- * @param[in] path The path to the socket
- * @param[in] permissions File permissions (the internal representation)
- * @return The socket FD, or negative errno
- */
-int listen_fd_create(const char* path, int permissions)
-{
- int sd = bind_fd_create(path, SOCK_STREAM);
- if (sd < 0)
- return sd;
-
- if (permissions)
- if (chmod(path, permissions) < 0) // ideally, fchmod would be used, but that does not work
- goto failure;
-
- if (listen(sd, MAX_CONNECTION_Q) < 0)
- goto failure;
-
- return sd;
-
-failure:
- close(sd);
- return -errno;
-}
-
-/**
* @brief Create a writer
* @details Create a writer structure
* @param[out] writer The newly-allocated writer
return ret;
}
-int systemd_sock_get(const char *path, int type)
-{
- int sock_fd = -1;
- int n = sd_listen_fds(0);
- if (n > 0) {
- int i;
- for (i = SD_LISTEN_FDS_START; sock_fd < 0 && i < SD_LISTEN_FDS_START + n; i++)
- if (sd_is_socket_unix(i, type, -1, path, 0) > 0)
- sock_fd = i;
- }
- return sock_fd;
-}
-
-/* TODO: move the path to the configuration */
-static const char dev_log_sock[] = "/run/dlog/dev-log";
-static const char dev_log_link[] = "/dev/log";
-
-int dev_log_sock_get()
-{
- return systemd_sock_get(dev_log_sock, SOCK_DGRAM);
-}
-
-int dev_log_sock_create()
-{
- int fd = bind_fd_create(dev_log_sock, SOCK_DGRAM);
- if (fd >= 0) {
- unlink(dev_log_link);
- if (symlink(dev_log_sock, dev_log_link) == -1) {
- close(fd);
- fd = -errno;
- }
- }
- return fd;
-}
-
/**
* @brief Create syslog writer
* @details Create the structure responsible for handling writing data from syslog to given logging buffer
}
/**
- * @brief Close socket that was initialized using socket_initialize function
- * @details Closes socket entity fd
- * @param[in] sock socet data to close
- */
-void socket_close(struct sock_data *sock)
-{
- assert(sock);
- if (sock->fd_entity.fd >= 0)
- close(sock->fd_entity.fd);
-}
-
-/**
* @brief Create buffer
* @details Allocate a buffer structure
* @param[out] lb The newly-allocated buffer
* @param[in] server The logger server
* @param[in] err errno from the call that failed to create an FD
*/
-static void check_if_fd_limit_reached(struct logger *server, int err)
+void check_if_fd_limit_reached(struct logger *server, int err)
{
assert(server);
* @param[in] event The event containing the request
* @return 0 on success, else -errno
*/
-static int service_writer_socket(struct logger* server, struct writer* wr, struct epoll_event* event)
+int service_writer_socket(struct logger* server, struct writer* wr, struct epoll_event* event)
{
int r = 0;
}
/**
- * @brief Initialize a socket
- * @details Initializes a socket
- * @param[out] sock The socket to initialize
- * @param[in] buffer The buffer to whom the socket belongs
- * @param[in] type Type of the socket
- * @param[in] data Socket config data
- * @return 0 on success, else -errno
- */
-int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data)
-{
- assert(data);
- int sock_fd = listen_fd_create(data->path, data->permissions);
- if (sock_fd < 0)
- return sock_fd;
-
- init_fd_entity(&sock->fd_entity, dispatch_event_sock, sock);
- sock->service_socket = service_socket;
- sock->buf_ptr = buffer;
- set_read_fd_entity(&sock->fd_entity, sock_fd);
-
- return 0;
-}
-
-/**
* @brief Add writer to server
* @details Adds a writer to the server's witers list and registers its event to epoll loop
* @param[in] l The server to add the writer to
* @param[in] writer The writer to add to the server and register its working_fd to epoll loop
*/
-static void logger_add_writer(struct logger* l, struct writer* wr)
+void logger_add_writer(struct logger* l, struct writer* wr)
{
assert(l);
assert(wr);
}
/**
- * @brief Dispatch socket event
- * @details Receives and handles an event
- * @param[in] server The logger server
- * @param[in] event The received event
- */
-void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata)
-{
- assert(event);
- struct sock_data const *const sock = (struct sock_data const * const) userdata;
- assert(sock);
-
- int sock_pipe = accept4(sock->fd_entity.fd, NULL, NULL, SOCK_NONBLOCK);
- if (sock_pipe < 0) {
- check_if_fd_limit_reached(server, errno);
- return;
- }
-
- struct writer *writer;
- if (writer_create(&writer, sock_pipe, sock->buf_ptr, service_writer_socket, sock->service_socket) != 0) {
- close(sock_pipe);
- return;
- }
-
- logger_add_writer(server, writer);
- add_fd_entity(&server->epoll_socket, &writer->fd_entity);
-}
-
-/**
* @brief Handle interrupting/terminating signals
* @details Clears global flag to stop main loop
* @param[in] signo signal number
#include "reader_common.h"
#include "reader_logger.h"
#include "reader_pipe.h"
+#include "socket.h"
#ifdef __cplusplus
extern "C" {
*/
typedef int (*service_writer_t)(struct logger* server, struct writer* wr, struct epoll_event* event);
-/**
- * @brief Service socket request
- * @details Handle request on socket in respect to msg request type
- * @param[in] server The logger server
- * @param[in] wr The writer to handle the request on the socket
- * @param[in] msg The message containing the request
- * @return 0 on success, else -errno
- */
-typedef int (*service_socket_t)(struct logger *server, struct writer *wr, struct dlog_control_msg *msg);
-
/* Writers and readers can be a bit confusing in what they refer to.
* Something that does write() calls is usually actually a reader,
};
#undef LARGEST_STRUCT
-struct sock_data {
- struct fd_entity fd_entity;
- struct log_buffer* buf_ptr;
- struct epoll_event event;
- service_socket_t service_socket;
-};
-
struct log_buffer {
struct sock_data sock_wr;
struct sock_data sock_ctl;
struct qos_module qos;
};
-struct socket_config_data {
- int permissions;
- char path[MAX_CONF_VAL_LEN];
-};
-
struct buffer_config_data {
int size;
struct socket_config_data write_socket;
void remove_reader_fd_entities(struct logger *server, struct reader *reader);
void reader_deinit_common(struct reader *reader);
+void check_if_fd_limit_reached(struct logger *server, int err);
+int writer_create(struct writer **writer, int fd, struct log_buffer *log_buffer,
+ service_writer_t service_writer, service_socket_t service_socket);
+int service_writer_socket(struct logger* server, struct writer* wr, struct epoll_event* event);
#ifdef __cplusplus
}
--- /dev/null
+#include "socket.h"
+#include "logger_internal.h"
+
+/**
+ * @brief Create a bound socket
+ * @details Creates a socket of given type under the given path
+ * @param[in] path The path to the socket
+ * @param[in] type Socket type (SOCK_DGRAM or SOCK_STREAM) with flags
+ * @return The socket FD, or negative errno
+ */
+int bind_fd_create(const char* path, int type)
+{
+ struct sockaddr_un server_addr;
+ int sd;
+
+ sd = socket(AF_UNIX, type, 0);
+ if (sd == -1)
+ return -errno;
+
+ memset(&server_addr, 0, sizeof(server_addr));
+ server_addr.sun_family = AF_UNIX;
+ strncpy(server_addr.sun_path, path, sizeof(server_addr.sun_path)-1);
+ unlink(server_addr.sun_path);
+
+ if (bind(sd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
+ goto failure;
+
+ return sd;
+
+failure:
+ close(sd);
+ return -errno;
+}
+
+/**
+ * @brief Create a listening socket
+ * @details Creates a socket with given permissions under the given path
+ * @param[in] path The path to the socket
+ * @param[in] permissions File permissions (the internal representation)
+ * @return The socket FD, or negative errno
+ */
+int listen_fd_create(const char* path, int permissions)
+{
+ int sd = bind_fd_create(path, SOCK_STREAM);
+ if (sd < 0)
+ return sd;
+
+ if (permissions)
+ if (chmod(path, permissions) < 0) // ideally, fchmod would be used, but that does not work
+ goto failure;
+
+ if (listen(sd, MAX_CONNECTION_Q) < 0)
+ goto failure;
+
+ return sd;
+
+failure:
+ close(sd);
+ return -errno;
+}
+
+/**
+ * @brief Dispatch socket event
+ * @details Receives and handles an event
+ * @param[in] server The logger server
+ * @param[in] event The received event
+ */
+void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata)
+{
+ assert(event);
+ struct sock_data const *const sock = (struct sock_data const * const) userdata;
+ assert(sock);
+
+ int sock_pipe = accept4(sock->fd_entity.fd, NULL, NULL, SOCK_NONBLOCK);
+ if (sock_pipe < 0) {
+ check_if_fd_limit_reached(server, errno);
+ return;
+ }
+
+ struct writer *writer;
+ if (writer_create(&writer, sock_pipe, sock->buf_ptr, service_writer_socket, sock->service_socket) != 0) {
+ close(sock_pipe);
+ return;
+ }
+
+ logger_add_writer(server, writer);
+ add_fd_entity(&server->epoll_socket, &writer->fd_entity);
+}
+
+/**
+ * @brief Initialize a socket
+ * @details Initializes a socket
+ * @param[out] sock The socket to initialize
+ * @param[in] buffer The buffer to whom the socket belongs
+ * @param[in] type Type of the socket
+ * @param[in] data Socket config data
+ * @return 0 on success, else -errno
+ */
+int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data)
+{
+ assert(data);
+ int sock_fd = listen_fd_create(data->path, data->permissions);
+ if (sock_fd < 0)
+ return sock_fd;
+
+ init_fd_entity(&sock->fd_entity, dispatch_event_sock, sock);
+ sock->service_socket = service_socket;
+ sock->buf_ptr = buffer;
+ set_read_fd_entity(&sock->fd_entity, sock_fd);
+
+ return 0;
+}
+
+/**
+ * @brief Close socket that was initialized using socket_initialize function
+ * @details Closes socket entity fd
+ * @param[in] sock socet data to close
+ */
+void socket_close(struct sock_data *sock)
+{
+ assert(sock);
+ if (sock->fd_entity.fd >= 0)
+ close(sock->fd_entity.fd);
+}
+
+int systemd_sock_get(const char *path, int type)
+{
+ int sock_fd = -1;
+ int n = sd_listen_fds(0);
+ if (n > 0) {
+ int i;
+ for (i = SD_LISTEN_FDS_START; sock_fd < 0 && i < SD_LISTEN_FDS_START + n; i++)
+ if (sd_is_socket_unix(i, type, -1, path, 0) > 0)
+ sock_fd = i;
+ }
+ return sock_fd;
+}
+
+/* TODO: move the path to the configuration */
+static const char dev_log_sock[] = "/run/dlog/dev-log";
+static const char dev_log_link[] = "/dev/log";
+
+int dev_log_sock_get()
+{
+ return systemd_sock_get(dev_log_sock, SOCK_DGRAM);
+}
+
+int dev_log_sock_create()
+{
+ int fd = bind_fd_create(dev_log_sock, SOCK_DGRAM);
+ if (fd >= 0) {
+ unlink(dev_log_link);
+ if (symlink(dev_log_sock, dev_log_link) == -1) {
+ close(fd);
+ fd = -errno;
+ }
+ }
+ return fd;
+}
--- /dev/null
+#pragma once
+
+#include "fd_entity.h"
+#include <logpipe.h>
+#include <logconfig.h>
+
+struct logger;
+struct writer;
+
+/**
+ * @brief Service socket request
+ * @details Handle request on socket in respect to msg request type
+ * @param[in] server The logger server
+ * @param[in] wr The writer to handle the request on the socket
+ * @param[in] msg The message containing the request
+ * @return 0 on success, else -errno
+ */
+typedef int (*service_socket_t)(struct logger *server, struct writer *wr, struct dlog_control_msg *msg);
+
+struct sock_data {
+ struct fd_entity fd_entity;
+ struct log_buffer* buf_ptr;
+ struct epoll_event event;
+ service_socket_t service_socket;
+};
+
+struct socket_config_data {
+ int permissions;
+ char path[MAX_CONF_VAL_LEN];
+};
+
+int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data);
+void socket_close(struct sock_data *sock);
+void logger_add_writer(struct logger* l, struct writer* wr);
+
+int dev_log_sock_get();
+int dev_log_sock_create();
+
+#ifdef UNIT_TEST
+int bind_fd_create(const char* path, int type);
+int listen_fd_create(const char* path, int permissions);
+void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata);
+int systemd_sock_get(const char *path, int type);
+#endif