示例#1
0
static void
_sendto (cbuf_t cbuf, int fd, struct sockaddr_in *destaddr)
{
  int n, rv;
  uint8_t buf[IPMIPOWER_PACKET_BUFLEN];

  if ((n = cbuf_read (cbuf, buf, IPMIPOWER_PACKET_BUFLEN)) < 0)
    {
      IPMIPOWER_ERROR (("cbuf_read: %s", fd, strerror (errno)));
      exit (EXIT_FAILURE);
    }

  if (n == IPMIPOWER_PACKET_BUFLEN)
    {
      IPMIPOWER_ERROR (("cbuf_read: buffer full"));
      exit (EXIT_FAILURE);
    }

  do 
    {
      if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN)
	rv = ipmi_lan_sendto (fd,
			      buf,
			      n,
			      0,
			      (struct sockaddr *)destaddr,
			      sizeof (struct sockaddr_in));
      else
	{
	  if (ipmi_is_ipmi_1_5_packet (buf, n))
	    rv = ipmi_lan_sendto (fd,
				  buf,
				  n,
				  0,
				  (struct sockaddr *)destaddr,
				  sizeof (struct sockaddr_in));
	  else
	    rv = ipmi_rmcpplus_sendto (fd,
				       buf,
				       n,
				       0,
				       (struct sockaddr *)destaddr,
				       sizeof (struct sockaddr_in));
	}
    } while (rv < 0 && errno == EINTR);

  if (rv < 0)
    {
      IPMIPOWER_ERROR (("ipmi_lan/rmcpplus_sendto: %s", strerror (errno)));
      exit (EXIT_FAILURE);
    }

  /* cbuf should be empty now */
  if (!cbuf_is_empty (cbuf))
    {
      IPMIPOWER_ERROR (("cbuf not empty"));
      exit (EXIT_FAILURE);
    }
}
示例#2
0
文件: zio.c 项目: surajpkn/flux-core
static int zio_fd_read (zio_t *zio, void *dst, int len)
{
    assert (zio != NULL);
    assert (zio->magic == ZIO_MAGIC);
    assert (zio->buf);

    if (zio_line_buffered (zio) && !zio_eof (zio))
        return cbuf_read_line (zio->buf, dst, len, -1);
    else
        return cbuf_read (zio->buf, dst, len);
}
示例#3
0
文件: devices.c 项目: wwjnc/zeos
int sys_read_console(char* buffer, int size)
{
	if (!list_empty(&keyboardqueue) || keyboard_serving_read)
		block_current_task(&keyboardqueue, BLOCK_AT_END);
	
	keyboard_serving_read = 1;

	// 1) If we can satisfy the read(), copy the needed bytes and return
	// 2) If we can't and the buffer is full, copy the entire input buffer and block
	// 3) Otherwise, block
	int* remaining_bytes = &keyboard_req_bytes[task_struct_to_task_index(current())];
	*remaining_bytes = size;

	for (;;)
	{
		// Copy bytes from the keyboard buffer to the user buffer
		int read_bytes = 0;

		if (cbuf_size(&keyboard_input) >= *remaining_bytes)
			read_bytes = cbuf_read(&keyboard_input, buffer, *remaining_bytes, copy_to_user);
		else if (cbuf_full(&keyboard_input))
			read_bytes = cbuf_read(&keyboard_input, buffer, cbuf_size(&keyboard_input), copy_to_user);

		buffer += read_bytes;
		*remaining_bytes -= read_bytes;

		if (*remaining_bytes == 0)
			break;

		// Block process back at the beginning of the keyboard queue
		keyboard_serving_read = 0;
		block_current_task(&keyboardqueue, BLOCK_AT_BEGINNING);
	}

	keyboard_serving_read = 0;
	return size - *remaining_bytes;
}
示例#4
0
文件: util.c 项目: TUM-LIS/glip
/**
 * Backend helper: read from a cbuf
 *
 * This function is compatible to the glip_read() function and can be used in
 * backend implementations using a cbuf for storing incoming data.
 *
 * @param[in]  buf the buffer to read from
 * @param[in]  size how much data is supposed to be read
 * @param[out] data the read data
 * @param[out] size_read how much data has been read
 *
 * @return 0 if reading was successful
 * @return any other value indicates failure
 *
 * @see glip_read()
 */
int gb_util_cbuf_read(struct cbuf *buf, size_t size, uint8_t *data,
                      size_t *size_read)
{
    /* Check the fill level */
    size_t fill_level = cbuf_fill_level(buf);
    /* We read as much as possible up to size */
    size_t size_read_req = min(fill_level, size);

    /* Read from buffer */
    int rv = cbuf_read(buf, data, size_read_req);
    if (rv < 0) {
        return -1;
    }

    /* Update actual read information */
    *size_read = size_read_req;

    return 0;
}
示例#5
0
static void
_recvfrom (cbuf_t cbuf, int fd, struct sockaddr_in *srcaddr)
{
  int n, rv, dropped = 0;
  uint8_t buf[IPMIPOWER_PACKET_BUFLEN];
  struct sockaddr_in from;
  unsigned int fromlen = sizeof (struct sockaddr_in);

  do
    {
      /* For receive side, ipmi_lan_recvfrom and
       * ipmi_rmcpplus_recvfrom are identical.  So we just use
       * ipmi_lan_recvfrom for both.
       *
       * In event of future change, should use util functions
       * ipmi_is_ipmi_1_5_packet or ipmi_is_ipmi_2_0_packet
       * appropriately.
       */
      rv = ipmi_lan_recvfrom (fd,
                              buf,
                              IPMIPOWER_PACKET_BUFLEN,
                              0,
                              (struct sockaddr *)&from,
                              &fromlen);
    } while (rv < 0 && errno == EINTR);

  /* achu & hliebig:
   *
   * Premise from ipmitool (http://ipmitool.sourceforge.net/)
   *
   * On some OSes (it seems Unixes), the behavior is to not return
   * port denied errors up to the client for UDP responses (i.e. you
   * need to timeout).  But on some OSes (it seems Windows), the
   * behavior is to return port denied errors up to the user for UDP
   * responses via ECONNRESET or ECONNREFUSED.
   *
   * If this were just the case, we could return or handle errors
   * properly and move on.  However, it's not the case.
   *
   * According to Ipmitool, on some motherboards, both the OS and the
   * BMC are capable of responding to an IPMI request.  That means you
   * can get an ECONNRESET or ECONNREFUSED, then later on, get your
   * real IPMI response.
   *
   * Our solution is copied from Ipmitool, we'll ignore some specific
   * errors and try to read again.
   *
   * If the ECONNREFUSED or ECONNRESET is from the OS, but we will get
   * an IPMI response later, the recvfrom later on gets the packet we
   * want.
   *
   * If the ECONNREFUSED or ECONNRESET is from the OS but there is no
   * BMC (or IPMI disabled, etc.), just do the recvfrom again to
   * eventually get a timeout, which is the behavior we'd like.
   */
  if (rv < 0
      && (errno == ECONNRESET
          || errno == ECONNREFUSED))
    {
      IPMIPOWER_DEBUG (("ipmi_lan_recvfrom: connection refused: %s", strerror (errno)));
      return;
    }

  if (rv < 0)
    {
      IPMIPOWER_ERROR (("ipmi_lan_recvfrom: %s", strerror (errno)));
      exit (EXIT_FAILURE);
    }

  if (!rv)
    {
      IPMIPOWER_ERROR (("ipmi_lan_recvfrom: EOF"));
      exit (EXIT_FAILURE);
    }

  /* Don't store if this packet is strange for some reason */
  if (from.sin_family != AF_INET
      || from.sin_addr.s_addr != srcaddr->sin_addr.s_addr)
    return;

  /* cbuf should be empty, but if it isn't, empty it */
  if (!cbuf_is_empty (cbuf))
    {
      IPMIPOWER_DEBUG (("cbuf not empty, draining"));
      do
        {
          uint8_t tempbuf[IPMIPOWER_PACKET_BUFLEN];
          
          if (cbuf_read (cbuf, tempbuf, IPMIPOWER_PACKET_BUFLEN) < 0)
            {
              IPMIPOWER_ERROR (("cbuf_read: %s", strerror (errno)));
              exit (EXIT_FAILURE);
            }
        } while(!cbuf_is_empty (cbuf));
    }

  if ((n = cbuf_write (cbuf, buf, rv, &dropped)) < 0)
    {
      IPMIPOWER_ERROR (("cbuf_write: %s", strerror (errno)));
      exit (EXIT_FAILURE);
    }

  if (n != rv)
    {
      IPMIPOWER_ERROR (("cbuf_write: rv=%d n=%d", rv, n));
      exit (EXIT_FAILURE);
    }

  if (dropped)
    IPMIPOWER_DEBUG (("cbuf_write: read dropped %d bytes", dropped));
}
示例#6
0
文件: debug.c 项目: offchooffcho/lk
int platform_dgetc(char *c, bool wait)
{
	return cbuf_read(&debug_rx_buf, c, 1, wait);
}