diff --git a/CHANGES b/CHANGES index 672e2c8..79f047f 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ cleanups in stralloc and buffer: int -> long for sizes char -> unsigned char for strings + buffer_getline is now a function, not a macro 0.20: add errmsg API diff --git a/buffer/buffer_getline.c b/buffer/buffer_getline.c new file mode 100644 index 0000000..675c184 --- /dev/null +++ b/buffer/buffer_getline.c @@ -0,0 +1,5 @@ +#include + +int buffer_getline(buffer* b,unsigned char* x,unsigned long int len) { + return buffer_get_token(b,x,len,"\n",1); +} diff --git a/io.h b/io.h index 5f3f052..505e2d8 100644 --- a/io.h +++ b/io.h @@ -100,6 +100,11 @@ int io_passfd(int64 sock,int64 fd); * process. Return sock if ok, -1 on error, setting errno. */ int64 io_receivefd(int64 sock); +typedef int64 (*io_write_callback)(int64 s,const void* buf,uint64 n); + +/* used internally, but hey, who knows */ +int64 io_mmapwritefile(int64 out,int64 in,uint64 off,uint64 bytes,io_write_callback writecb); + #ifdef __MINGW32__ #include_next #endif diff --git a/io/io_sendfile.c b/io/io_sendfile.c index 893be76..d828b9e 100644 --- a/io/io_sendfile.c +++ b/io/io_sendfile.c @@ -113,91 +113,14 @@ int64 io_sendfile(int64 s,int64 fd,uint64 off,uint64 n) { #else -#include -#include -#include +#include -#define BUFSIZE 16384 +static int64 writecb(int64 s,const void* buf,uint64 n) { + return write(s,buf,n); +} int64 io_sendfile(int64 out,int64 in,uint64 off,uint64 bytes) { - char buf[BUFSIZE]; - int n,m; - uint64 sent=0; - io_entry* e=array_get(&io_fds,sizeof(io_entry),out); - if (e) { - const char* c; - long left; - do { - if (e->mmapped) { - /* did we already map the right chunk? */ - if (off>=e->mapofs && offmapofs+e->maplen) - goto mapok; /* ok; mmapped the right chunk*/ - munmap(e->mmapped,e->maplen); - } - e->mapofs=off&0xffffffffffff0000ull; - if (e->mapofs+0x10000>off+bytes) - e->maplen=off+bytes-e->mapofs; - else - e->maplen=0x10000; - if ((e->mmapped=mmap(0,e->maplen,PROT_READ,MAP_SHARED,in,e->mapofs))==MAP_FAILED) { - e->mmapped=0; - goto readwrite; - } - mapok: - c=(const char*)(e->mmapped)+(off&0xffff); - left=e->maplen-(off&0xffff); - if (left>bytes) left=bytes; - while (left>0) { - m=write(out,c,left); - if (m==-1) { - e->canwrite=0; - e->next_write=-1; - if (errno!=EAGAIN) { - munmap(e->mmapped,e->maplen); - e->mmapped=0; - return -3; - } - return sent?sent:-1; - } - if (m==0) return sent; - sent+=m; - left-=m; - bytes-=m; - off+=m; - c+=m; - } - } while (bytes); - if (e->mmapped) { - munmap(e->mmapped,e->maplen); - e->mmapped=0; - } - return sent; - } -readwrite: - if (lseek(in,off,SEEK_SET) != off) - return -1; - while (bytes>0) { - char* tmp=buf; - if ((n=read(in,tmp,(bytes0) { - if ((m=write(out,tmp,n))<0) { - if (m==-1) { - if (e) { - e->canwrite=0; - e->next_write=-1; - } - return errno==EAGAIN?(sent?sent:-1):-3; - } - goto abort; - } - sent+=m; - n-=m; - tmp+=m; - } - } -abort: - return sent; + return io_mmapwritefile(out,in,off,bytes,writecb); } #endif diff --git a/io/iob_addfile.c b/io/iob_addfile.c index d57784a..dead5a2 100644 --- a/io/iob_addfile.c +++ b/io/iob_addfile.c @@ -3,6 +3,7 @@ int iob_addfile(io_batch* b,int64 fd,uint64 off,uint64 n) { iob_entry* e; if (n==0) return 1; + io_fd(fd); e=array_allocate(&b->b,sizeof(iob_entry), array_length(&b->b,sizeof(iob_entry))); if (!e) return 0; diff --git a/io/iob_addfile_close.c b/io/iob_addfile_close.c index d8ae66a..3aa65d9 100644 --- a/io/iob_addfile_close.c +++ b/io/iob_addfile_close.c @@ -3,6 +3,7 @@ int iob_addfile_close(io_batch* b,int64 fd,uint64 off,uint64 n) { iob_entry* e; if (n==0) return 1; + io_fd(fd); e=array_allocate(&b->b,sizeof(iob_entry), array_length(&b->b,sizeof(iob_entry))); if (!e) return 0; diff --git a/io/iob_send.c b/io/iob_send.c index d796f95..94faca0 100644 --- a/io/iob_send.c +++ b/io/iob_send.c @@ -1,8 +1,4 @@ #include "havebsdsf.h" -#ifdef HAVE_BSDSENDFILE -/* for MacOS X. Yep, they blew it again. */ -#define SENDFILE 1 -#endif #include #include #include diff --git a/iob.h b/iob.h index 61e284e..9d9565c 100644 --- a/iob.h +++ b/iob.h @@ -29,6 +29,7 @@ int iob_adds_free(io_batch* b,const char* s); int iob_addfile(io_batch* b,int64 fd,uint64 off,uint64 n); int iob_addfile_close(io_batch* b,int64 fd,uint64 off,uint64 n); int64 iob_send(int64 s,io_batch* b); +int64 iob_write(int64 s,io_batch* b,io_write_callback cb); void iob_reset(io_batch* b); void iob_prefetch(io_batch* b,uint64 bytes); diff --git a/test/iob.c b/test/iob.c index c2dc9ac..58b603c 100644 --- a/test/iob.c +++ b/test/iob.c @@ -1,17 +1,24 @@ #include #include "iob.h" #include "buffer.h" +#include + +static int64 write_cb(int64 fd,const void* buf,uint64 len) { + if (len>2) len=2; + return write(fd,buf,len); +} int main() { int64 fd; io_batch* b; + int64 r; assert(io_readfile(&fd,"GNUmakefile")); assert(b=iob_new(10)); assert(iob_addbuf(b,"Huhu",4)); assert(iob_addbuf(b," fnord\n",7)); assert(iob_addfile(b,fd,10,10)); - buffer_puts(buffer_2,"iob_send returned "); - buffer_putlong(buffer_2,iob_send(1,b)); - buffer_putsflush(buffer_2,".\n"); + do { + r=iob_write(1,b,write_cb); + } while (r>0); return 0; }