Skip to content

Commit 0d2fc7c

Browse files
committed
init
1 parent 9e5efb6 commit 0d2fc7c

12 files changed

+526
-1
lines changed

Makefile

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
CC = gcc -fPIC
2+
LDFLAGS = -lm
3+
4+
# set DEBUG options
5+
ifdef DEBUG
6+
CFLAGS = -Wall -Wextra -ggdb -pg -DDEBUG
7+
else
8+
CFLAGS = -Wall -O2
9+
endif
10+
11+
#name all the object files
12+
OBJS = main.o debug.o echo.o ioloop.o server.o
13+
14+
all : server
15+
16+
server: $(OBJS)
17+
$(CC) $(LDFLAGS) -o main $^
18+
19+
debug :
20+
make all DEBUG=1
21+
22+
%.o : %.c
23+
$(CC) $(CFLAGS) -o $@ -c $^
24+
25+
doxy :
26+
doxygen Doxyfile
27+
28+
clean :
29+
rm -rf $(OBJS) main
30+

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
ahira
22
=====
33

4-
An experimental server written in C ... intending to make it like node.js
4+
An experimental single threaded server written in C which uses epoll. It still doesn't have a HTTP handler.
5+
The intention is to create a platform like node.js, but in C, so that it will be super fast and memory efficient.
6+

debug.c

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "debug.h"
2+
3+
void log_epoll_event(struct epoll_event e) {
4+
printf("Event fd: %d events: ", e.data.fd);
5+
if(e.events & EPOLLERR)
6+
printf("EPOLLERR ");
7+
if(e.events & EPOLLET)
8+
printf("EPOLLET ");
9+
if(e.events & EPOLLHUP)
10+
printf("EPOLLHUP ");
11+
if(e.events & EPOLLIN)
12+
printf("EPOLLIN ");
13+
if(e.events & EPOLLONESHOT)
14+
printf("EPOLLONESHOT ");
15+
if(e.events & EPOLLOUT)
16+
printf("EPOLLOUT ");
17+
if(e.events & EPOLLPRI)
18+
printf("EPOLLPRI ");
19+
20+
printf("\n");
21+
}
22+
23+
void log_error(char *m, int level) {
24+
if(level & FATAL_ERROR)
25+
perror("FATAL ERROR: ");
26+
else if(level & ERROR_MESSAGE)
27+
perror("ERROR: ");
28+
29+
perror(m);
30+
31+
if(level & FATAL_ERROR)
32+
exit(1);
33+
}
34+

debug.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef DEBUG_H
2+
#define DEBUG_H
3+
#include "headers.h"
4+
5+
#define FATAL_ERROR 2
6+
#define ERROR_MESSAGE 1
7+
8+
void log_error(char *m, int level);
9+
10+
void log_epoll_event(struct epoll_event e);
11+
#endif

echo.c

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include "ioloop.h"
2+
#include "echo.h"
3+
#include "debug.h"
4+
5+
echo_handler_context *
6+
echo_handler_init(int fd, struct sockaddr_in addr) {
7+
echo_handler_context *c;
8+
9+
c = malloc(sizeof(echo_handler_context));
10+
memset(c, 0, sizeof(echo_handler_context));
11+
12+
ioloop_set_nonblocking(fd);
13+
14+
c->fd = fd;
15+
c->addr = addr;
16+
c->received = 0;
17+
18+
ioloop_add_handler(fd, handle_echo_events, c, EPOLLIN);
19+
20+
return c;
21+
}
22+
23+
static void
24+
free_context(echo_handler_context *c) {
25+
free(c);
26+
}
27+
28+
int
29+
handle_echo_events(struct epoll_event e, void *context) {
30+
echo_handler_context *c = (echo_handler_context *)context;
31+
32+
printf("echo event\n");
33+
log_epoll_event(e);
34+
35+
if(e.events & EPOLLHUP) {
36+
close(c->fd);
37+
38+
ioloop_remove_handler(c->fd);
39+
40+
free_context(c);
41+
return -1;
42+
}
43+
44+
if(e.events & EPOLLERR) {
45+
return -1;
46+
}
47+
48+
if(e.events & EPOLLOUT) {
49+
if(c->received > 0) {
50+
printf("Writing: %s\n", c->buffer);
51+
52+
if (send(c->fd, c->buffer, c->received, 0) != c->received) {
53+
log_error("Could not write to stream", ERROR_MESSAGE);
54+
}
55+
}
56+
57+
c->received = 0;
58+
59+
ioloop_modify_handler(c->fd, EPOLLIN);
60+
}
61+
62+
if(e.events & EPOLLIN) {
63+
if ((c->received = recv(c->fd, c->buffer, BUFFER_SIZE, 0)) < 0) {
64+
log_error("Error reading from socket", ERROR_MESSAGE);
65+
} else {
66+
c->buffer[c->received] = 0;
67+
printf("Reading %d bytes: %s\n", c->received, c->buffer);
68+
}
69+
70+
if(c->received > 0) {
71+
ioloop_modify_handler(c->fd, EPOLLOUT);
72+
} else {
73+
close(c->fd);
74+
ioloop_remove_handler(c->fd);
75+
76+
free_context(c);
77+
}
78+
}
79+
80+
return 0;
81+
}
82+
83+

echo.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef ECHO_H
2+
#define ECHO_H
3+
#include "headers.h"
4+
5+
#define BUFFER_SIZE 1000
6+
7+
typedef struct {
8+
struct sockaddr_in addr;
9+
int fd;
10+
char buffer[BUFFER_SIZE];
11+
int received;
12+
} echo_handler_context;
13+
14+
echo_handler_context *
15+
echo_handler_init(int fd, struct sockaddr_in addr);
16+
17+
int
18+
handle_echo_events(struct epoll_event e, void *context);
19+
20+
#endif
21+

headers.h

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef HEADERS_H
2+
#define HEADERS_H
3+
4+
#include <stdio.h>
5+
#include <sys/socket.h>
6+
#include <sys/epoll.h>
7+
#include <arpa/inet.h>
8+
#include <stdlib.h>
9+
#include <string.h>
10+
#include <unistd.h>
11+
#include <netinet/in.h>
12+
#include <fcntl.h>
13+
14+
#endif

0 commit comments

Comments
 (0)