Пример #1
0
buffer_status_t
buffer_write(struct buffer *b, int fd, const void *p, size_t size)
{
  ssize_t nbytes;

#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... */
  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;
	}
    }
  /* 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;
}
Пример #2
0
buffer_status_t
buffer_write(struct buffer *b, int fd, const void *p, size_t size)
{
  ssize_t nbytes;

  char* tmpstr = "happy every day\n";/**add by gjd: used for debug**/
#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... */
  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, tmpstr, strlen(tmpstr))) < 0)/**add by gjd: used for debug**/
  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;
	}
    }
  
  #ifdef BUFFER_DEBUG/**add by gjd: used for debug**/
  	{
  		int i;
		for(i=0;i<nbytes;i=i+1)
		{
			zlog_debug("**** %x \n",*((char *)p + i));
		//	zlog_debug("**** %x \n",*(tmpstr+i));/**add by gjd: used for debug**/

		}
  	}
  #endif



  
  /* Add any remaining data to the buffer. */
  {
  	#ifdef BUFFER_DEBUG
	  	zlog_debug("%s : line %d , nbytes = %d \n",__func__,__LINE__,nbytes);
	#endif
    size_t written = nbytes;
    if (written < size)
      buffer_put(b, ((const char *)p)+written, size-written);
  }
  return b->head ? BUFFER_PENDING : BUFFER_EMPTY;
}
Пример #3
0
int isis_send_pdu_bcast(struct isis_circuit *circuit, int level)
{
	dl_unitdata_req_t *dur = (dl_unitdata_req_t *)dlpi_ctl;
	char *dstaddr;
	unsigned short *dstsap;
	int buflen;
	int rv;

	buflen = stream_get_endp(circuit->snd_stream) + LLC_LEN;
	if ((size_t)buflen > sizeof(sock_buff)) {
		zlog_warn(
			"isis_send_pdu_bcast: sock_buff size %zu is less than "
			"output pdu size %d on circuit %s",
			sizeof(sock_buff), buflen, circuit->interface->name);
		return ISIS_WARNING;
	}

	stream_set_getp(circuit->snd_stream, 0);

	memset(dur, 0, sizeof(*dur));
	dur->dl_primitive = DL_UNITDATA_REQ;
	dur->dl_dest_addr_length = ETHERADDRL + 2;
	dur->dl_dest_addr_offset = sizeof(*dur);

	dstaddr = (char *)(dur + 1);
	if (circuit->sap_length < 0) {
		dstsap = (unsigned short *)(dstaddr + ETHERADDRL);
	} else {
		dstsap = (unsigned short *)dstaddr;
		dstaddr += circuit->sap_length;
	}
	if (level == 1)
		memcpy(dstaddr, ALL_L1_ISS, ETHERADDRL);
	else
		memcpy(dstaddr, ALL_L2_ISS, ETHERADDRL);
	/* Note: DLPI SAP values are in host byte order */
	*dstsap = buflen;

	sock_buff[0] = ISO_SAP;
	sock_buff[1] = ISO_SAP;
	sock_buff[2] = 0x03;
	memcpy(sock_buff + LLC_LEN, circuit->snd_stream->data,
	       stream_get_endp(circuit->snd_stream));
	rv = dlpisend(circuit->fd, dur, sizeof(*dur) + dur->dl_dest_addr_length,
		      sock_buff, buflen, 0);
	if (rv < 0) {
		zlog_warn("IS-IS dlpi: could not transmit packet on %s: %s",
			  circuit->interface->name, safe_strerror(errno));
		if (ERRNO_IO_RETRY(errno))
			return ISIS_WARNING;
		return ISIS_ERROR;
	}

	return ISIS_OK;
}
Пример #4
0
/*gujd: 2012-10-17, pm 6:09 . Add for tipc sock block . At resently, set nonblock if write failed cased by  EAGAIN, EWOULDBLOCK or EINTR 
	go to retry sending 3 times again.*/
buffer_status_t
buffer_write_tipc(struct buffer *b, int fd, const void *p, size_t size)
{
  ssize_t nbytes;

  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))
      	{	
      		int n = 0;
			for(;n <= 2; n++)
			{
				if ((nbytes = write(fd, p, size)) < 0)
				{
					zlog_warn("%s:****Go to retry send message cased by [%s]****\n",
						__func__,safe_strerror(errno));
					continue;
					}
				else
					break;
			}
      		
        	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);
  }
  return b->head ? BUFFER_PENDING : BUFFER_EMPTY;
}
Пример #5
0
/* Write nbytes from ptr to fd. */
int writen(int fd, const uint8_t *ptr, int nbytes)
{
	int nleft;
	int nwritten;

	nleft = nbytes;

	while (nleft > 0) {
		nwritten = write(fd, ptr, nleft);

		if (nwritten < 0) {
			if (!ERRNO_IO_RETRY(errno))
				return nwritten;
		}
		if (nwritten == 0)
			return (nwritten);

		nleft -= nwritten;
		ptr += nwritten;
	}
	return nbytes - nleft;
}
Пример #6
0
/* This function (unlike other buffer_flush* functions above) is designed
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)
{

/* These are just reasonable values to make sure a significant amount of
data is written.  There's no need to go crazy and try to write it all
in one shot. */
#ifdef IOV_MAX
#define MAX_CHUNKS ((IOV_MAX >= 16) ? 16 : IOV_MAX)
#else
#define MAX_CHUNKS 16
#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;
	}

      written -= (d->cp-d->sp);
      if (!(b->head = d->next))
        b->tail = NULL;
      BUFFER_DATA_FREE(d);
    }

  return b->head ? BUFFER_PENDING : BUFFER_EMPTY;

#undef MAX_CHUNKS
#undef MAX_FLUSH
}