commit 66e0540b52c9bf057ec362e714d2e1d10add5d0b
parent eaf6435af0a6cde7568b1198eb36ff3a6a76df72
Author: kyle <kyle@getaddrinfo.net>
Date: Wed, 28 Oct 2015 22:34:37 -0600
viewer: add af_unix non blocking socket class
- accepts new connections
- reads on accepted connections, drops them on eof read
- non blocking, safe to call from idle and display glut callbacks
- includes pretty good error checking
Diffstat:
4 files changed, 103 insertions(+), 6 deletions(-)
diff --git a/viewer/Makefile b/viewer/Makefile
@@ -7,7 +7,7 @@ LDLIBS += -lfreetype -lz -lglut
CXX = eg++ -std=c++1y
BIN = viewer
-SRCS = viewer.cpp shader_utils.cpp text.cpp
+SRCS = viewer.cpp shader_utils.cpp text.cpp af_unix.cpp
OBJS = $(SRCS:cpp=o)
$(BIN): $(OBJS)
diff --git a/viewer/af_unix.cpp b/viewer/af_unix.cpp
@@ -0,0 +1,74 @@
+#include <err.h> // err
+#include <string.h> // memset
+#include <sys/socket.h> // socket
+#include <sys/un.h> // sockaddr_un
+#include <unistd.h> // close
+
+#include <iostream>
+
+#include "af_unix.h"
+
+af_unix_nonblock::af_unix_nonblock()
+{
+ if ((listen_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
+ err(1, "socket");
+
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, "socket", sizeof(addr.sun_path) - 1);
+
+ if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)))
+ err(1, "bind");
+
+ if (listen(listen_fd, 1024))
+ err(1, "listen");
+}
+
+void
+af_unix_nonblock::accept_one()
+{
+ int new_fd;
+ struct sockaddr_un addr;
+ socklen_t len = sizeof(struct sockaddr_un);
+
+ new_fd = accept(listen_fd, (struct sockaddr *)&addr, &len);
+ if (new_fd == -1) {
+ if (errno != EWOULDBLOCK) {
+ perror("accept");
+ }
+ return;
+ }
+
+ connected_fds.push_back(new_fd);
+ std::cout << "accepted new connection" << std::endl;
+}
+
+void
+af_unix_nonblock::read()
+{
+ char buffer[512];
+ int nread;
+
+ if (connected_fds.size() == 0)
+ return;
+
+ nread = ::read(connected_fds[0], buffer, sizeof buffer);
+ if (nread == 0) {
+ // don't try to read from this socket anymore
+ connected_fds.clear();
+ std::cerr << __func__ << ": eof read!" << std::endl;
+ }
+ if (nread > 0)
+ std::cout << __func__ << ": read " << nread << " bytes" << std::endl;
+ if (nread == -1)
+ if (errno != EAGAIN)
+ std::cerr << __func__ << ": read() failed: "
+ << strerror(errno) << std::endl;
+}
+
+af_unix_nonblock::~af_unix_nonblock()
+{
+ close(listen_fd);
+ unlink("socket");
+}
diff --git a/viewer/af_unix.h b/viewer/af_unix.h
@@ -0,0 +1,17 @@
+#ifndef AF_UNIX_H
+#define AF_UNIX_H
+
+#include <vector>
+
+class af_unix_nonblock {
+public:
+ af_unix_nonblock();
+ ~af_unix_nonblock();
+ void accept_one();
+ void read();
+private:
+ int listen_fd;
+ std::vector<int> connected_fds;
+};
+
+#endif
diff --git a/viewer/viewer.cpp b/viewer/viewer.cpp
@@ -9,8 +9,10 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
+#include "af_unix.h"
#include "text.h"
+
class window {
public:
window(int argc, char *argv[]);
@@ -20,6 +22,7 @@ public:
private:
static std::vector<drawable*> drawables;
static std::vector<idleable*> idleables;
+ static af_unix_nonblock socket;
static void display();
static void idle();
};
@@ -27,6 +30,7 @@ private:
// fuckin c++
std::vector<drawable*> window::drawables;
std::vector<idleable*> window::idleables;
+af_unix_nonblock window::socket;
window::window(int argc, char *argv[])
{
@@ -75,7 +79,7 @@ window::display(void)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- for(auto &d : drawables)
+ for (auto &d : drawables)
d->draw();
glutSwapBuffers();
@@ -84,14 +88,16 @@ window::display(void)
void
window::idle(void)
{
- // printf("idling!\n");
+ socket.accept_one();
+ socket.read();
- for(auto &i : idleables)
+ for (auto &i : idleables)
i->idle();
}
-int main(int argc, char *argv[]) {
-
+int
+main(int argc, char *argv[])
+{
window gl_window(argc, argv);
text gl_text;