14#include "compat/compat.h"
34#ifdef MAP_UNINITIALIZED
35#define MAPFLAGS (MAP_POPULATE | MAP_UNINITIALIZED)
37#define MAPFLAGS MAP_POPULATE
40#ifdef MAP_UNINITIALIZED
41#define MAPFLAGS MAP_UNINITIALIZED
52fbuf_grow(
fbuf* f,
size_t n){
55 size_t size = f->
size;
56 if(size - f->
used >=
n){
59 while(SIZE_MAX / 2 >= size){
61 if(size - f->
used <
n){
66 tmp = mremap(f->
buf, f->
size, size, MREMAP_MAYMOVE);
67 if(tmp == MAP_FAILED){
71 tmp = realloc(f->
buf, size);
87fbuf_initgrow(
fbuf* f,
unsigned small){
94 size_t size = small ? (4096 > BUFSIZ ? 4096 : BUFSIZ) : 0x200000lu;
108 f->
buf = (
char*)mmap(
NULL, size, PROT_READ | PROT_WRITE,
109 MAP_PRIVATE | MAP_ANONYMOUS |
MAPFLAGS , -1, 0);
111 if(f->
buf == MAP_FAILED){
116 f->
buf = (
char*)malloc(size);
128fbuf_init_small(
fbuf* f){
132 return fbuf_initgrow(f, 1);
141 return fbuf_initgrow(f, 0);
151fbuf_reserve(
fbuf* f,
size_t len){
152 if(fbuf_grow(f,
len)){
165fbuf_putc(
fbuf* f,
char c){
174fbuf_putn(
fbuf* f,
const char* s,
size_t len){
175 if(fbuf_grow(f,
len)){
184fbuf_puts(
fbuf* f,
const char* s){
185 size_t slen = strlen(s);
186 return fbuf_putn(f, s, slen);
190fbuf_putint(
fbuf* f,
int n){
191 if(fbuf_grow(f, 20)){
204fbuf_putuint(
fbuf* f,
int n){
205 if(fbuf_grow(f, 20)){
221 if(fbuf_grow(f, BUFSIZ) < 0){
226 int r = vsnprintf(f->buf + f->used, f->size - f->used,
fmt, va);
228 if((
size_t)
r >= f->size - f->used){
238fbuf_emit(
fbuf* f,
const char* esc){
242 if(fbuf_puts(f, esc) < 0){
271blocking_write(
int fd,
const char* buf,
size_t buflen){
274 while(written < buflen){
275 ssize_t w = write(fd, buf + written, buflen - written);
277 if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR && errno != EBUSY){
278 logerror(
"Error writing out data on %d (%s)", fd, strerror(errno));
286 if(written < buflen){
287 struct pollfd pfd = {
302fbuf_flush(
fbuf* f, FILE* fp){
305 if(fflush(fp) == EOF){
307 }
else if(blocking_write(fileno(fp), f->
buf, f->
used)){
318fbuf_finalize(
fbuf* f, FILE* fp){
321 if(fflush(fp) == EOF){
323 }
else if(blocking_write(fileno(fp), f->
buf, f->
used)){
__attribute__((format(printf, 2, 3))) static inline int fbuf_printf(fbuf *f
const char va_start(va, fmt)
#define logerror(fmt,...)
API int API int const nccell unsigned len