diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vty/buffer.c | 31 | ||||
-rw-r--r-- | src/vty/vty.c | 7 |
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..27e35fe0 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#4146. */ + return 0; + } + /* Try to write to initial buffer. */ va_copy(args, ap); len = vsnprintf(buf, sizeof buf, format, args); |