Replace () with (void) in function prototypes
[platform/core/system/dlog.git] / src / logger / socket.c
1 #include "socket.h"
2 #include "logger_internal.h"
3
4 /**
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
10  */
11 int bind_fd_create(const char *path, int type)
12 {
13         struct sockaddr_un server_addr;
14         int sd;
15
16         sd = socket(AF_UNIX, type, 0);
17         if (sd == -1)
18                 return -errno;
19
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);
24
25         if (bind(sd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
26                 goto failure;
27
28         return sd;
29
30 failure:
31         close(sd);
32         return -errno;
33 }
34
35 /**
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
41  */
42 int listen_fd_create(const char *path, int permissions)
43 {
44         int sd = bind_fd_create(path, SOCK_STREAM);
45         if (sd < 0)
46                 return sd;
47
48         if (permissions)
49                 if (chmod(path, permissions) < 0) // ideally, fchmod would be used, but that does not work
50                         goto failure;
51
52         if (listen(sd, MAX_CONNECTION_Q) < 0)
53                 goto failure;
54
55         return sd;
56
57 failure:
58         close(sd);
59         return -errno;
60 }
61
62 /**
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
67  */
68 void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata)
69 {
70         assert(event);
71         struct sock_data const *const sock = (struct sock_data const * const) userdata;
72         assert(sock);
73
74         int sock_pipe = accept4(sock->fd_entity.fd, NULL, NULL, SOCK_NONBLOCK);
75         if (sock_pipe < 0) {
76                 check_if_fd_limit_reached(server, errno);
77                 return;
78         }
79
80         struct writer *writer;
81         if (writer_create(&writer, sock_pipe, sock->buf_ptr, service_writer_socket, sock->service_socket) != 0) {
82                 close(sock_pipe);
83                 return;
84         }
85
86         logger_add_writer(server, writer);
87         add_fd_entity(&server->epoll_socket, &writer->fd_entity);
88 }
89
90 /**
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
98  */
99 int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data)
100 {
101         assert(data);
102         int sock_fd = listen_fd_create(data->path, data->permissions);
103         if (sock_fd < 0)
104                 return sock_fd;
105
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);
110
111         return 0;
112 }
113
114 /**
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
118  */
119 void socket_close(struct sock_data *sock)
120 {
121         assert(sock);
122         if (sock->fd_entity.fd >= 0)
123                 close(sock->fd_entity.fd);
124 }
125
126 int systemd_sock_get(const char *path, int type)
127 {
128         int sock_fd = -1;
129         int n = sd_listen_fds(0);
130         if (n > 0) {
131                 int i;
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)
134                                 sock_fd = i;
135         }
136         return sock_fd;
137 }
138
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";
142
143 int dev_log_sock_get(void)
144 {
145         return systemd_sock_get(dev_log_sock, SOCK_DGRAM);
146 }
147
148 int dev_log_sock_create(void)
149 {
150         int fd = bind_fd_create(dev_log_sock, SOCK_DGRAM);
151         if (fd >= 0) {
152                 unlink(dev_log_link);
153                 if (symlink(dev_log_sock, dev_log_link) == -1) {
154                         close(fd);
155                         fd = -errno;
156                 }
157         }
158         return fd;
159 }