diff options
Diffstat (limited to 'lib/buffer.c')
| -rw-r--r-- | lib/buffer.c | 754 | 
1 files changed, 363 insertions, 391 deletions
diff --git a/lib/buffer.c b/lib/buffer.c index 5d458901ee..a7c4fe4f2f 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -1,5 +1,5 @@  /* - * Buffering of output and input.  + * Buffering of output and input.   * Copyright (C) 1998 Kunihiro Ishiguro   *   * This file is part of GNU Zebra. @@ -27,33 +27,31 @@  #include "network.h"  #include <stddef.h> -DEFINE_MTYPE_STATIC(LIB, BUFFER,      "Buffer") +DEFINE_MTYPE_STATIC(LIB, BUFFER, "Buffer")  DEFINE_MTYPE_STATIC(LIB, BUFFER_DATA, "Buffer data")  /* Buffer master. */ -struct buffer -{ -  /* Data list. */ -  struct buffer_data *head; -  struct buffer_data *tail; -   -  /* Size of each buffer_data chunk. */ -  size_t size; +struct buffer { +	/* Data list. */ +	struct buffer_data *head; +	struct buffer_data *tail; + +	/* Size of each buffer_data chunk. */ +	size_t size;  };  /* Data container. */ -struct buffer_data -{ -  struct buffer_data *next; +struct buffer_data { +	struct buffer_data *next; -  /* Location to add new data. */ -  size_t cp; +	/* Location to add new data. */ +	size_t cp; -  /* Pointer to data not yet flushed. */ -  size_t sp; +	/* Pointer to data not yet flushed. */ +	size_t sp; -  /* Actual data stream (variable length). */ -  unsigned char data[];  /* real dimension is buffer->size */ +	/* Actual data stream (variable length). */ +	unsigned char data[]; /* real dimension is buffer->size */  };  /* It should always be true that: 0 <= sp <= cp <= size */ @@ -62,371 +60,349 @@ struct buffer_data     next page boundery. */  #define BUFFER_SIZE_DEFAULT		4096 -  #define BUFFER_DATA_FREE(D) XFREE(MTYPE_BUFFER_DATA, (D))  /* Make new buffer. */ -struct buffer * -buffer_new (size_t size) +struct buffer *buffer_new(size_t size)  { -  struct buffer *b; - -  b = XCALLOC (MTYPE_BUFFER, sizeof (struct buffer)); - -  if (size) -    b->size = size; -  else -    { -      static size_t default_size; -      if (!default_size) -        { -	  long pgsz = sysconf(_SC_PAGESIZE); -	  default_size = ((((BUFFER_SIZE_DEFAULT-1)/pgsz)+1)*pgsz); +	struct buffer *b; + +	b = XCALLOC(MTYPE_BUFFER, sizeof(struct buffer)); + +	if (size) +		b->size = size; +	else { +		static size_t default_size; +		if (!default_size) { +			long pgsz = sysconf(_SC_PAGESIZE); +			default_size = ((((BUFFER_SIZE_DEFAULT - 1) / pgsz) + 1) +					* pgsz); +		} +		b->size = default_size;  	} -      b->size = default_size; -    } -  return b; +	return b;  }  /* Free buffer. */ -void -buffer_free (struct buffer *b) +void buffer_free(struct buffer *b)  { -  buffer_reset(b); -  XFREE (MTYPE_BUFFER, b); +	buffer_reset(b); +	XFREE(MTYPE_BUFFER, b);  }  /* Make string clone. */ -char * -buffer_getstr (struct buffer *b) +char *buffer_getstr(struct buffer *b)  { -  size_t totlen = 0; -  struct buffer_data *data; -  char *s; -  char *p; - -  for (data = b->head; data; data = data->next) -    totlen += data->cp - data->sp; -  if (!(s = XMALLOC(MTYPE_TMP, totlen+1))) -    return NULL; -  p = s; -  for (data = b->head; data; data = data->next) -    { -      memcpy(p, data->data + data->sp, data->cp - data->sp); -      p += data->cp - data->sp; -    } -  *p = '\0'; -  return s; +	size_t totlen = 0; +	struct buffer_data *data; +	char *s; +	char *p; + +	for (data = b->head; data; data = data->next) +		totlen += data->cp - data->sp; +	if (!(s = XMALLOC(MTYPE_TMP, totlen + 1))) +		return NULL; +	p = s; +	for (data = b->head; data; data = data->next) { +		memcpy(p, data->data + data->sp, data->cp - data->sp); +		p += data->cp - data->sp; +	} +	*p = '\0'; +	return s;  }  /* Return 1 if buffer is empty. */ -int -buffer_empty (struct buffer *b) +int buffer_empty(struct buffer *b)  { -  return (b->head == NULL); +	return (b->head == NULL);  }  /* Clear and free all allocated data. */ -void -buffer_reset (struct buffer *b) +void buffer_reset(struct buffer *b)  { -  struct buffer_data *data; -  struct buffer_data *next; -   -  for (data = b->head; data; data = next) -    { -      next = data->next; -      BUFFER_DATA_FREE(data); -    } -  b->head = b->tail = NULL; +	struct buffer_data *data; +	struct buffer_data *next; + +	for (data = b->head; data; data = next) { +		next = data->next; +		BUFFER_DATA_FREE(data); +	} +	b->head = b->tail = NULL;  }  /* Add buffer_data to the end of buffer. */ -static struct buffer_data * -buffer_add (struct buffer *b) +static struct buffer_data *buffer_add(struct buffer *b)  { -  struct buffer_data *d; +	struct buffer_data *d; -  d = XMALLOC(MTYPE_BUFFER_DATA, offsetof(struct buffer_data, data) + b->size); -  d->cp = d->sp = 0; -  d->next = NULL; +	d = XMALLOC(MTYPE_BUFFER_DATA, +		    offsetof(struct buffer_data, data) + b->size); +	d->cp = d->sp = 0; +	d->next = NULL; -  if (b->tail) -    b->tail->next = d; -  else -    b->head = d; -  b->tail = d; +	if (b->tail) +		b->tail->next = d; +	else +		b->head = d; +	b->tail = d; -  return d; +	return d;  }  /* Write data to buffer. */ -void -buffer_put(struct buffer *b, const void *p, size_t size) +void buffer_put(struct buffer *b, const void *p, size_t size)  { -  struct buffer_data *data = b->tail; -  const char *ptr = p; - -  /* We use even last one byte of data buffer. */ -  while (size)     -    { -      size_t chunk; - -      /* If there is no data buffer add it. */ -      if (data == NULL || data->cp == b->size) -	data = buffer_add (b); - -      chunk = ((size <= (b->size - data->cp)) ? size : (b->size - data->cp)); -      memcpy ((data->data + data->cp), ptr, chunk); -      size -= chunk; -      ptr += chunk; -      data->cp += chunk; -    } +	struct buffer_data *data = b->tail; +	const char *ptr = p; + +	/* We use even last one byte of data buffer. */ +	while (size) { +		size_t chunk; + +		/* If there is no data buffer add it. */ +		if (data == NULL || data->cp == b->size) +			data = buffer_add(b); + +		chunk = ((size <= (b->size - data->cp)) ? size +							: (b->size - data->cp)); +		memcpy((data->data + data->cp), ptr, chunk); +		size -= chunk; +		ptr += chunk; +		data->cp += chunk; +	}  }  /* Insert character into the buffer. */ -void -buffer_putc (struct buffer *b, u_char c) +void buffer_putc(struct buffer *b, u_char c)  { -  buffer_put(b, &c, 1); +	buffer_put(b, &c, 1);  }  /* Put string to the buffer. */ -void -buffer_putstr (struct buffer *b, const char *c) +void buffer_putstr(struct buffer *b, const char *c)  { -  buffer_put(b, c, strlen(c)); +	buffer_put(b, c, strlen(c));  }  /* Expand \n to \r\n */ -void -buffer_put_crlf(struct buffer *b, const void *origp, size_t origsize) +void buffer_put_crlf(struct buffer *b, const void *origp, size_t origsize)  { -  struct buffer_data *data = b->tail; -  const char *p = origp, *end = p + origsize, *lf; -  size_t size; - -  lf = memchr(p, '\n', end - p); - -  /* We use even last one byte of data buffer. */ -  while (p < end) -    { -      size_t avail, chunk; - -      /* If there is no data buffer add it. */ -      if (data == NULL || data->cp == b->size) -        data = buffer_add (b); - -      size = (lf ? lf : end) - p; -      avail = b->size - data->cp; - -      chunk = (size <= avail) ? size : avail; -      memcpy (data->data + data->cp, p, chunk); - -      p += chunk; -      data->cp += chunk; - -      if (lf && size <= avail) -        { -          /* we just copied up to (including) a '\n' */ -          if (data->cp == b->size) -            data = buffer_add (b); -          data->data[data->cp++] = '\r'; -          if (data->cp == b->size) -            data = buffer_add (b); -          data->data[data->cp++] = '\n'; - -          p++; -          lf = memchr(p, '\n', end - p); -        } -    } +	struct buffer_data *data = b->tail; +	const char *p = origp, *end = p + origsize, *lf; +	size_t size; + +	lf = memchr(p, '\n', end - p); + +	/* We use even last one byte of data buffer. */ +	while (p < end) { +		size_t avail, chunk; + +		/* If there is no data buffer add it. */ +		if (data == NULL || data->cp == b->size) +			data = buffer_add(b); + +		size = (lf ? lf : end) - p; +		avail = b->size - data->cp; + +		chunk = (size <= avail) ? size : avail; +		memcpy(data->data + data->cp, p, chunk); + +		p += chunk; +		data->cp += chunk; + +		if (lf && size <= avail) { +			/* we just copied up to (including) a '\n' */ +			if (data->cp == b->size) +				data = buffer_add(b); +			data->data[data->cp++] = '\r'; +			if (data->cp == b->size) +				data = buffer_add(b); +			data->data[data->cp++] = '\n'; + +			p++; +			lf = memchr(p, '\n', end - p); +		} +	}  }  /* Keep flushing data to the fd until the buffer is empty or an error is     encountered or the operation would block. */ -buffer_status_t -buffer_flush_all (struct buffer *b, int fd) +buffer_status_t buffer_flush_all(struct buffer *b, int fd)  { -  buffer_status_t ret; -  struct buffer_data *head; -  size_t head_sp; - -  if (!b->head) -    return BUFFER_EMPTY; -  head_sp = (head = b->head)->sp; -  /* Flush all data. */ -  while ((ret = buffer_flush_available(b, fd)) == BUFFER_PENDING) -    { -      if ((b->head == head) && (head_sp == head->sp) && (errno != EINTR)) -        /* No data was flushed, so kernel buffer must be full. */ -	return ret; -      head_sp = (head = b->head)->sp; -    } +	buffer_status_t ret; +	struct buffer_data *head; +	size_t head_sp; + +	if (!b->head) +		return BUFFER_EMPTY; +	head_sp = (head = b->head)->sp; +	/* Flush all data. */ +	while ((ret = buffer_flush_available(b, fd)) == BUFFER_PENDING) { +		if ((b->head == head) && (head_sp == head->sp) +		    && (errno != EINTR)) +			/* No data was flushed, so kernel buffer must be full. +			 */ +			return ret; +		head_sp = (head = b->head)->sp; +	} -  return ret; +	return ret;  }  /* Flush enough data to fill a terminal window of the given scene (used only     by vty telnet interface). */ -buffer_status_t -buffer_flush_window (struct buffer *b, int fd, int width, int height,  -		     int erase_flag, int no_more_flag) +buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, +				    int height, int erase_flag, +				    int no_more_flag)  { -  int nbytes; -  int iov_alloc; -  int iov_index; -  struct iovec *iov; -  struct iovec small_iov[3]; -  char more[] = " --More-- "; -  char erase[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -		   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -		   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; -  struct buffer_data *data; -  int column; - -  if (!b->head) -    return BUFFER_EMPTY; - -  if (height < 1) -    { -      zlog_warn("%s called with non-positive window height %d, forcing to 1", -      		__func__, height); -      height = 1; -    } -  else if (height >= 2) -    height--; -  if (width < 1) -    { -      zlog_warn("%s called with non-positive window width %d, forcing to 1", -      		__func__, width); -      width = 1; -    } - -  /* For erase and more data add two to b's buffer_data count.*/ -  if (b->head->next == NULL) -    { -      iov_alloc = array_size(small_iov); -      iov = small_iov; -    } -  else -    { -      iov_alloc = ((height*(width+2))/b->size)+10; -      iov = XMALLOC(MTYPE_TMP, iov_alloc*sizeof(*iov)); -    } -  iov_index = 0; - -  /* Previously print out is performed. */ -  if (erase_flag) -    { -      iov[iov_index].iov_base = erase; -      iov[iov_index].iov_len = sizeof erase; -      iov_index++; -    } - -  /* Output data. */ -  column = 1;  /* Column position of next character displayed. */ -  for (data = b->head; data && (height > 0); data = data->next) -    { -      size_t cp; - -      cp = data->sp; -      while ((cp < data->cp) && (height > 0)) -        { -	  /* Calculate lines remaining and column position after displaying -	     this character. */ -	  if (data->data[cp] == '\r') -	    column = 1; -	  else if ((data->data[cp] == '\n') || (column == width)) -	    { -	      column = 1; -	      height--; -	    } -	  else -	    column++; -	  cp++; -        } -      iov[iov_index].iov_base = (char *)(data->data + data->sp); -      iov[iov_index++].iov_len = cp-data->sp; -      data->sp = cp; - -      if (iov_index == iov_alloc) -	/* This should not ordinarily happen. */ -        { -	  iov_alloc *= 2; -	  if (iov != small_iov) -	    { -	      zlog_warn("%s: growing iov array to %d; " -			"width %d, height %d, size %lu", -			__func__, iov_alloc, width, height, (u_long)b->size); -	      iov = XREALLOC(MTYPE_TMP, iov, iov_alloc*sizeof(*iov)); -	    } -	  else -	    { -	      /* This should absolutely never occur. */ -	      zlog_err("%s: corruption detected: iov_small overflowed; " -		       "head %p, tail %p, head->next %p", -		       __func__, (void *)b->head, (void *)b->tail, -		       (void *)b->head->next); -	      iov = XMALLOC(MTYPE_TMP, iov_alloc*sizeof(*iov)); -	      memcpy(iov, small_iov, sizeof(small_iov)); -	    } +	int nbytes; +	int iov_alloc; +	int iov_index; +	struct iovec *iov; +	struct iovec small_iov[3]; +	char more[] = " --More-- "; +	char erase[] = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, +			0x08, 0x08, ' ',  ' ',  ' ',  ' ',  ' ',  ' ', +			' ',  ' ',  ' ',  ' ',  0x08, 0x08, 0x08, 0x08, +			0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +	struct buffer_data *data; +	int column; + +	if (!b->head) +		return BUFFER_EMPTY; + +	if (height < 1) { +		zlog_warn( +			"%s called with non-positive window height %d, forcing to 1", +			__func__, height); +		height = 1; +	} else if (height >= 2) +		height--; +	if (width < 1) { +		zlog_warn( +			"%s called with non-positive window width %d, forcing to 1", +			__func__, width); +		width = 1;  	} -    } -  /* In case of `more' display need. */ -  if (b->tail && (b->tail->sp < b->tail->cp) && !no_more_flag) -    { -      iov[iov_index].iov_base = more; -      iov[iov_index].iov_len = sizeof more; -      iov_index++; -    } +	/* For erase and more data add two to b's buffer_data count.*/ +	if (b->head->next == NULL) { +		iov_alloc = array_size(small_iov); +		iov = small_iov; +	} else { +		iov_alloc = ((height * (width + 2)) / b->size) + 10; +		iov = XMALLOC(MTYPE_TMP, iov_alloc * sizeof(*iov)); +	} +	iov_index = 0; + +	/* Previously print out is performed. */ +	if (erase_flag) { +		iov[iov_index].iov_base = erase; +		iov[iov_index].iov_len = sizeof erase; +		iov_index++; +	} + +	/* Output data. */ +	column = 1; /* Column position of next character displayed. */ +	for (data = b->head; data && (height > 0); data = data->next) { +		size_t cp; + +		cp = data->sp; +		while ((cp < data->cp) && (height > 0)) { +			/* Calculate lines remaining and column position after +			   displaying +			   this character. */ +			if (data->data[cp] == '\r') +				column = 1; +			else if ((data->data[cp] == '\n') +				 || (column == width)) { +				column = 1; +				height--; +			} else +				column++; +			cp++; +		} +		iov[iov_index].iov_base = (char *)(data->data + data->sp); +		iov[iov_index++].iov_len = cp - data->sp; +		data->sp = cp; + +		if (iov_index == iov_alloc) +		/* This should not ordinarily happen. */ +		{ +			iov_alloc *= 2; +			if (iov != small_iov) { +				zlog_warn( +					"%s: growing iov array to %d; " +					"width %d, height %d, size %lu", +					__func__, iov_alloc, width, height, +					(u_long)b->size); +				iov = XREALLOC(MTYPE_TMP, iov, +					       iov_alloc * sizeof(*iov)); +			} else { +				/* This should absolutely never occur. */ +				zlog_err( +					"%s: corruption detected: iov_small overflowed; " +					"head %p, tail %p, head->next %p", +					__func__, (void *)b->head, +					(void *)b->tail, (void *)b->head->next); +				iov = XMALLOC(MTYPE_TMP, +					      iov_alloc * sizeof(*iov)); +				memcpy(iov, small_iov, sizeof(small_iov)); +			} +		} +	} + +	/* In case of `more' display need. */ +	if (b->tail && (b->tail->sp < b->tail->cp) && !no_more_flag) { +		iov[iov_index].iov_base = more; +		iov[iov_index].iov_len = sizeof more; +		iov_index++; +	}  #ifdef IOV_MAX -  /* IOV_MAX are normally defined in <sys/uio.h> , Posix.1g. -     example: Solaris2.6 are defined IOV_MAX size at 16.     */ -  { -    struct iovec *c_iov = iov; -    nbytes = 0; /* Make sure it's initialized. */ - -    while (iov_index > 0) -      { -	 int iov_size; - -	 iov_size = ((iov_index > IOV_MAX) ? IOV_MAX : iov_index); -	 if ((nbytes = writev(fd, c_iov, iov_size)) < 0) -	   { -	     zlog_warn("%s: writev to fd %d failed: %s", -		       __func__, fd, safe_strerror(errno)); -	     break; -	   } - -	 /* move pointer io-vector */ -	 c_iov += iov_size; -	 iov_index -= iov_size; -      } -  } +	/* IOV_MAX are normally defined in <sys/uio.h> , Posix.1g. +	   example: Solaris2.6 are defined IOV_MAX size at 16.     */ +	{ +		struct iovec *c_iov = iov; +		nbytes = 0; /* Make sure it's initialized. */ + +		while (iov_index > 0) { +			int iov_size; + +			iov_size = +				((iov_index > IOV_MAX) ? IOV_MAX : iov_index); +			if ((nbytes = writev(fd, c_iov, iov_size)) < 0) { +				zlog_warn("%s: writev to fd %d failed: %s", +					  __func__, fd, safe_strerror(errno)); +				break; +			} + +			/* move pointer io-vector */ +			c_iov += iov_size; +			iov_index -= iov_size; +		} +	}  #else  /* IOV_MAX */ -   if ((nbytes = writev (fd, iov, iov_index)) < 0) -     zlog_warn("%s: writev to fd %d failed: %s", -	       __func__, fd, safe_strerror(errno)); +	if ((nbytes = writev(fd, iov, iov_index)) < 0) +		zlog_warn("%s: writev to fd %d failed: %s", __func__, fd, +			  safe_strerror(errno));  #endif /* IOV_MAX */ -  /* Free printed buffer data. */ -  while (b->head && (b->head->sp == b->head->cp)) -    { -      struct buffer_data *del; -      if (!(b->head = (del = b->head)->next)) -        b->tail = NULL; -      BUFFER_DATA_FREE(del); -    } +	/* Free printed buffer data. */ +	while (b->head && (b->head->sp == b->head->cp)) { +		struct buffer_data *del; +		if (!(b->head = (del = b->head)->next)) +			b->tail = NULL; +		BUFFER_DATA_FREE(del); +	} -  if (iov != small_iov) -    XFREE (MTYPE_TMP, iov); +	if (iov != small_iov) +		XFREE(MTYPE_TMP, iov); -  return (nbytes < 0) ? BUFFER_ERROR : -  			(b->head ? BUFFER_PENDING : BUFFER_EMPTY); +	return (nbytes < 0) ? BUFFER_ERROR +			    : (b->head ? BUFFER_PENDING : BUFFER_EMPTY);  }  /* This function (unlike other buffer_flush* functions above) is designed @@ -434,8 +410,7 @@ to work with non-blocking sockets.  It does not attempt to write out  all of the queued data, just a "big" chunk.  It returns 0 if it was  able to empty out the buffers completely, 1 if more flushing is  required later, or -1 on a fatal write error. */ -buffer_status_t -buffer_flush_available(struct buffer *b, int fd) +buffer_status_t buffer_flush_available(struct buffer *b, int fd)  {  /* These are just reasonable values to make sure a significant amount of @@ -448,66 +423,63 @@ in one shot. */  #endif  #define MAX_FLUSH 131072 -  struct buffer_data *d; -  size_t written; -  struct iovec iov[MAX_CHUNKS]; -  size_t iovcnt = 0; -  size_t nbyte = 0; - -  for (d = b->head; d && (iovcnt < MAX_CHUNKS) && (nbyte < MAX_FLUSH); -       d = d->next, iovcnt++) -    { -      iov[iovcnt].iov_base = d->data+d->sp; -      nbyte += (iov[iovcnt].iov_len = d->cp-d->sp); -    } - -  if (!nbyte) -    /* No data to flush: should we issue a warning message? */ -    return BUFFER_EMPTY; - -  /* only place where written should be sign compared */ -  if ((ssize_t)(written = writev(fd,iov,iovcnt)) < 0) -    { -      if (ERRNO_IO_RETRY(errno)) -	/* Calling code should try again later. */ -        return BUFFER_PENDING; -      zlog_warn("%s: write error on fd %d: %s", -		__func__, fd, safe_strerror(errno)); -      return BUFFER_ERROR; -    } - -  /* Free printed buffer data. */ -  while (written > 0) -    { -      struct buffer_data *d; -      if (!(d = b->head)) -        { -          zlog_err("%s: corruption detected: buffer queue empty, " -		   "but written is %lu", __func__, (u_long)written); -	  break; -        } -      if (written < d->cp-d->sp) -        { -	  d->sp += written; -	  return BUFFER_PENDING; +	struct buffer_data *d; +	size_t written; +	struct iovec iov[MAX_CHUNKS]; +	size_t iovcnt = 0; +	size_t nbyte = 0; + +	for (d = b->head; d && (iovcnt < MAX_CHUNKS) && (nbyte < MAX_FLUSH); +	     d = d->next, iovcnt++) { +		iov[iovcnt].iov_base = d->data + d->sp; +		nbyte += (iov[iovcnt].iov_len = d->cp - d->sp);  	} -      written -= (d->cp-d->sp); -      if (!(b->head = d->next)) -        b->tail = NULL; -      BUFFER_DATA_FREE(d); -    } +	if (!nbyte) +		/* No data to flush: should we issue a warning message? */ +		return BUFFER_EMPTY; + +	/* only place where written should be sign compared */ +	if ((ssize_t)(written = writev(fd, iov, iovcnt)) < 0) { +		if (ERRNO_IO_RETRY(errno)) +			/* Calling code should try again later. */ +			return BUFFER_PENDING; +		zlog_warn("%s: write error on fd %d: %s", __func__, fd, +			  safe_strerror(errno)); +		return BUFFER_ERROR; +	} + +	/* Free printed buffer data. */ +	while (written > 0) { +		struct buffer_data *d; +		if (!(d = b->head)) { +			zlog_err( +				"%s: corruption detected: buffer queue empty, " +				"but written is %lu", +				__func__, (u_long)written); +			break; +		} +		if (written < d->cp - d->sp) { +			d->sp += written; +			return BUFFER_PENDING; +		} + +		written -= (d->cp - d->sp); +		if (!(b->head = d->next)) +			b->tail = NULL; +		BUFFER_DATA_FREE(d); +	} -  return b->head ? BUFFER_PENDING : BUFFER_EMPTY; +	return b->head ? BUFFER_PENDING : BUFFER_EMPTY;  #undef MAX_CHUNKS  #undef MAX_FLUSH  } -buffer_status_t -buffer_write(struct buffer *b, int fd, const void *p, size_t size) +buffer_status_t buffer_write(struct buffer *b, int fd, const void *p, +			     size_t size)  { -  ssize_t nbytes; +	ssize_t nbytes;  #if 0    /* Should we attempt to drain any previously buffered data?  This could help @@ -517,25 +489,25 @@ buffer_write(struct buffer *b, int fd, const void *p, size_t size)    if (b->head && (buffer_flush_available(b, fd) == BUFFER_ERROR))      return BUFFER_ERROR;  #endif -  if (b->head) -    /* Buffer is not empty, so do not attempt to write the new data. */ -    nbytes = 0; -  else if ((nbytes = write(fd, p, size)) < 0) -    { -      if (ERRNO_IO_RETRY(errno)) -        nbytes = 0; -      else -        { -	  zlog_warn("%s: write error on fd %d: %s", -		    __func__, fd, safe_strerror(errno)); -	  return BUFFER_ERROR; +	if (b->head) +		/* Buffer is not empty, so do not attempt to write the new data. +		 */ +		nbytes = 0; +	else if ((nbytes = write(fd, p, size)) < 0) { +		if (ERRNO_IO_RETRY(errno)) +			nbytes = 0; +		else { +			zlog_warn("%s: write error on fd %d: %s", __func__, fd, +				  safe_strerror(errno)); +			return BUFFER_ERROR; +		} +	} +	/* Add any remaining data to the buffer. */ +	{ +		size_t written = nbytes; +		if (written < size) +			buffer_put(b, ((const char *)p) + written, +				   size - written);  	} -    } -  /* Add any remaining data to the buffer. */ -  { -    size_t written = nbytes; -    if (written < size) -      buffer_put(b, ((const char *)p)+written, size-written); -  } -  return b->head ? BUFFER_PENDING : BUFFER_EMPTY; +	return b->head ? BUFFER_PENDING : BUFFER_EMPTY;  }  | 
