diff --git a/CHANGES b/CHANGES index 94766a5..89fd9fc 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ ' '; needed for web servers, so they can serve libstdc++.tar.gz) fix iob_write to handle failure properly document that the iob_write callback should limit itself + add iob_free, add man pages for iob_free and iob_reset 0.21: errno cleanup and man page updates (Rolf Eike Beer) diff --git a/buffer/buffer_close.c b/buffer/buffer_close.c index 6d8127a..41d57d9 100644 --- a/buffer/buffer_close.c +++ b/buffer/buffer_close.c @@ -1,13 +1,22 @@ #include #include #include +#ifdef __MINGW32__ +#include +#else #include +#endif void buffer_close(buffer* b) { if (b->fd != -1) close(b->fd); switch (b->todo) { case FREE: free(b->x); break; - case MUNMAP: munmap(b->x,b->a); break; + case MUNMAP: +#ifdef __MINGW32__ + UnmapViewOfFile(b->x); +#else + munmap(b->x,b->a); break; +#endif default: ; } } diff --git a/buffer/errmsg_cvt.c b/buffer/errmsg_cvt.c index e80ce1e..be350cf 100644 --- a/buffer/errmsg_cvt.c +++ b/buffer/errmsg_cvt.c @@ -1,6 +1,15 @@ #include #include +#ifdef __MINGW32__ +#include "windows.h" + +struct iovec { + LPCVOID iov_base; + DWORD iov_len; +}; +#else #include +#endif #include "errmsg.h" #include "str.h" diff --git a/buffer/errmsg_info.c b/buffer/errmsg_info.c index fd39da7..b2a4c8e 100644 --- a/buffer/errmsg_info.c +++ b/buffer/errmsg_info.c @@ -1,6 +1,16 @@ #include #include +#ifdef __MINGW32__ +#include "windows.h" +#include + +struct iovec { + LPCVOID iov_base; + DWORD iov_len; +}; +#else #include +#endif #include "errmsg.h" #include "str.h" @@ -10,6 +20,15 @@ void errmsg_info(const char* message, ...) { struct iovec x[23]; va_list a; va_start(a,message); +#ifdef __MINGW32__ + { + int i,j; + j=errmsg_cvt(x,message,a); + for (i=0; i #include -#include #include "errmsg.h" #include "str.h" #include #include -extern int errmsg_cvt(struct iovec* x,const char* message, va_list a); extern void errmsg_writesys(int fd,const char* message,va_list list); void errmsg_infosys(const char* message, ...) { diff --git a/buffer/errmsg_warn.c b/buffer/errmsg_warn.c index 013c531..5fc7ce5 100644 --- a/buffer/errmsg_warn.c +++ b/buffer/errmsg_warn.c @@ -1,6 +1,16 @@ #include #include +#ifdef __MINGW32__ +#include "windows.h" +#include + +struct iovec { + LPCVOID iov_base; + DWORD iov_len; +}; +#else #include +#endif #include "errmsg.h" #include "str.h" @@ -10,6 +20,15 @@ void errmsg_warn(const char* message, ...) { struct iovec x[23]; va_list a; va_start(a,message); +#ifdef __MINGW32__ + { + int i,j; + j=errmsg_cvt(x,message,a); + for (i=0; i #include -#include #include "errmsg.h" #include "str.h" #include #include -extern int errmsg_cvt(struct iovec* x,const char* message, va_list a); extern void errmsg_writesys(int fd,const char* message,va_list list); void errmsg_warnsys(const char* message, ...) { diff --git a/buffer/errmsg_writesys.c b/buffer/errmsg_writesys.c index 1fb93e4..82f8713 100644 --- a/buffer/errmsg_writesys.c +++ b/buffer/errmsg_writesys.c @@ -1,6 +1,16 @@ #include #include +#ifdef __MINGW32__ +#include "windows.h" +#include + +struct iovec { + LPCVOID iov_base; + DWORD iov_len; +}; +#else #include +#endif #include "errmsg.h" #include "str.h" #include @@ -22,5 +32,13 @@ void errmsg_writesys(int fd,const char* message,va_list list) { x[i+1].iov_base="\n"; x[i+1].iov_len=1; +#ifdef __MINGW32__ + { + int j; + for (j=0; j #include +#ifdef __MINGW32__ +#include +#else #include +#endif #include "io_internal.h" void io_close(int64 d) { @@ -10,7 +14,12 @@ void io_close(int64 d) { io_dontwantread(d); io_dontwantwrite(d); if (e->mmapped) { +#ifdef __MINGW32__ + UnmapViewOfFile(e->mmapped); + CloseHandle(e->mh); +#else munmap(e->mmapped,e->maplen); +#endif e->mmapped=0; } } diff --git a/io/io_fd.c b/io/io_fd.c index 410002b..b707c40 100644 --- a/io/io_fd.c +++ b/io/io_fd.c @@ -54,7 +54,9 @@ int io_fd(int64 d) { if (!(e=array_allocate(&io_fds,sizeof(io_entry),d))) return 0; byte_zero(e,sizeof(io_entry)); e->inuse=1; -#ifndef __MINGW32__ +#ifdef __MINGW32__ + e->mh=0; +#else if (r&O_NDELAY) e->nonblock=1; #endif e->next_read=e->next_write=-1; diff --git a/io/io_mmapwritefile.c b/io/io_mmapwritefile.c index 9b0d62a..8866fc4 100644 --- a/io/io_mmapwritefile.c +++ b/io/io_mmapwritefile.c @@ -2,7 +2,11 @@ #include #include #include +#ifdef __MINGW32__ +#include +#else #include +#endif #define BUFSIZE 16384 @@ -14,19 +18,33 @@ int64 io_mmapwritefile(int64 out,int64 in,uint64 off,uint64 bytes,io_write_callb if (e) { const char* c; long left; +#ifdef __MINGW32__ + if (!e->mh) e->mh=CreateFileMapping(out,0,PAGE_READONLY,0,0,NULL); + if (!e->mh) goto readwrite; +#endif 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*/ +#ifdef __MINGW32__ + UnmapViewOfFile(e->mmapped); +#else munmap(e->mmapped,e->maplen); +#endif } 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) { +#ifdef __MINGW32__ + if ((e->mmapped=MapViewOfFile(e->mh,FILE_MAP_READ,(DWORD)(e->mapofs>>32), + (DWORD)e->mapofs,e->maplen))==0) +#else + if ((e->mmapped=mmap(0,e->maplen,PROT_READ,MAP_SHARED,in,e->mapofs))==MAP_FAILED) +#endif + { e->mmapped=0; goto readwrite; } @@ -40,7 +58,11 @@ int64 io_mmapwritefile(int64 out,int64 in,uint64 off,uint64 bytes,io_write_callb e->canwrite=0; e->next_write=-1; if (errno!=EAGAIN) { +#ifdef __MINGW32__ + UnmapViewOfFile(e->mmapped); +#else munmap(e->mmapped,e->maplen); +#endif e->mmapped=0; return -3; } @@ -55,7 +77,11 @@ int64 io_mmapwritefile(int64 out,int64 in,uint64 off,uint64 bytes,io_write_callb } } while (bytes); if (e->mmapped) { +#ifdef __MINGW32__ + UnmapViewOfFile(e->mmapped); +#else munmap(e->mmapped,e->maplen); +#endif e->mmapped=0; } return sent; diff --git a/io/io_passfd.c b/io/io_passfd.c index f6b371a..8d66081 100644 --- a/io/io_passfd.c +++ b/io/io_passfd.c @@ -1,3 +1,12 @@ +#ifdef __MINGW32__ +#include "io_internal.h" +#include +int io_passfd(int64 sock,int64 fd) { + errno=EINVAL; + return -1; +} +#else + #include #include #include @@ -40,3 +49,4 @@ int io_passfd(int64 sock,int64 fd) { #endif return sendmsg(sock,&msg,0)>=0?0:-1; } +#endif diff --git a/io/io_receivefd.c b/io/io_receivefd.c index 9e8d8a6..dcc1605 100644 --- a/io/io_receivefd.c +++ b/io/io_receivefd.c @@ -1,3 +1,12 @@ +#ifdef __MINGW32__ +#include +#include "io_internal.h" +int64 io_receivefd(int64 sock) { + errno=EINVAL; + return -1; +} +#else + #include #include #include @@ -60,3 +69,4 @@ int64 io_receivefd(int64 sock) { return fd; #endif } +#endif diff --git a/io/io_sigpipe.c b/io/io_sigpipe.c index e92c876..bb800dc 100644 --- a/io/io_sigpipe.c +++ b/io/io_sigpipe.c @@ -5,9 +5,11 @@ /* this is an internal function, called by io_trywrite and io_waitwrite */ void io_sigpipe(void) { +#ifndef __MINGW32__ static int isitdone; if (!isitdone) { signal(SIGPIPE,SIG_IGN); isitdone=1; } +#endif } diff --git a/io/io_socketpair.c b/io/io_socketpair.c index 561213d..b10f435 100644 --- a/io/io_socketpair.c +++ b/io/io_socketpair.c @@ -1,12 +1,16 @@ #include #include +#ifndef __MINGW32__ #include #include +#endif +#include "windoze.h" #include #include "io_internal.h" int io_socketpair(int64* d) { int fds[2]; + __winsock_init(); if (socketpair(AF_UNIX,SOCK_STREAM,0,fds)==-1) if (socketpair(AF_INET6,SOCK_STREAM,IPPROTO_TCP,fds)==-1) if (socketpair(AF_INET,SOCK_STREAM,IPPROTO_TCP,fds)==-1) diff --git a/io/iob_free.3 b/io/iob_free.3 new file mode 100644 index 0000000..381be95 --- /dev/null +++ b/io/iob_free.3 @@ -0,0 +1,13 @@ +.TH iob_free 3 +.SH NAME +iob_free \- free an I/O batch +.SH SYNTAX +.B #include + +void \fBiob_free\fP(io_batch* b); +.SH DESCRIPTION +iob_free frees all resources associated with \fIb\fR. Calling iob_free +is equivalent to calling iob_reset and free. +avoiding unnecessary copying (using writev). +.SH "SEE ALSO" +iob_new(3), iob_reset(3) diff --git a/io/iob_free.c b/io/iob_free.c new file mode 100644 index 0000000..39bcfa0 --- /dev/null +++ b/io/iob_free.c @@ -0,0 +1,7 @@ +#include +#include "iob_internal.h" + +void iob_free(io_batch* b) { + iob_reset(b); + free(b); +} diff --git a/io/iob_reset.3 b/io/iob_reset.3 new file mode 100644 index 0000000..81d6658 --- /dev/null +++ b/io/iob_reset.3 @@ -0,0 +1,16 @@ +.TH iob_reset 3 +.SH NAME +iob_reset \- reset an I/O batch +.SH SYNTAX +.B #include + +void \fBiob_reset\fP(io_batch* b); +.SH DESCRIPTION +iob_free empties the list of transactions in an I/O batch. Files added +with iob_addfile_close are closed, and buffer added with iob_addbuf_free +of iob_adds_free are freed. + +The I/O batch itself is not freed. You can start adding transactions to +it again. +.SH "SEE ALSO" +iob_new(3), iob_reset(3) diff --git a/io_internal.h b/io_internal.h index abf607f..8b67dd7 100644 --- a/io_internal.h +++ b/io_internal.h @@ -30,7 +30,7 @@ typedef struct { uint64 mapofs; #ifdef __MINGW32__ OVERLAPPED o; - HANDLE fd; + HANDLE /* fd, */ mh; #endif } io_entry; diff --git a/iob.h b/iob.h index 9d9565c..c791ca4 100644 --- a/iob.h +++ b/iob.h @@ -31,6 +31,7 @@ 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_free(io_batch* b); void iob_prefetch(io_batch* b,uint64 bytes); #endif diff --git a/test/b64encode.c b/test/b64encode.c index b1c1a15..95e9ed3 100644 --- a/test/b64encode.c +++ b/test/b64encode.c @@ -4,9 +4,9 @@ #include "textcode.h" #include "havealloca.h" -void b64encode(const char* c) { - char* buf=alloca(strlen(c)*2+4); - buffer_put(buffer_1,buf,fmt_base64(buf,c,strlen(c))); +void b64encode(const char* c,long len) { + char* buf=alloca(len*2+4); + buffer_put(buffer_1,buf,fmt_base64(buf,c,len)); if (isatty(1)) buffer_putnlflush(buffer_1); else @@ -16,15 +16,14 @@ void b64encode(const char* c) { int main(int argc,char* argv[]) { int i; for (i=1; i0) { if (len==-1) return(1); - src[len]=0; - b64encode(src); + b64encode(src,len); } } return 0;