Implement startHostConsole

startHostConsole function would add the Host Console fd to the
event loop for EPOLLIN and update the console buffer.

Change-Id: Icac2955dc84f108b5d819df0a015f9eac7301b42
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/sd_event_loop.cpp b/sd_event_loop.cpp
index a99cf56..2fc8551 100644
--- a/sd_event_loop.cpp
+++ b/sd_event_loop.cpp
@@ -53,6 +53,50 @@
     return 0;
 }
 
+static int consoleInputHandler(sd_event_source* es, int fd, uint32_t revents,
+                               void* userdata)
+{
+    try
+    {
+        int readSize = 0;
+
+        if (ioctl(fd, FIONREAD, &readSize) < 0)
+        {
+            log<level::ERR>("ioctl failed for FIONREAD:",
+                    entry("errno = %d", errno));
+            return 0;
+        }
+
+        std::vector<uint8_t> buffer(readSize);
+        auto bufferSize = buffer.size();
+        ssize_t readDataLen = 0;
+
+        readDataLen = read(fd, buffer.data(), bufferSize);
+
+        // Update the Console buffer with data read from the socket
+        if (readDataLen > 0)
+        {
+            buffer.resize(readDataLen);
+            std::get<sol::Manager&>(singletonPool).dataBuffer.write(buffer);
+        }
+        else if (readDataLen == 0)
+        {
+            log<level::ERR>("Connection Closed for host console socket");
+        }
+        else if (readDataLen < 0) // Error
+        {
+            log<level::ERR>("Reading from host console socket failed:",
+                    entry("ERRNO=%d", errno));
+        }
+    }
+    catch (std::exception& e)
+    {
+        log<level::ERR>(e.what());
+    }
+
+    return 0;
+}
+
 int EventLoop::startEventLoop()
 {
     int fd = -1;
@@ -130,4 +174,27 @@
     return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
 
+void EventLoop::startHostConsole(const sol::CustomFD& fd)
+{
+    int rc = 0;
+
+    if((fd() == -1) || hostConsole.get())
+    {
+        throw std::runtime_error("Console descriptor already added");
+    }
+
+    sd_event_source* source = nullptr;
+
+    // Add the fd to the event loop for EPOLLIN
+    rc = sd_event_add_io(
+            event, &source, fd(), EPOLLIN, consoleInputHandler, nullptr);
+    if (rc < 0)
+    {
+        throw std::runtime_error("Failed to add socket descriptor");
+    }
+
+    hostConsole.reset(source);
+    source=nullptr;
+}
+
 } // namespace eventloop