aboutsummaryrefslogtreecommitdiff
path: root/src/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface.c')
-rw-r--r--src/interface.c445
1 files changed, 270 insertions, 175 deletions
diff --git a/src/interface.c b/src/interface.c
index dbec9b8a..a75890ac 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -24,7 +24,7 @@
#include "listen.h"
#include "playlist.h"
#include "permission.h"
-#include "sig_handlers.h"
+#include "sllist.h"
#include <stdio.h>
#include <stdlib.h>
@@ -41,7 +41,7 @@
#include <errno.h>
#include <signal.h>
-#define GREETING "OK MPD"
+#define GREETING "OK MPD " VERSION "\n"
#define INTERFACE_MAX_BUFFER_LENGTH (40960)
#define INTERFACE_LIST_MODE_BEGIN "command_list_begin"
@@ -61,26 +61,36 @@ static size_t interface_max_command_list_size =
static size_t interface_max_output_buffer_size =
INTERFACE_MAX_OUTPUT_BUFFER_SIZE_DEFAULT;
+/* maybe make conf option for this, or... 32 might be good enough */
+static long int interface_list_cache_size = 32;
+
+/* shared globally between all interfaces: */
+static struct strnode *list_cache = NULL;
+static struct strnode *list_cache_head = NULL;
+static struct strnode *list_cache_tail = NULL;
+
typedef struct _Interface {
char buffer[INTERFACE_MAX_BUFFER_LENGTH];
int bufferLength;
int bufferPos;
int fd; /* file descriptor */
- FILE *fp; /* file pointer */
- int open; /* open/used */
int permission;
time_t lastTime;
- List *commandList; /* for when in list mode */
- int commandListOK; /* print OK after each command execution */
- size_t commandListSize; /* mem commandList consumes */
- List *bufferList; /* for output if client is slow */
- size_t outputBufferSize; /* mem bufferList consumes */
+ struct strnode *cmd_list; /* for when in list mode */
+ struct strnode *cmd_list_tail; /* for when in list mode */
+ int cmd_list_OK; /* print OK after each command execution */
+ int cmd_list_size; /* mem cmd_list consumes */
+ int cmd_list_dup; /* has the cmd_list been copied to private space? */
+ struct sllnode *deferred_send; /* for output if client is slow */
+ int deferred_bytes; /* mem deferred_send consumes */
int expired; /* set whether this interface should be closed on next
check of old interfaces */
int num; /* interface number */
- char *outBuffer;
- int outBuflen;
- int outBufSize;
+
+ char *send_buf;
+ int send_buf_used; /* bytes used this instance */
+ int send_buf_size; /* bytes usable this instance */
+ int send_buf_alloc; /* bytes actually allocated */
} Interface;
static Interface *interfaces = NULL;
@@ -89,66 +99,150 @@ static void flushInterfaceBuffer(Interface * interface);
static void printInterfaceOutBuffer(Interface * interface);
+#ifdef SO_SNDBUF
+static int get_default_snd_buf_size(Interface * interface)
+{
+ int new_size;
+ socklen_t sockOptLen = sizeof(int);
+
+ if (getsockopt(interface->fd, SOL_SOCKET, SO_SNDBUF,
+ (char *)&new_size, &sockOptLen) < 0) {
+ DEBUG("problem getting sockets send buffer size\n");
+ return INTERFACE_DEFAULT_OUT_BUFFER_SIZE;
+ }
+ if (new_size > 0)
+ return new_size;
+ DEBUG("sockets send buffer size is not positive\n");
+ return INTERFACE_DEFAULT_OUT_BUFFER_SIZE;
+}
+#else /* !SO_SNDBUF */
+static int get_default_snd_buf_size(Interface * interface)
+{
+ return INTERFACE_DEFAULT_OUT_BUFFER_SIZE;
+}
+#endif /* !SO_SNDBUF */
+
+static void set_send_buf_size(Interface * interface)
+{
+ int new_size = get_default_snd_buf_size(interface);
+ if (interface->send_buf_size != new_size) {
+ interface->send_buf_size = new_size;
+ /* don't resize to get smaller, only bigger */
+ if (interface->send_buf_alloc < new_size) {
+ if (interface->send_buf)
+ free(interface->send_buf);
+ interface->send_buf = malloc(new_size);
+ interface->send_buf_alloc = new_size;
+ }
+ }
+}
+
static void openInterface(Interface * interface, int fd)
{
int flags;
- assert(interface->open == 0);
+ assert(interface->fd < 0);
+ interface->cmd_list_size = 0;
+ interface->cmd_list_dup = 0;
+ interface->cmd_list_OK = -1;
interface->bufferLength = 0;
interface->bufferPos = 0;
interface->fd = fd;
- /* fcntl(interface->fd,F_SETOWN,(int)getpid()); */
while ((flags = fcntl(fd, F_GETFL)) < 0 && errno == EINTR) ;
- flags |= O_NONBLOCK;
- while (fcntl(interface->fd, F_SETFL, flags) < 0 && errno == EINTR) ;
- while ((interface->fp = fdopen(fd, "rw")) == NULL && errno == EINTR) ;
- interface->open = 1;
+ while (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0 && errno == EINTR) ;
interface->lastTime = time(NULL);
- interface->commandList = NULL;
- interface->bufferList = NULL;
+ interface->cmd_list = NULL;
+ interface->cmd_list_tail = NULL;
+ interface->deferred_send = NULL;
interface->expired = 0;
- interface->outputBufferSize = 0;
- interface->outBuflen = 0;
+ interface->deferred_bytes = 0;
+ interface->send_buf_used = 0;
interface->permission = getDefaultPermissions();
+ set_send_buf_size(interface);
- interface->outBufSize = INTERFACE_DEFAULT_OUT_BUFFER_SIZE;
-#ifdef SO_SNDBUF
- {
- int getSize;
- unsigned int sockOptLen = sizeof(int);
-
- if (getsockopt(interface->fd, SOL_SOCKET, SO_SNDBUF,
- (char *)&getSize, &sockOptLen) < 0) {
- DEBUG("problem getting sockets send buffer size\n");
- } else if (getSize <= 0) {
- DEBUG("sockets send buffer size is not positive\n");
+ xwrite(fd, GREETING, strlen(GREETING));
+}
+
+static void free_cmd_list(struct strnode *list)
+{
+ struct strnode *tmp = list;
+
+ while (tmp) {
+ struct strnode *next = tmp->next;
+ if (tmp >= list_cache_head && tmp <= list_cache_tail) {
+ /* inside list_cache[] array */
+ tmp->data = NULL;
+ tmp->next = NULL;
} else
- interface->outBufSize = getSize;
+ free(tmp);
+ tmp = next;
}
-#endif
- interface->outBuffer = malloc(interface->outBufSize);
+}
- myfprintf(interface->fp, "%s %s\n", GREETING, VERSION);
- printInterfaceOutBuffer(interface);
+static void cmd_list_clone(Interface * interface)
+{
+ struct strnode *new = dup_strlist(interface->cmd_list);
+ free_cmd_list(interface->cmd_list);
+ interface->cmd_list = new;
+ interface->cmd_list_dup = 1;
+
+ /* new tail */
+ while (new && new->next)
+ new = new->next;
+ interface->cmd_list_tail = new;
}
-static void closeInterface(Interface * interface)
+static void new_cmd_list_ptr(Interface * interface, char *s, const int size)
{
- if (!interface->open)
- return;
+ int i;
+ struct strnode *new;
+
+ if (!interface->cmd_list_dup) {
+ for (i = interface_list_cache_size - 1; i >= 0; --i) {
+ if (list_cache[i].data)
+ continue;
+ new = &(list_cache[i]);
+ new->data = s;
+ /* implied in free_cmd_list() and init: */
+ /* last->next->next = NULL; */
+ goto out;
+ }
+ }
- interface->open = 0;
+ /* allocate from the heap */
+ new = interface->cmd_list_dup ? new_strnode_dup(s, size)
+ : new_strnode(s);
+out:
+ if (interface->cmd_list) {
+ interface->cmd_list_tail->next = new;
+ interface->cmd_list_tail = new;
+ } else
+ interface->cmd_list = interface->cmd_list_tail = new;
+}
- while (fclose(interface->fp) && errno == EINTR) ;
+static void closeInterface(Interface * interface)
+{
+ struct sllnode *buf;
+ if (interface->fd < 0)
+ return;
+ xclose(interface->fd);
+ interface->fd = -1;
- if (interface->commandList)
- freeList(interface->commandList);
- if (interface->bufferList)
- freeList(interface->bufferList);
+ if (interface->cmd_list) {
+ free_cmd_list(interface->cmd_list);
+ interface->cmd_list = NULL;
+ }
- free(interface->outBuffer);
+ if ((buf = interface->deferred_send)) {
+ do {
+ struct sllnode *prev = buf;
+ buf = buf->next;
+ free(prev);
+ } while (buf);
+ interface->deferred_send = NULL;
+ }
SECURE("interface %i: closed\n", interface->num);
}
@@ -157,11 +251,12 @@ void openAInterface(int fd, struct sockaddr *addr)
{
int i;
- for (i = 0; i < interface_max_connections && interfaces[i].open; i++) ;
+ for (i = 0; i < interface_max_connections
+ && interfaces[i].fd >= 0; i++) /* nothing */ ;
if (i == interface_max_connections) {
ERROR("Max Connections Reached!\n");
- while (close(fd) && errno == EINTR) ;
+ xclose(fd);
} else {
SECURE("interface %i: opened from ", i);
switch (addr->sa_family) {
@@ -207,74 +302,60 @@ static int processLineOfInput(Interface * interface)
int ret = 1;
char *line = interface->buffer + interface->bufferPos;
- if (interface->bufferLength - interface->bufferPos > 1) {
- if (interface->buffer[interface->bufferLength - 2] == '\r') {
- interface->buffer[interface->bufferLength - 2] = '\0';
- }
- }
-
- if (interface->commandList) {
+ if (interface->cmd_list_OK >= 0) {
if (strcmp(line, INTERFACE_LIST_MODE_END) == 0) {
DEBUG("interface %i: process command "
"list\n", interface->num);
- ret = processListOfCommands(interface->fp,
+ ret = processListOfCommands(interface->fd,
&(interface->permission),
&(interface->expired),
- interface->commandListOK,
- interface->commandList);
+ interface->cmd_list_OK,
+ interface->cmd_list);
DEBUG("interface %i: process command "
"list returned %i\n", interface->num, ret);
if (ret == 0)
- commandSuccess(interface->fp);
+ commandSuccess(interface->fd);
else if (ret == COMMAND_RETURN_CLOSE
- || interface->expired) {
-
+ || interface->expired)
closeInterface(interface);
- }
- printInterfaceOutBuffer(interface);
- freeList(interface->commandList);
- interface->commandList = NULL;
+ printInterfaceOutBuffer(interface);
+ free_cmd_list(interface->cmd_list);
+ interface->cmd_list = NULL;
+ interface->cmd_list_OK = -1;
} else {
- interface->commandListSize += sizeof(ListNode);
- interface->commandListSize += strlen(line) + 1;
- if (interface->commandListSize >
+ size_t len = strlen(line) + 1;
+ interface->cmd_list_size += len;
+ if (interface->cmd_list_size >
interface_max_command_list_size) {
ERROR("interface %i: command "
- "list size (%lli) is "
+ "list size (%i) is "
"larger than the max "
- "(%lli)\n",
+ "(%i)\n",
interface->num,
- (long long)interface->
- commandListSize, (long long)
+ interface->cmd_list_size,
interface_max_command_list_size);
closeInterface(interface);
ret = COMMAND_RETURN_CLOSE;
- } else {
- insertInListWithoutKey(interface->commandList,
- strdup(line));
- }
+ } else
+ new_cmd_list_ptr(interface, line, len);
}
} else {
if (strcmp(line, INTERFACE_LIST_MODE_BEGIN) == 0) {
- interface->commandList = makeList(free, 1);
- interface->commandListSize = sizeof(List);
- interface->commandListOK = 0;
+ interface->cmd_list_OK = 0;
ret = 1;
} else if (strcmp(line, INTERFACE_LIST_OK_MODE_BEGIN) == 0) {
- interface->commandList = makeList(free, 1);
- interface->commandListSize = sizeof(List);
- interface->commandListOK = 1;
+ interface->cmd_list_OK = 1;
ret = 1;
} else {
DEBUG("interface %i: process command \"%s\"\n",
interface->num, line);
- ret = processCommand(interface->fp,
+ ret = processCommand(interface->fd,
&(interface->permission), line);
DEBUG("interface %i: command returned %i\n",
interface->num, ret);
if (ret == 0)
- commandSuccess(interface->fp);
+ commandSuccess(interface->fd);
else if (ret == COMMAND_RETURN_CLOSE
|| interface->expired) {
closeInterface(interface);
@@ -289,12 +370,18 @@ static int processLineOfInput(Interface * interface)
static int processBytesRead(Interface * interface, int bytesRead)
{
int ret = 0;
+ char *buf_tail = &(interface->buffer[interface->bufferLength - 1]);
while (bytesRead > 0) {
interface->bufferLength++;
bytesRead--;
- if (interface->buffer[interface->bufferLength - 1] == '\n') {
- interface->buffer[interface->bufferLength - 1] = '\0';
+ buf_tail++;
+ if (*buf_tail == '\n') {
+ *buf_tail = '\0';
+ if (interface->bufferLength - interface->bufferPos > 1) {
+ if (*(buf_tail - 1) == '\r')
+ *(buf_tail - 1) = '\0';
+ }
ret = processLineOfInput(interface);
interface->bufferPos = interface->bufferLength;
}
@@ -305,6 +392,9 @@ static int processBytesRead(Interface * interface, int bytesRead)
closeInterface(interface);
return 1;
}
+ if (interface->cmd_list_OK >= 0 &&
+ !interface->cmd_list_dup)
+ cmd_list_clone(interface);
interface->bufferLength -= interface->bufferPos;
memmove(interface->buffer,
interface->buffer + interface->bufferPos,
@@ -347,8 +437,8 @@ static void addInterfacesReadyToReadAndListenSocketToFdSet(fd_set * fds,
addListenSocketsToFdSet(fds, fdmax);
for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].open && !interfaces[i].expired
- && !interfaces[i].bufferList) {
+ if (interfaces[i].fd >= 0 && !interfaces[i].expired
+ && !interfaces[i].deferred_send) {
FD_SET(interfaces[i].fd, fds);
if (*fdmax < interfaces[i].fd)
*fdmax = interfaces[i].fd;
@@ -363,8 +453,8 @@ static void addInterfacesForBufferFlushToFdSet(fd_set * fds, int *fdmax)
FD_ZERO(fds);
for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].open && !interfaces[i].expired
- && interfaces[i].bufferList) {
+ if (interfaces[i].fd >= 0 && !interfaces[i].expired
+ && interfaces[i].deferred_send) {
FD_SET(interfaces[i].fd, fds);
if (*fdmax < interfaces[i].fd)
*fdmax = interfaces[i].fd;
@@ -382,7 +472,7 @@ static void closeNextErroredInterface(void)
tv.tv_usec = 0;
for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].open) {
+ if (interfaces[i].fd >= 0) {
FD_ZERO(&fds);
FD_SET(interfaces[i].fd, &fds);
if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) < 0) {
@@ -424,7 +514,7 @@ int doIOForInterfaces(void)
getConnections(&rfds);
for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].open
+ if (interfaces[i].fd >= 0
&& FD_ISSET(interfaces[i].fd, &rfds)) {
if (COMMAND_RETURN_KILL ==
interfaceReadInput(&(interfaces[i]))) {
@@ -432,7 +522,7 @@ int doIOForInterfaces(void)
}
interfaces[i].lastTime = time(NULL);
}
- if (interfaces[i].open
+ if (interfaces[i].fd >= 0
&& FD_ISSET(interfaces[i].fd, &wfds)) {
flushInterfaceBuffer(&interfaces[i]);
interfaces[i].lastTime = time(NULL);
@@ -504,8 +594,15 @@ void initInterfaces(void)
interfaces = malloc(sizeof(Interface) * interface_max_connections);
+ list_cache = calloc(interface_list_cache_size, sizeof(struct strnode));
+ list_cache_head = &(list_cache[0]);
+ list_cache_tail = &(list_cache[interface_list_cache_size - 1]);
+
for (i = 0; i < interface_max_connections; i++) {
- interfaces[i].open = 0;
+ interfaces[i].fd = -1;
+ interfaces[i].send_buf = NULL;
+ interfaces[i].send_buf_size = 0;
+ interfaces[i].send_buf_alloc = 0;
interfaces[i].num = i;
}
}
@@ -514,13 +611,13 @@ static void closeAllInterfaces(void)
{
int i;
- fflush(NULL);
-
for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].open) {
+ if (interfaces[i].fd > 0)
closeInterface(&(interfaces[i]));
- }
+ if (interfaces[i].send_buf)
+ free(interfaces[i].send_buf);
}
+ free(list_cache);
}
void freeAllInterfaces(void)
@@ -537,7 +634,7 @@ void closeOldInterfaces(void)
int i;
for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].open) {
+ if (interfaces[i].fd > 0) {
if (interfaces[i].expired) {
DEBUG("interface %i: expired\n", i);
closeInterface(&(interfaces[i]));
@@ -552,37 +649,45 @@ void closeOldInterfaces(void)
static void flushInterfaceBuffer(Interface * interface)
{
- ListNode *node = NULL;
- char *str;
+ struct sllnode *buf;
int ret = 0;
- while ((node = interface->bufferList->firstNode)) {
- str = (char *)node->data;
- if ((ret = write(interface->fd, str, strlen(str))) < 0)
+ buf = interface->deferred_send;
+ while (buf) {
+ ret = write(interface->fd, buf->data, buf->size);
+ if (ret < 0)
break;
- else if (ret < strlen(str)) {
- interface->outputBufferSize -= ret;
- str = strdup(&str[ret]);
- free(node->data);
- node->data = str;
+ else if (ret < buf->size) {
+ interface->deferred_bytes -= ret;
+ buf->data += ret;
+ buf->size -= ret;
} else {
- interface->outputBufferSize -= strlen(str) + 1;
- interface->outputBufferSize -= sizeof(ListNode);
- deleteNodeFromList(interface->bufferList, node);
+ struct sllnode *tmp = buf;
+ interface->deferred_bytes -= (buf->size +
+ sizeof(struct sllnode));
+ buf = buf->next;
+ free(tmp);
+ interface->deferred_send = buf;
}
interface->lastTime = time(NULL);
}
- if (!interface->bufferList->firstNode) {
- DEBUG("interface %i: buffer empty\n", interface->num);
- freeList(interface->bufferList);
- interface->bufferList = NULL;
+ if (!interface->deferred_send) {
+ DEBUG("interface %i: buffer empty %i\n", interface->num,
+ interface->deferred_bytes);
+ assert(interface->deferred_bytes == 0);
} else if (ret < 0 && errno != EAGAIN && errno != EINTR) {
/* cause interface to close */
DEBUG("interface %i: problems flushing buffer\n",
interface->num);
- freeList(interface->bufferList);
- interface->bufferList = NULL;
+ buf = interface->deferred_send;
+ do {
+ struct sllnode *prev = buf;
+ buf = buf->next;
+ free(prev);
+ } while (buf);
+ interface->deferred_send = NULL;
+ interface->deferred_bytes = 0;
interface->expired = 1;
}
}
@@ -593,10 +698,12 @@ int interfacePrintWithFD(int fd, char *buffer, int buflen)
int copylen;
Interface *interface;
+ assert(fd > 0);
+
if (i >= interface_max_connections ||
- !interfaces[i].open || interfaces[i].fd != fd) {
+ interfaces[i].fd < 0 || interfaces[i].fd != fd) {
for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].open && interfaces[i].fd == fd)
+ if (interfaces[i].fd == fd)
break;
}
if (i == interface_max_connections)
@@ -610,17 +717,15 @@ int interfacePrintWithFD(int fd, char *buffer, int buflen)
interface = interfaces + i;
while (buflen > 0 && !interface->expired) {
- copylen = buflen >
- interface->outBufSize - interface->outBuflen ?
- interface->outBufSize - interface->outBuflen : buflen;
- memcpy(interface->outBuffer + interface->outBuflen, buffer,
+ int left = interface->send_buf_size - interface->send_buf_used;
+ copylen = buflen > left ? left : buflen;
+ memcpy(interface->send_buf + interface->send_buf_used, buffer,
copylen);
buflen -= copylen;
- interface->outBuflen += copylen;
+ interface->send_buf_used += copylen;
buffer += copylen;
- if (interface->outBuflen >= interface->outBufSize) {
+ if (interface->send_buf_used >= interface->send_buf_size)
printInterfaceOutBuffer(interface);
- }
}
return 0;
@@ -628,73 +733,63 @@ int interfacePrintWithFD(int fd, char *buffer, int buflen)
static void printInterfaceOutBuffer(Interface * interface)
{
- char *buffer;
int ret;
+ struct sllnode *buf;
- if (!interface->open || interface->expired || !interface->outBuflen) {
+ if (interface->fd < 0 || interface->expired ||
+ !interface->send_buf_used)
return;
- }
- if (interface->bufferList) {
- interface->outputBufferSize += sizeof(ListNode);
- interface->outputBufferSize += interface->outBuflen + 1;
- if (interface->outputBufferSize >
+ if ((buf = interface->deferred_send)) {
+ interface->deferred_bytes += sizeof(struct sllnode)
+ + interface->send_buf_used;
+ if (interface->deferred_bytes >
interface_max_output_buffer_size) {
- ERROR("interface %i: output buffer size (%lli) is "
- "larger than the max (%lli)\n",
+ ERROR("interface %i: output buffer size (%li) is "
+ "larger than the max (%li)\n",
interface->num,
- (long long)interface->outputBufferSize,
- (long long)interface_max_output_buffer_size);
+ (long)interface->deferred_bytes,
+ (long)interface_max_output_buffer_size);
/* cause interface to close */
- freeList(interface->bufferList);
- interface->bufferList = NULL;
interface->expired = 1;
+ do {
+ struct sllnode *prev = buf;
+ buf = buf->next;
+ free(prev);
+ } while (buf);
+ interface->deferred_send = NULL;
+ interface->deferred_bytes = 0;
} else {
- buffer = malloc(interface->outBuflen + 1);
- memcpy(buffer, interface->outBuffer,
- interface->outBuflen);
- buffer[interface->outBuflen] = '\0';
- insertInListWithoutKey(interface->bufferList,
- (void *)buffer);
- flushInterfaceBuffer(interface);
+ while (buf->next)
+ buf = buf->next;
+ buf->next = new_sllnode(interface->send_buf,
+ interface->send_buf_used);
}
} else {
- if ((ret = write(interface->fd, interface->outBuffer,
- interface->outBuflen)) < 0) {
+ if ((ret = write(interface->fd, interface->send_buf,
+ interface->send_buf_used)) < 0) {
if (errno == EAGAIN || errno == EINTR) {
- buffer = malloc(interface->outBuflen + 1);
- memcpy(buffer, interface->outBuffer,
- interface->outBuflen);
- buffer[interface->outBuflen] = '\0';
- interface->bufferList = makeList(free, 1);
- insertInListWithoutKey(interface->bufferList,
- (void *)buffer);
+ interface->deferred_send =
+ new_sllnode(interface->send_buf,
+ interface->send_buf_used);
} else {
DEBUG("interface %i: problems writing\n",
interface->num);
interface->expired = 1;
return;
}
- } else if (ret < interface->outBuflen) {
- buffer = malloc(interface->outBuflen - ret + 1);
- memcpy(buffer, interface->outBuffer + ret,
- interface->outBuflen - ret);
- buffer[interface->outBuflen - ret] = '\0';
- interface->bufferList = makeList(free, 1);
- insertInListWithoutKey(interface->bufferList, buffer);
+ } else if (ret < interface->send_buf_used) {
+ interface->deferred_send =
+ new_sllnode(interface->send_buf + ret,
+ interface->send_buf_used - ret);
}
- /* if we needed to create buffer, initialize bufferSize info */
- if (interface->bufferList) {
+ if (interface->deferred_send) {
DEBUG("interface %i: buffer created\n", interface->num);
- interface->outputBufferSize = sizeof(List);
- interface->outputBufferSize += sizeof(ListNode);
- interface->outputBufferSize += strlen((char *)
- interface->
- bufferList->
- firstNode->data) +
- 1;
+ interface->deferred_bytes =
+ interface->deferred_send->size
+ + sizeof(struct sllnode);
}
}
- interface->outBuflen = 0;
+ interface->send_buf_used = 0;
}