ADDED   .fossil-settings/ignore-glob
Index: .fossil-settings/ignore-glob
==================================================================
--- /dev/null
+++ .fossil-settings/ignore-glob
@@ -0,0 +1,2 @@
+filed
+filed.o

ADDED   Makefile
Index: Makefile
==================================================================
--- /dev/null
+++ Makefile
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -Wall -Werror -W -pthread -O3
+LDFLAGS = -pthread
+LIBS = -lpthread
+
+filed: filed.o
+filed.o: filed.c
+
+clean:
+	rm -f filed filed.o
+
+distclean: clean
+
+.PHONY: clean distclean

ADDED   filed.c
Index: filed.c
==================================================================
--- /dev/null
+++ filed.c
@@ -0,0 +1,174 @@
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Default values */
+#define MAX_FAILURE_COUNT 30
+#define PORT 8080
+#define THREAD_COUNT 10
+#define BIND_ADDR "::"
+
+/* Arguments for worker threads */
+struct filed_worker_thread_args {
+	int fd;
+};
+
+static void filed_init(void) {
+	mlockall(MCL_CURRENT | MCL_FUTURE);
+}
+
+static int filed_listen(const char *address, unsigned int port) {
+	struct sockaddr_in6 addr;
+	int pton_ret, bind_ret, listen_ret;
+	int fd;
+
+	addr.sin6_family = AF_INET6;
+	addr.sin6_flowinfo = 0;
+	addr.sin6_scope_id = 0;
+	addr.sin6_port = htons(port);
+	pton_ret = inet_pton(AF_INET6, address, addr.sin6_addr.s6_addr);
+	if (pton_ret != 1) {
+		return(-1);
+	}
+
+	fd = socket(AF_INET6, SOCK_STREAM, 0);
+	if (fd < 0) {
+		return(fd);
+	}
+
+	bind_ret = bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
+	if (bind_ret < 0) {
+		close(fd);
+
+		return(-1);
+	}
+
+	listen_ret = listen(fd, 128);
+	if (listen_ret != 0) {
+		close(fd);
+
+		return(-1);
+	}
+
+	return(fd);
+}
+
+static int filed_logging_thread_init(void) {
+	/* XXX:TODO: Unimplemented */
+	return(0);
+}
+
+static void filed_handle_client(int fd) {
+	/* XXX:TODO: Unimplemented */
+	fd = fd;
+	return;
+}
+
+static void *filed_worker_thread(void *arg_v) {
+	struct filed_worker_thread_args *arg;
+	struct sockaddr_in6 addr;
+	socklen_t addrlen;
+	int failure_count = 0, max_failure_count = MAX_FAILURE_COUNT;
+	int master_fd, fd;
+
+	/* Read arguments */
+	arg = arg_v;
+
+	master_fd = arg->fd;
+
+	while (1) {
+		/* Failure loop prevention */
+		if (failure_count > max_failure_count) {
+			break;
+		}
+
+		/* Accept a new client */
+		addrlen = sizeof(addr);
+		fd = accept(master_fd, (struct sockaddr *) &addr, &addrlen);
+
+		/*
+		 * If we fail, make a note of it so we don't go into a loop of
+		 * accept() failing
+		 */
+		if (fd < 0) {
+			failure_count++;
+
+			continue;
+		}
+
+		/* Reset failure count*/
+		failure_count = 0;
+
+		/* Handle socket */
+		filed_handle_client(fd);
+
+		/* Cleanup */
+		close(fd);
+	}
+
+	/* XXX:TODO: Report error */
+	return(NULL);
+}
+
+static int filed_worker_threads_init(int fd, int thread_count) {
+	struct filed_worker_thread_args *arg;
+	pthread_t threadid;
+	int pthread_ret;
+	int i;
+
+	for (i = 0; i < thread_count; i++) {
+		arg = malloc(sizeof(*arg));
+
+		arg->fd = fd;
+
+		pthread_ret = pthread_create(&threadid, NULL, filed_worker_thread, arg);
+		if (pthread_ret != 0) {
+			return(-1);
+		}
+	}
+
+	return(0);
+}
+
+int main(int argc, char **argv) {
+	int port = PORT, thread_count = THREAD_COUNT;
+	const char *bind_addr = BIND_ADDR;
+	int fd;
+
+	/* Ignore */
+	argc = argc;
+	argv = argv;
+
+	/* Create listening socket */
+	fd = filed_listen(bind_addr, port);
+	if (fd < 0) {
+		return(1);
+	}
+
+	/* Become a daemon */
+	/* XXX:TODO: Become a daemon */
+
+	/* Initialize */
+	filed_init();
+
+	/* Create logging thread */
+	/* XXX:TODO: Check for errors */
+	filed_logging_thread_init();
+
+	/* Create worker threads */
+	/* XXX:TODO: Check for errors */
+	filed_worker_threads_init(fd, thread_count);
+
+	/* Wait for threads to exit */
+	/* XXX:TODO: Monitor thread usage */
+	while (1) {
+		sleep(60);
+	}
+
+	/* Return in failure */
+	return(2);
+}