client: use the new fifo_buffer library
This commit is contained in:
87
src/client.c
87
src/client.c
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "fifo_buffer.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "listen.h"
|
#include "listen.h"
|
||||||
@@ -71,13 +72,12 @@ struct deferred_buffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct client {
|
struct client {
|
||||||
char buffer[4096];
|
|
||||||
size_t bufferLength;
|
|
||||||
size_t bufferPos;
|
|
||||||
|
|
||||||
GIOChannel *channel;
|
GIOChannel *channel;
|
||||||
guint source_id;
|
guint source_id;
|
||||||
|
|
||||||
|
/** the buffer for reading lines from the #channel */
|
||||||
|
struct fifo_buffer *input;
|
||||||
|
|
||||||
unsigned permission;
|
unsigned permission;
|
||||||
|
|
||||||
/** the uid of the client process, or -1 if unknown */
|
/** the uid of the client process, or -1 if unknown */
|
||||||
@@ -176,8 +176,6 @@ static void client_init(struct client *client, int fd)
|
|||||||
|
|
||||||
client->cmd_list_size = 0;
|
client->cmd_list_size = 0;
|
||||||
client->cmd_list_OK = -1;
|
client->cmd_list_OK = -1;
|
||||||
client->bufferLength = 0;
|
|
||||||
client->bufferPos = 0;
|
|
||||||
|
|
||||||
#ifndef G_OS_WIN32
|
#ifndef G_OS_WIN32
|
||||||
client->channel = g_io_channel_unix_new(fd);
|
client->channel = g_io_channel_unix_new(fd);
|
||||||
@@ -197,6 +195,8 @@ static void client_init(struct client *client, int fd)
|
|||||||
G_IO_IN|G_IO_ERR|G_IO_HUP,
|
G_IO_IN|G_IO_ERR|G_IO_HUP,
|
||||||
client_in_event, client);
|
client_in_event, client);
|
||||||
|
|
||||||
|
client->input = fifo_buffer_new(4096);
|
||||||
|
|
||||||
client->lastTime = time(NULL);
|
client->lastTime = time(NULL);
|
||||||
client->cmd_list = NULL;
|
client->cmd_list = NULL;
|
||||||
client->deferred_send = g_queue_new();
|
client->deferred_send = g_queue_new();
|
||||||
@@ -370,54 +370,45 @@ static int client_process_line(struct client *client, char *line)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
client_read_line(struct client *client)
|
||||||
|
{
|
||||||
|
const char *p, *newline;
|
||||||
|
size_t length;
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
p = fifo_buffer_read(client->input, &length);
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
newline = memchr(p, '\n', length);
|
||||||
|
if (newline == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
line = g_strndup(p, newline - p);
|
||||||
|
fifo_buffer_consume(client->input, newline - p + 1);
|
||||||
|
|
||||||
|
return g_strchomp(line);
|
||||||
|
}
|
||||||
|
|
||||||
static int client_input_received(struct client *client, size_t bytesRead)
|
static int client_input_received(struct client *client, size_t bytesRead)
|
||||||
{
|
{
|
||||||
char *start = client->buffer + client->bufferPos, *end;
|
char *line;
|
||||||
char *newline, *next;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
assert(client->bufferPos <= client->bufferLength);
|
fifo_buffer_append(client->input, bytesRead);
|
||||||
assert(client->bufferLength + bytesRead <= sizeof(client->buffer));
|
|
||||||
|
|
||||||
client->bufferLength += bytesRead;
|
|
||||||
end = client->buffer + client->bufferLength;
|
|
||||||
|
|
||||||
/* process all lines */
|
/* process all lines */
|
||||||
while ((newline = memchr(start, '\n', end - start)) != NULL) {
|
|
||||||
next = newline + 1;
|
|
||||||
|
|
||||||
if (newline > start && newline[-1] == '\r')
|
while ((line = client_read_line(client)) != NULL) {
|
||||||
--newline;
|
ret = client_process_line(client, line);
|
||||||
*newline = 0;
|
g_free(line);
|
||||||
|
|
||||||
ret = client_process_line(client, start);
|
|
||||||
if (ret == COMMAND_RETURN_KILL ||
|
if (ret == COMMAND_RETURN_KILL ||
|
||||||
ret == COMMAND_RETURN_CLOSE)
|
ret == COMMAND_RETURN_CLOSE)
|
||||||
return ret;
|
return ret;
|
||||||
if (client_is_expired(client))
|
if (client_is_expired(client))
|
||||||
return COMMAND_RETURN_CLOSE;
|
return COMMAND_RETURN_CLOSE;
|
||||||
|
|
||||||
start = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mark consumed lines */
|
|
||||||
client->bufferPos = start - client->buffer;
|
|
||||||
|
|
||||||
/* if we're have reached the buffer's end, close the gab at
|
|
||||||
the beginning */
|
|
||||||
if (client->bufferLength == sizeof(client->buffer)) {
|
|
||||||
if (client->bufferPos == 0) {
|
|
||||||
g_warning("[%u] buffer overflow",
|
|
||||||
client->num);
|
|
||||||
return COMMAND_RETURN_CLOSE;
|
|
||||||
}
|
|
||||||
assert(client->bufferLength >= client->bufferPos
|
|
||||||
&& "bufferLength >= bufferPos");
|
|
||||||
client->bufferLength -= client->bufferPos;
|
|
||||||
memmove(client->buffer,
|
|
||||||
client->buffer + client->bufferPos,
|
|
||||||
client->bufferLength);
|
|
||||||
client->bufferPos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -425,17 +416,19 @@ static int client_input_received(struct client *client, size_t bytesRead)
|
|||||||
|
|
||||||
static int client_read(struct client *client)
|
static int client_read(struct client *client)
|
||||||
{
|
{
|
||||||
|
char *p;
|
||||||
|
size_t max_length;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GIOStatus status;
|
GIOStatus status;
|
||||||
gsize bytes_read;
|
gsize bytes_read;
|
||||||
|
|
||||||
assert(client->bufferPos <= client->bufferLength);
|
p = fifo_buffer_write(client->input, &max_length);
|
||||||
assert(client->bufferLength < sizeof(client->buffer));
|
if (p == NULL) {
|
||||||
|
g_warning("[%u] buffer overflow", client->num);
|
||||||
|
return COMMAND_RETURN_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
status = g_io_channel_read_chars
|
status = g_io_channel_read_chars(client->channel, p, max_length,
|
||||||
(client->channel,
|
|
||||||
client->buffer + client->bufferLength,
|
|
||||||
sizeof(client->buffer) - client->bufferLength,
|
|
||||||
&bytes_read, &error);
|
&bytes_read, &error);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case G_IO_STATUS_NORMAL:
|
case G_IO_STATUS_NORMAL:
|
||||||
|
Reference in New Issue
Block a user