summaryrefslogtreecommitdiffhomepage
path: root/plop.c
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2020-04-30 21:06:39 +0200
committerAki <please@ignore.pl>2020-04-30 21:06:39 +0200
commit8acc060eef3799b0f3f8c7601c67870f553795c7 (patch)
tree10a80f3a73f81f703ee6a8ce379cab8fef147667 /plop.c
parentf84d2ede0d80ab9031dca83ef706161e2365e350 (diff)
downloadplop-8acc060eef3799b0f3f8c7601c67870f553795c7.zip
plop-8acc060eef3799b0f3f8c7601c67870f553795c7.tar.gz
plop-8acc060eef3799b0f3f8c7601c67870f553795c7.tar.bz2
Made server and client non-blocking
Diffstat (limited to 'plop.c')
-rw-r--r--plop.c78
1 files changed, 64 insertions, 14 deletions
diff --git a/plop.c b/plop.c
index eb27125..931618e 100644
--- a/plop.c
+++ b/plop.c
@@ -1,4 +1,7 @@
+#include <errno.h>
+#include <fcntl.h>
#include <netdb.h>
+#include <poll.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -35,6 +38,12 @@ int make_server(const char * node, const char * service)
if (-1 == server)
continue;
+ if (-1 == fcntl(server, F_SETFL, (fcntl(server, F_GETFL, 0) | O_NONBLOCK)))
+ {
+ close(server);
+ continue;
+ }
+
if (0 == bind(server, it->ai_addr,it->ai_addrlen))
break;
@@ -56,6 +65,42 @@ int make_server(const char * node, const char * service)
return server;
}
+/// Progresses the connection for a client and shifts it back in the array.
+/// `pfd` must be at least `shift_by + 1`-th element of the array.
+/// \param pfd Element in array processed by poll
+/// \param shift_by Element will be moved by in array this many indices
+/// \return Shift value for next handler
+/// \see poll(2)
+int handle_client(struct pollfd * pfd, const int shift_by)
+{
+ if (0 == pfd->revents)
+ {
+ return shift_by;
+ }
+
+ if (~(POLLIN | POLLOUT) & pfd->revents)
+ {
+ return -1; // TODO: Handle errors properly
+ }
+
+ static const char * response =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/plain; charset=utf-8\r\n"
+ "\r\n"
+ "plop\n";
+
+ if (-1 == send(pfd->fd, response, strlen(response), 0))
+ {
+ // TODO: Handle errors properly
+ }
+
+ close(pfd->fd);
+ (pfd - shift_by)->fd = -1;
+ (pfd - shift_by)->events = pfd->events;
+
+ return shift_by + 1;
+}
+
/// Standard entry point for the program.
/// \param argc Argument count
/// \param argv Argument array
@@ -67,26 +112,31 @@ int main(int argc, char ** argv)
return 4;
}
- int server = make_server(NULL, argv[1]);
+ struct pollfd fdv[200];
+ memset(fdv, 0, sizeof(fdv));
- int client;
- static const char * response =
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain; charset=utf-8\r\n"
- "\r\n"
- "plop\n";
+ fdv[0].fd = make_server(NULL, argv[1]);
+ fdv[0].events = POLLIN;
+ int fdc = 1;
- for (;;)
+ while (-1 != poll(fdv, fdc, -1))
{
- if (-1 != (client = accept(server, NULL, NULL)))
+ int shift_by = 0;
+
+ for (int i = 1; i < fdc; ++i)
+ {
+ shift_by = handle_client(&fdv[i], shift_by);
+ }
+
+ fdc = fdc - shift_by;
+
+ if (POLLIN == fdv[0].revents)
{
- if (-1 == send(client, response, strlen(response), 0))
+ if (-1 != (fdv[fdc].fd = accept(fdv[0].fd, NULL, NULL)))
{
- // TODO: Handle errors properly
+ fdv[fdc].events = POLLIN | POLLOUT;
+ fdc++;
}
-
- // Ignore the close-related error mess.
- close(client);
}
}
}