I am trying to implement a simple syslog application. It should create a /dev/log socket, meanwhile it would receive logging messages provided by the logger
terminal command in an infinite loop.
The current state of my code looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define SOCKET_NAME "/dev/log"
#define BUFFER_SIZE 50
int main()
{
struct sockaddr_un name;
int ret;
int connection_socket;
int data_socket;
char buffer[BUFFER_SIZE];
/*
* In case the program exited inadvertently on the last run,
* remove the socket.
*/
unlink(SOCKET_NAME);
/* Create local socket. */
connection_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
if (connection_socket == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
/*
* For portability clear the whole structure, since some
* implementations have additional (nonstandard) fields in
* the structure.
*/
memset(&name, 0, sizeof(struct sockaddr_un));
/* Bind socket to socket name. */
name.sun_family = AF_UNIX;
strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path));
name.sun_path[sizeof(name.sun_path)-1] = '\0';
ret = bind(connection_socket, (const struct sockaddr *) &name, SUN_LEN(&name));
if (ret == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
/*
* Prepare for accepting connections. The backlog size is set
* to 20. So while one request is being processed other requests
* can be waiting.
*/
ret = listen(connection_socket, 20);
if (ret == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
/* This is the main loop for handling connections. */
for (;;) {
/* Wait for incoming connection. */
data_socket = accept(connection_socket, NULL, NULL);
if (data_socket == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
for (;;) {
/* Wait for next data packet. */
ret = read(data_socket, buffer, BUFFER_SIZE);
if (ret == -1) {
perror("read");
exit(EXIT_FAILURE);
}
/* Ensure buffer is 0-terminated. */
buffer[BUFFER_SIZE - 1] = 0;
/* Printf buffer*/
printf("Log message: \n", buffer);
}
close(data_socket);
}
close(connection_socket);
/* Unlink the socket. */
unlink(SOCKET_NAME);
exit(EXIT_SUCCESS);
}
Error message is the following: bind: Address already in use
My question is:
- Why am I getting the error mentioned above?
- Is there a solution for this? If yes, how?
I assumed that this behavior was caused by the presence of the original syslog, so I stoped syslog with systemctl stop rsyslog
. However, this had no effect on the outcome.
I have also tried a suggestion found in : Error: Address already in use while binding socket with address but the port number is shown free by `netstat`
The final program should be something like this: How to read /dev/log?