-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtinydb_tcp_client_handler.c
100 lines (84 loc) · 2.49 KB
/
tinydb_tcp_client_handler.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "tinydb_command_executor.h"
#include "tinydb_context.h"
#include "tinydb_database.h"
#include "tinydb_log.h"
#include "tinydb_query_parser.h"
#include "tinydb_tcp_client_handler.h"
#define INITIAL_BUFFER_SIZE COMMAND_BUFFER_SIZE
#define BUFFER_INCREMENT COMMAND_BUFFER_SIZE
extern RuntimeContext* context;
void
TCP_Client_Handler(void* socket_desc)
{
if (socket_desc == NULL) {
DB_Log(DB_LOG_ERROR, "TCP_SERVER socket_desc is NULL");
return;
}
int32_t sock = *(int32_t*)socket_desc;
free(socket_desc);
size_t buffer_size = INITIAL_BUFFER_SIZE;
char* buffer = (char*)malloc(buffer_size);
if (buffer == NULL) {
DB_Log(DB_LOG_ERROR,
"TCP_SERVER Failed to allocate initial memory for buffer");
close(sock);
return;
}
ssize_t read_size;
size_t total_read = 0;
#if 0
struct timeval timeout;
timeout.tv_sec = 5; /* we need to make this configurable. */
timeout.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
#endif
while (1) {
read_size =
recv(sock, buffer + total_read, buffer_size - total_read - 1, 0);
if (read_size <= 0) {
break;
}
total_read += read_size;
buffer[total_read] = '\0';
buffer[strcspn(buffer, "\r\n")] = '\0';
ParsedCommand* cmd = Parse_Command(buffer, buffer_size, &total_read);
if (cmd != NULL) {
Execute_Command(sock, cmd, context->Active.db);
Free_Parsed_Command(cmd);
} else {
const char* error_msg = "Invalid command\n";
if (write(sock, error_msg, strlen(error_msg)) == -1) {
DB_Log(DB_LOG_ERROR,
"TCP_SERVER Failed to send error message, closing"
"connection.");
break;
}
}
// if buffer is almost full, increase the size size
if (total_read >= buffer_size - 1) {
buffer_size += BUFFER_INCREMENT;
char* temp = realloc(buffer, buffer_size);
if (temp == NULL) {
DB_Log(DB_LOG_ERROR,
"TCP_SERVER Failed to reallocate memory for buffer");
break;
}
buffer = temp;
}
}
if (read_size == 0) {
DB_Log(DB_LOG_WARNING, "TCP_SERVER Client disconnected.");
} else if (read_size == -1) {
DB_Log(DB_LOG_ERROR, "TCP_SERVER recv failed: %s", strerror(errno));
}
free(buffer);
close(sock);
}