12 #define BUFFERS_PRIVATE
32 #define check() STMT_BEGIN buf_assert_ok(buf); STMT_END
34 #define check() STMT_NIL
45 int *reached_eof,
int *error,
bool is_socket)
48 if (at_most > CHUNK_REMAINING_CAPACITY(chunk))
49 at_most = CHUNK_REMAINING_CAPACITY(chunk);
52 read_result = tor_socket_recv(fd, CHUNK_WRITE_PTR(chunk), at_most, 0);
54 read_result = read(fd, CHUNK_WRITE_PTR(chunk), at_most);
56 if (read_result < 0) {
57 int e = is_socket ? tor_socket_errno(fd) : errno;
59 if (!ERRNO_IS_EAGAIN(e)) {
62 log_warn(
LD_NET,
"%s() failed: WSAENOBUFS. Not enough ram?",
63 is_socket ?
"recv" :
"read");
70 }
else if (read_result == 0) {
71 log_debug(
LD_NET,
"Encountered eof on fd %d", (
int)fd);
75 buf->datalen += read_result;
76 chunk->datalen += read_result;
77 log_debug(
LD_NET,
"Read %ld bytes. %d on inbuf.", (
long)read_result,
80 return (
int)read_result;
100 size_t total_read = 0;
111 while (at_most > total_read) {
112 size_t readlen = at_most - total_read;
114 if (!buf->tail || CHUNK_REMAINING_CAPACITY(buf->tail) < MIN_READ_LEN) {
116 if (readlen > chunk->memlen)
117 readlen = chunk->memlen;
119 size_t cap = CHUNK_REMAINING_CAPACITY(buf->tail);
126 reached_eof, socket_error, is_socket);
132 if ((
size_t)r < readlen) {
136 return (
int)total_read;
147 ssize_t write_result;
149 if (sz > chunk->datalen)
153 write_result = tor_socket_send(fd, chunk->data, sz, 0);
155 write_result = write(fd, chunk->data, sz);
157 if (write_result < 0) {
158 int e = is_socket ? tor_socket_errno(fd) : errno;
160 if (!ERRNO_IS_EAGAIN(e)) {
163 log_warn(
LD_NET,
"write() failed: WSAENOBUFS. Not enough ram?");
167 log_debug(
LD_NET,
"write() would block, returning.");
172 return (
int)write_result;
191 if (BUG(sz > buf->datalen)) {
199 if (buf->head->datalen >= sz)
202 flushlen0 = buf->head->datalen;
204 r =
flush_chunk(fd, buf, buf->head, flushlen0, is_socket);
210 if (r == 0 || (
size_t)r < flushlen0)
264 return buf_read_from_fd(buf, fd, at_most, reached_eof, socket_error,
false);
chunk_t * buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped)
void buf_drain(buf_t *buf, size_t n)
Header file for buffers.c.
int buf_flush_to_socket(buf_t *buf, tor_socket_t s, size_t sz)
int buf_read_from_pipe(buf_t *buf, int fd, size_t at_most, int *reached_eof, int *socket_error)
static int read_to_chunk(buf_t *buf, chunk_t *chunk, tor_socket_t fd, size_t at_most, int *reached_eof, int *error, bool is_socket)
int buf_flush_to_pipe(buf_t *buf, int fd, size_t sz)
static int buf_flush_to_fd(buf_t *buf, int fd, size_t sz, bool is_socket)
static int flush_chunk(tor_socket_t fd, buf_t *buf, chunk_t *chunk, size_t sz, bool is_socket)
int buf_read_from_socket(buf_t *buf, tor_socket_t s, size_t at_most, int *reached_eof, int *socket_error)
static int buf_read_from_fd(buf_t *buf, int fd, size_t at_most, int *reached_eof, int *socket_error, bool is_socket)
Header file for buffers_net.c.
Declarations for types used throughout the Tor networking system.
Macros to manage assertions, fatal and non-fatal.