Пример #1
0
/* Fill buffers from socket based on poll results. */
int
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
{
	ssize_t	n;

	if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
		return (-1);
	if (pfd->revents & POLLIN) {
		buffer_ensure(in, BUFSIZ);
		n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
		if (n == 0)
			return (-1);
		if (n == -1) {
			if (errno != EINTR && errno != EAGAIN)
				return (-1);
		} else
			buffer_add(in, n);
	}
	if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
		n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
		if (n == -1) {
			if (errno != EINTR && errno != EAGAIN)
				return (-1);
		} else
			buffer_remove(out, n);
	}
	return (0);
}
Пример #2
0
Файл: io.c Проект: mbeck-/fdm
/* Write a line to the io write buffer from a va_list. */
void
io_vwriteline(struct io *io, const char *fmt, va_list ap)
{
    int	 n;
    va_list	 aq;

    if (io->error != NULL)
        return;

    IO_DEBUG(io, "in: wr: used=%zu, free=%zu",
             BUFFER_USED(io->wr), BUFFER_FREE(io->wr));

    if (fmt != NULL) {
        va_copy(aq, ap);
        n = xvsnprintf(NULL, 0, fmt, aq);
        va_end(aq);

        buffer_ensure(io->wr, n + 1);
        xvsnprintf(BUFFER_IN(io->wr), n + 1, fmt, ap);
        buffer_add(io->wr, n);
    } else
        n = 0;
    io_write(io, io->eol, strlen(io->eol));

    IO_DEBUG(io, "out: %zu bytes, wr: used=%zu, free=%zu",
             n + strlen(io->eol), BUFFER_USED(io->wr), BUFFER_FREE(io->wr));
}
Пример #3
0
static char *get_line(void)
{
   if (feof(g_file))
      return NULL;

   g_line.size = 0;
   
   int c;
   while ((c = fgetc(g_file)) != EOF && c != '\n') {
      if (g_line.size == g_line.alloc)
         buffer_ensure(&g_line, g_line.size + 1024);
      g_line.data[g_line.size++] = c;
   }
   if (g_line.alloc)
      g_line.data[g_line.size] = '\0';
   
   if (ferror(g_file))
      die("IO error while reading %s: %s", g_config.dataset_path, strerror(errno));
   
   // Skip the last line if empty.
   if (!g_line.size) {
      c = fgetc(g_file);
      if (c == EOF)
         return NULL;
      ungetc(c, g_file);
   }

   g_line_no++;
   return g_line.data;
}
Пример #4
0
/* Store an 8-bit value. */
void
buffer_write8(struct buffer *b, uint8_t n)
{
	buffer_ensure(b, 1);
	BUFFER_IN(b)[0] = n;
	buffer_add(b, 1);
}
Пример #5
0
/* Store a 16-bit value. */
void
buffer_write16(struct buffer *b, uint16_t n)
{
	buffer_ensure(b, 2);
	BUFFER_IN(b)[0] = n & 0xff;
	BUFFER_IN(b)[1] = n >> 8;
	buffer_add(b, 2);
}
Пример #6
0
/* Copy data into a buffer. */
void
buffer_write(struct buffer *b, const void *data, size_t size)
{
	if (size == 0)
		fatalx("zero size");

	buffer_ensure(b, size);
	memcpy(BUFFER_IN(b), data, size);
	buffer_add(b, size);
}
Пример #7
0
/* Insert a section into the buffer. */
void
buffer_insert_range(struct buffer *b, size_t base, size_t size)
{
	if (size == 0)
		fatalx("zero size");
	if (base > b->size)
		fatalx("range outside buffer");

	buffer_ensure(b, size);
	memmove(b->base + b->off + base + size,
	    b->base + b->off + base, b->size - base);
	b->size += size;
}
Пример #8
0
static const where *
get_where( int line, const char *file ) {
  static int init_done = 0;
  static hash *cache = NULL;
  static buffer work;
  where *w;
  int err;
  size_t sz;

  if ( !file ) {
    return NULL;
  }

  if ( !init_done ) {
    if ( err = buffer_init( &work, 256, 64 ), ERR_None != err ) {
      nomem(  );
    }
    if ( err = hash_new( 1000, &cache ), ERR_None != err ) {
      nomem(  );
    }
    init_done = 1;
  }

  sz = sizeof( where ) + strlen( file ) + 1;
  if ( err = buffer_ensure( &work, sz ), ERR_None != err ) {
    nomem(  );
  }

  w = ( where * ) work.buf;
  w->line = line;
  strcpy( ( char * ) ( w + 1 ), file );

  /* Already got it? */
  if ( w = ( where * ) hash_get( cache, w, sz ), NULL != w ) {
    return w;
  }

  if ( w = malloc( sz ), !w ) {
    nomem(  );
  }

  memcpy( w, work.buf, sz );

  /* Add it to cache */
  if ( err = hash_put( cache, w, sz, w ), ERR_None != err ) {
    nomem(  );
  }

  return w;
}
Пример #9
0
static void 
build_location(const char* dir_start, size_t dir_len, const char* name, struct buffer *buf)
{
	size_t name_len, file_len;
	
	if (name != NULL) {
		name_len = strlen(name);
		file_len = dir_len + 1 + name_len;
	} else {
		name_len = 0; /* or GCC complains */
		file_len = dir_len;
	}
	buffer_ensure(buf, file_len + 1);	

	memcpy(buf->ptr, dir_start, dir_len);
	if (name != NULL) {
		buf->ptr[dir_len] = '/';
		memcpy(buf->ptr + dir_len + 1, name, name_len);
	}
	buf->ptr[file_len] = '\0';
}
Пример #10
0
int buffer_ensure_free(buffer *b, size_t minfree) {
    return buffer_ensure(b, b->used + minfree);
}
Пример #11
0
Файл: io.c Проект: mbeck-/fdm
/*
 * Fill read buffer. Returns 0 for closed, -1 for error, 1 for success,
 * a la read(2).
 */
int
io_fill(struct io *io)
{
    ssize_t	n;
    int	error;

again:
    /* Ensure there is at least some minimum space in the buffer. */
    buffer_ensure(io->rd, IO_WATERMARK);

    /* Attempt to read as much as the buffer has available. */
    if (io->ssl == NULL) {
        n = read(io->fd, BUFFER_IN(io->rd), BUFFER_FREE(io->rd));
        IO_DEBUG(io, "read returned %zd (errno=%d)", n, errno);
        if (n == 0 || (n == -1 && errno == EPIPE))
            return (0);
        if (n == -1 && errno != EINTR && errno != EAGAIN) {
            if (io->error != NULL)
                xfree(io->error);
            xasprintf(&io->error, "io: read: %s", strerror(errno));
            return (-1);
        }
    } else {
        n = SSL_read(io->ssl, BUFFER_IN(io->rd), BUFFER_FREE(io->rd));
        IO_DEBUG(io, "SSL_read returned %zd", n);
        if (n == 0)
            return (0);
        if (n < 0) {
            switch (error = SSL_get_error(io->ssl, n)) {
            case SSL_ERROR_WANT_READ:
                /*
                 * A repeat is certain (poll on the socket will
                 * still return data ready) so this can be
                 * ignored.
                 */
                break;
            case SSL_ERROR_WANT_WRITE:
                io->flags |= IOF_NEEDFILL;
                break;
            case SSL_ERROR_SYSCALL:
                if (errno == EAGAIN || errno == EINTR)
                    break;
            /* FALLTHROUGH */
            default:
                if (io->error != NULL)
                    xfree(io->error);
                io->error = sslerror2(error, "SSL_read");
                return (-1);
            }
        }
    }

    /* Test for > 0 since SSL_read can return any -ve on error. */
    if (n > 0) {
        IO_DEBUG(io, "read %zd bytes", n);

        /* Copy out the duplicate fd. Errors are just ignored. */
        if (io->dup_fd != -1) {
            write(io->dup_fd, "< ", 2);
            write(io->dup_fd, BUFFER_IN(io->rd), n);
        }

        /* Adjust the buffer size. */
        buffer_add(io->rd, n);

        /* Reset the need flags. */
        io->flags &= ~IOF_NEEDFILL;

        goto again;
    }

    return (1);
}