0

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?

Croppi
  • 172
  • 11
  • `SOCKET_NAME "/var/log"` are you trying to bind to a directory? – KamilCuk May 16 '19 at 16:17
  • @KamilCuk Accidentaly I mistyped the name ```/var/log```. It SHOULD BE ```/dev/log``` which is a symbolic link to ```/run/systemd/journal/dev-log=``` – Croppi May 16 '19 at 16:23
  • But there is also `systemd-journald`. You want to forward from journald to your app, or just remove journald altogether? Both are pretty big tasks. – KamilCuk May 16 '19 at 16:59
  • Actually, I managed to overcome the bind issue by manually unlinking the SOCKET_NAME. In terminal: ```unlink /dev/log``` – Croppi May 16 '19 at 17:44

0 Answers0