aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vty/buffer.c31
-rw-r--r--src/vty/vty.c7
2 files changed, 35 insertions, 3 deletions
diff --git a/src/vty/buffer.c b/src/vty/buffer.c
index e68e3a20..486aafb1 100644
--- a/src/vty/buffer.c
+++ b/src/vty/buffer.c
@@ -92,6 +92,8 @@ struct buffer *buffer_new(void *ctx, size_t size)
/* Free buffer. */
void buffer_free(struct buffer *b)
{
+ if (!b)
+ return;
buffer_reset(b);
talloc_free(b);
}
@@ -104,6 +106,9 @@ char *buffer_getstr(struct buffer *b)
char *s;
char *p;
+ if (!b)
+ return NULL;
+
for (data = b->head; data; data = data->next)
totlen += data->cp - data->sp;
if (!(s = _talloc_zero(tall_vty_ctx, (totlen + 1), "buffer_getstr")))
@@ -120,7 +125,7 @@ char *buffer_getstr(struct buffer *b)
/* Return 1 if buffer is empty. */
int buffer_empty(struct buffer *b)
{
- return (b->head == NULL);
+ return (!b || b->head == NULL);
}
/* Clear and free all allocated data. */
@@ -129,6 +134,9 @@ void buffer_reset(struct buffer *b)
struct buffer_data *data;
struct buffer_data *next;
+ if (!b)
+ return;
+
for (data = b->head; data; data = next) {
next = data->next;
BUFFER_DATA_FREE(data);
@@ -141,6 +149,9 @@ static struct buffer_data *buffer_add(struct buffer *b)
{
struct buffer_data *d;
+ if (!b)
+ return NULL;
+
d = _talloc_zero(b,
offsetof(struct buffer_data, data[b->size]),
"buffer_add");
@@ -161,9 +172,14 @@ static struct buffer_data *buffer_add(struct buffer *b)
/* Write data to buffer. */
void buffer_put(struct buffer *b, const void *p, size_t size)
{
- struct buffer_data *data = b->tail;
+ struct buffer_data *data;
const char *ptr = p;
+ if (!b)
+ return;
+
+ data = b->tail;
+
/* We use even last one byte of data buffer. */
while (size) {
size_t chunk;
@@ -185,12 +201,16 @@ void buffer_put(struct buffer *b, const void *p, size_t size)
/* Insert character into the buffer. */
void buffer_putc(struct buffer *b, unsigned char c)
{
+ if (!b)
+ return;
buffer_put(b, &c, 1);
}
/* Put string to the buffer. */
void buffer_putstr(struct buffer *b, const char *c)
{
+ if (!b)
+ return;
buffer_put(b, c, strlen(c));
}
@@ -202,7 +222,7 @@ buffer_status_t buffer_flush_all(struct buffer *b, int fd)
struct buffer_data *head;
size_t head_sp;
- if (!b->head)
+ if (!b || !b->head)
return BUFFER_EMPTY;
head_sp = (head = b->head)->sp;
/* Flush all data. */
@@ -395,6 +415,9 @@ in one shot. */
size_t iovcnt = 0;
size_t nbyte = 0;
+ if (!b)
+ return BUFFER_EMPTY;
+
for (d = b->head; d && (iovcnt < MAX_CHUNKS) && (nbyte < MAX_FLUSH);
d = d->next, iovcnt++) {
iov[iovcnt].iov_base = d->data + d->sp;
@@ -440,6 +463,8 @@ buffer_write(struct buffer * b, int fd, const void *p, size_t size)
{
ssize_t nbytes;
+ if (!b)
+ return BUFFER_ERROR;
#if 0
/* Should we attempt to drain any previously buffered data? This could help reduce latency in pushing out the data if we are stuck in a long-running thread that is preventing the main select loop from calling the flush thread... */
diff --git a/src/vty/vty.c b/src/vty/vty.c
index a96d86ce..33160170 100644
--- a/src/vty/vty.c
+++ b/src/vty/vty.c
@@ -260,6 +260,13 @@ int vty_out_va(struct vty *vty, const char *format, va_list ap)
vprintf(format, ap);
} else {
va_list args;
+
+ if (!vty->obuf) {
+ /* There is no output buffer. This can happen from logging to a telnet session, during cleanup
+ * of this same (killed) telnet session. See OS#4164. */
+ return 0;
+ }
+
/* Try to write to initial buffer. */
va_copy(args, ap);
len = vsnprintf(buf, sizeof buf, format, args);