citrun

watch C/C++ source code execute
Log | Files | Refs | LICENSE

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:
Mviewer/Makefile | 2+-
Aviewer/af_unix.cpp | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aviewer/af_unix.h | 17+++++++++++++++++
Mviewer/viewer.cpp | 16+++++++++++-----
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;