From d361d81c64ca4a99139ae1feada2fc55b2edbbb4 Mon Sep 17 00:00:00 2001 From: leitner Date: Thu, 18 May 2006 06:02:43 +0000 Subject: [PATCH] make socket_(tc|ud)p[46] actually return non-blocking sockets as documented (Richard Lyons) --- CHANGES | 2 ++ cdb.h | 5 +++-- cdb/cdb.c | 28 ++++++++++++++++++++++++++-- cdb/cdb_make.c | 9 ++++++++- cdb_make.h | 5 +++-- io/iob_prefetch.c | 2 +- mmap.h | 3 +++ mmap/mmap_private.c | 3 ++- mmap/mmap_read.c | 3 ++- mmap/mmap_shared.c | 3 ++- scan/scan_httpdate.c | 2 ++ socket/socket_tcp4.c | 8 +++++++- socket/socket_tcp6.c | 3 ++- socket/socket_udp4.c | 8 +++++++- socket/socket_udp6.c | 1 + test/client.c | 2 ++ test/dllink.c | 2 ++ test/httpd.c | 2 -- test/io5.c | 2 -- test/proxy.c | 2 -- test/server.c | 3 +++ test/vd.c | 1 + textcode.h | 18 ++++++++++++++++-- textcode/fmt_ldapescape.c | 23 +++++++++++++++++++++++ textcode/scan_ldapescape.c | 24 ++++++++++++++++++++++++ 25 files changed, 142 insertions(+), 22 deletions(-) create mode 100644 textcode/fmt_ldapescape.c create mode 100644 textcode/scan_ldapescape.c diff --git a/CHANGES b/CHANGES index a08bbbb..5f28a08 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,8 @@ add cdb add rangecheck.h add io_block + make socket_(tc|ud)p[46] actually return non-blocking sockets as + documented (Richard Lyons) 0.24: fix scan_to_sa (Tim Lorenz) diff --git a/cdb.h b/cdb.h index 67142d5..ba01ef8 100644 --- a/cdb.h +++ b/cdb.h @@ -2,6 +2,7 @@ #define CDB_H #include "uint32.h" +#include "uint64.h" #define CDB_HASHSTART 5381 extern uint32 cdb_hashadd(uint32 h,unsigned char c); @@ -9,7 +10,7 @@ extern uint32 cdb_hash(const unsigned char *buf,unsigned long int len); struct cdb { char *map; /* 0 if no map is available */ - int fd; + int64 fd; uint32 size; /* initialized if map is nonzero */ uint32 loop; /* number of hash slots searched under this key */ uint32 khash; /* initialized if loop is nonzero */ @@ -21,7 +22,7 @@ struct cdb { } ; extern void cdb_free(struct cdb *); -extern void cdb_init(struct cdb *,int fd); +extern void cdb_init(struct cdb *,int64 fd); extern int cdb_read(struct cdb *,unsigned char *,unsigned long int,uint32); diff --git a/cdb/cdb.c b/cdb/cdb.c index fb5740c..ec6b431 100644 --- a/cdb/cdb.c +++ b/cdb/cdb.c @@ -2,15 +2,23 @@ #include #include -#include #include #include #include "byte.h" #include "cdb.h" +#ifdef __MINGW32__ +#include "windows.h" +#else +#include +#endif void cdb_free(struct cdb *c) { if (c->map) { +#ifdef __MINGW32__ + UnmapViewOfFile(c->map); +#else munmap(c->map,c->size); +#endif c->map = 0; } } @@ -19,14 +27,25 @@ void cdb_findstart(struct cdb *c) { c->loop = 0; } -void cdb_init(struct cdb *c,int fd) { +void cdb_init(struct cdb *c,int64 fd) { +#ifndef __MINGW32__ struct stat st; char *x; +#endif cdb_free(c); cdb_findstart(c); c->fd = fd; +#ifdef __MINGW32__ + { + HANDLE m=CreateFileMapping((HANDLE)(uintptr_t)fd,0,PAGE_READONLY,0,0,NULL); + if (m) + if ((c->map=MapViewOfFile(m,FILE_MAP_READ,0,0,0))) + c->size=GetFileSize((HANDLE)(uintptr_t)fd,NULL); + CloseHandle(m); + } +#else if (fstat(fd,&st) == 0) if (st.st_size <= 0xffffffff) { x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0); @@ -35,6 +54,7 @@ void cdb_init(struct cdb *c,int fd) { c->map = x; } } +#endif } int cdb_read(struct cdb *c,unsigned char *buf,unsigned long len,uint32 pos) { @@ -58,7 +78,11 @@ int cdb_read(struct cdb *c,unsigned char *buf,unsigned long len,uint32 pos) { return 0; FORMAT: +#ifdef EPROTO errno = EPROTO; +#else + errno = EINVAL; +#endif return -1; } diff --git a/cdb/cdb_make.c b/cdb/cdb_make.c index fe94af1..c3c6937 100644 --- a/cdb/cdb_make.c +++ b/cdb/cdb_make.c @@ -5,8 +5,11 @@ #include #include "cdb.h" #include "cdb_make.h" +#ifdef __MINGW32__ +#include "windows.h" +#endif -int cdb_make_start(struct cdb_make *c,int fd) { +int cdb_make_start(struct cdb_make *c,int64 fd) { c->head = 0; c->split = 0; c->hash = 0; @@ -14,7 +17,11 @@ int cdb_make_start(struct cdb_make *c,int fd) { c->fd = fd; c->pos = sizeof c->final; buffer_init(&c->b,(void*)write,fd,c->bspace,sizeof c->bspace); +#ifdef __MINGW32__ + return SetFilePointer((HANDLE)(uintptr_t)fd,c->pos,0,FILE_BEGIN); +#else return lseek(fd,c->pos,SEEK_SET); +#endif } static int posplus(struct cdb_make *c,uint32 len) { diff --git a/cdb_make.h b/cdb_make.h index 4b9adfe..4919f92 100644 --- a/cdb_make.h +++ b/cdb_make.h @@ -2,6 +2,7 @@ #define CDB_MAKE_H #include "buffer.h" +#include "uint64.h" #include "uint32.h" #define CDB_HPLIST 1000 @@ -25,10 +26,10 @@ struct cdb_make { uint32 numentries; buffer b; uint32 pos; - int fd; + int64 fd; } ; -extern int cdb_make_start(struct cdb_make *,int); +extern int cdb_make_start(struct cdb_make *,int64); extern int cdb_make_addbegin(struct cdb_make *,unsigned long int,unsigned long int); extern int cdb_make_addend(struct cdb_make *,unsigned long int,unsigned long int,uint32); extern int cdb_make_add(struct cdb_make *,const unsigned char *,unsigned long int,const unsigned char *,unsigned long int); diff --git a/io/iob_prefetch.c b/io/iob_prefetch.c index 1dbf1d5..5a15f14 100644 --- a/io/iob_prefetch.c +++ b/io/iob_prefetch.c @@ -3,7 +3,7 @@ #ifdef __MINGW32__ /* not supported */ -void iob_internal(io_batch* b,uint64 bytes) { +void iob_prefetch(io_batch* b,uint64 bytes) { (void)b; (void)bytes; } diff --git a/mmap.h b/mmap.h index a31c18d..34cccc1 100644 --- a/mmap.h +++ b/mmap.h @@ -14,4 +14,7 @@ char* mmap_private(const char *filename,unsigned long* filesize); * length of map in filesize and return pointer to map. */ char* mmap_shared(const char *filename,unsigned long* filesize); +/* unmap a mapped region */ +int mmap_unmap(char* mapped,unsigned long maplen); + #endif diff --git a/mmap/mmap_private.c b/mmap/mmap_private.c index c6cf54b..09a8b2a 100644 --- a/mmap/mmap_private.c +++ b/mmap/mmap_private.c @@ -18,7 +18,8 @@ char* mmap_private(const char* filename,unsigned long* filesize) { m=CreateFileMapping(fd,0,PAGE_WRITECOPY,0,0,NULL); map=0; if (m) - map=MapViewOfFile(m,FILE_MAP_COPY,0,0,0); + if ((map=MapViewOfFile(m,FILE_MAP_COPY,0,0,0))) + *filesize=GetFileSize(fd,NULL); CloseHandle(m); CloseHandle(fd); return map; diff --git a/mmap/mmap_read.c b/mmap/mmap_read.c index 07bbcc4..3f9cd29 100644 --- a/mmap/mmap_read.c +++ b/mmap/mmap_read.c @@ -18,7 +18,8 @@ extern char* mmap_read(const char* filename,unsigned long* filesize) { m=CreateFileMapping(fd,0,PAGE_READONLY,0,0,NULL); map=0; if (m) - map=MapViewOfFile(m,FILE_MAP_READ,0,0,0); + if ((map=MapViewOfFile(m,FILE_MAP_READ,0,0,0))) + *filesize=GetFileSize(fd,NULL); CloseHandle(m); CloseHandle(fd); return map; diff --git a/mmap/mmap_shared.c b/mmap/mmap_shared.c index 7e9a9db..96ff0d7 100644 --- a/mmap/mmap_shared.c +++ b/mmap/mmap_shared.c @@ -18,7 +18,8 @@ extern char* mmap_shared(const char* filename,unsigned long* filesize) { m=CreateFileMapping(fd,0,PAGE_READWRITE,0,0,NULL); map=0; if (m) - map=MapViewOfFile(m,FILE_MAP_WRITE,0,0,0); + if ((map=MapViewOfFile(m,FILE_MAP_WRITE,0,0,0))) + *filesize=GetFileSize(fd,NULL); CloseHandle(m); CloseHandle(fd); return map; diff --git a/scan/scan_httpdate.c b/scan/scan_httpdate.c index d4e915c..2dd4d7c 100644 --- a/scan/scan_httpdate.c +++ b/scan/scan_httpdate.c @@ -63,6 +63,8 @@ done: x.tm_wday=x.tm_yday=x.tm_isdst=0; #if defined(__dietlibc__) || defined(__GLIBC__) *t=timegm(&x); +#elif defined(__MINGW32__) + *t=mktime(&x); #else { #ifdef sgi diff --git a/socket/socket_tcp4.c b/socket/socket_tcp4.c index d36e8a6..698ff96 100644 --- a/socket/socket_tcp4.c +++ b/socket/socket_tcp4.c @@ -1,12 +1,18 @@ #include #ifndef __MINGW32__ +#include #include #include #endif #include "windoze.h" #include "socket.h" +#include "ndelay.h" int socket_tcp4(void) { + int s; __winsock_init(); - return winsock2errno(socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)); + s = winsock2errno(socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)); + if (s == -1) return -1; + if (ndelay_on(s) == -1) { close(s); return -1; } + return s; } diff --git a/socket/socket_tcp6.c b/socket/socket_tcp6.c index 46a78df..ba13533 100644 --- a/socket/socket_tcp6.c +++ b/socket/socket_tcp6.c @@ -29,7 +29,7 @@ int socket_tcp6(void) if (s == -1) { if (errno == EINVAL || errno == EAFNOSUPPORT || errno == EPFNOSUPPORT || errno == EPROTONOSUPPORT) { compat: - s=socket(AF_INET,SOCK_STREAM,0); + s=winsock2errno(socket(AF_INET,SOCK_STREAM,0)); noipv6=1; if (s==-1) return -1; } else @@ -41,6 +41,7 @@ compat: winsock2errno(setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&zero,sizeof(zero))); } #endif + if (ndelay_on(s) == -1) { close(s); return -1; } return s; #else return socket_tcp4(); diff --git a/socket/socket_udp4.c b/socket/socket_udp4.c index c1f4104..e0a07d0 100644 --- a/socket/socket_udp4.c +++ b/socket/socket_udp4.c @@ -1,13 +1,19 @@ #include #ifndef __MINGW32__ +#include #include #include #endif #include "windoze.h" #include "socket.h" +#include "ndelay.h" int socket_udp4(void) { + int s; __winsock_init(); - return winsock2errno(socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)); + s = winsock2errno(socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)); + if (s == -1) return -1; + if (ndelay_on(s) == -1) { close(s); return -1; } + return s; } diff --git a/socket/socket_udp6.c b/socket/socket_udp6.c index fb70170..7259f33 100644 --- a/socket/socket_udp6.c +++ b/socket/socket_udp6.c @@ -41,6 +41,7 @@ compat: winsock2errno(setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&zero,sizeof(zero))); } #endif + if (ndelay_on(s) == -1) { close(s); return -1; } return s; #else return socket_udp(); diff --git a/test/client.c b/test/client.c index bda9289..c9cab92 100644 --- a/test/client.c +++ b/test/client.c @@ -7,6 +7,7 @@ #include #include "socket.h" #include +#include "ndelay.h" #ifdef __dietlibc__ #include #else @@ -73,6 +74,7 @@ usage: if (s==-1) panic("client: error: socket() failed"); if (socket_connect6(s,ip,port,scope_id)==-1) panic("client: error: connect() failed"); } + ndelay_off(s); p[0].fd=0; p[0].events=POLLIN; p[1].fd=s; p[1].events=POLLIN; while (poll(p,2,5000)) { diff --git a/test/dllink.c b/test/dllink.c index bf7fe88..191ed16 100644 --- a/test/dllink.c +++ b/test/dllink.c @@ -5,6 +5,7 @@ #include #include #include "case.h" +#include "ndelay.h" int main(int argc,char* argv[]) { int s=socket_tcp4(); @@ -14,6 +15,7 @@ int main(int argc,char* argv[]) { int header=1; buffer filein; + ndelay_off(s); if (argc<2 || strlen(argv[1])>900) { buffer_putsflush(buffer_2,"usage: dllink ed2k://|file|||a=n; s->b=x; s->connected=0; s->done=s->todo=0; s->dir=UNDECIDED; io_nonblock(x); - io_nonblock(n); socket_connect6(x,out.s,hisport,hisscope_id); if (!io_fd(x) || !io_fd(n)) { buffer_puts(buffer_2,"io_fd failed: "); diff --git a/test/server.c b/test/server.c index b3fb5cf..61425c7 100644 --- a/test/server.c +++ b/test/server.c @@ -6,6 +6,7 @@ #include #include #include "socket.h" +#include "ndelay.h" #include #ifdef __dietlibc__ #include @@ -72,12 +73,14 @@ usage: if (s==-1) panic("server: error: socket() failed"); if (socket_bind4_reuse(s,ip+12,port)==-1) panic("server: error: bind() failed"); if (socket_listen(s,1)==-1) panic("server: error: listen() failed"); + ndelay_off(s); if ((t=socket_accept4(s,0,0))==-1) panic("server: error: accept() failed"); } else { s=socket_tcp6(); if (s==-1) panic("server: error: socket() failed"); if (socket_bind6_reuse(s,ip,port,scope_id)==-1) panic("server: error: bind() failed"); if (socket_listen(s,1)==-1) panic("server: error: listen() failed"); + ndelay_off(s); if ((t=socket_accept6(s,0,0,0))==-1) panic("server: error: accept() failed"); } close(s); diff --git a/test/vd.c b/test/vd.c index a7ad9cb..7185973 100644 --- a/test/vd.c +++ b/test/vd.c @@ -3,6 +3,7 @@ #include #include #include +#include "ndelay.h" int main(int argc,char* argv[]) { int s=socket_tcp4(); diff --git a/textcode.h b/textcode.h index e38c806..a0735e6 100644 --- a/textcode.h +++ b/textcode.h @@ -3,22 +3,35 @@ /* These take len bytes from src and write them in encoded form to * dest (if dest != NULL), returning the number of bytes written. */ + +/* needs len/3*4 bytes */ unsigned long fmt_uuencoded(char* dest,const char* src,unsigned long len); +/* needs len/3*4 bytes */ unsigned long fmt_base64(char* dest,const char* src,unsigned long len); +/* worst case: len*3 */ unsigned long fmt_quotedprintable(char* dest,const char* src,unsigned long len); +/* worst case: len*3 */ unsigned long fmt_quotedprintable2(char* dest,const char* src,unsigned long len,const char* escapeme); +/* worst case: len*3 */ unsigned long fmt_urlencoded(char* dest,const char* src,unsigned long len); +/* worst case: len*3 */ unsigned long fmt_urlencoded2(char* dest,const char* src,unsigned long len,const char* escapeme); +/* worst case: len*2 */ unsigned long fmt_yenc(char* dest,const char* src,unsigned long len); +/* needs len*2 bytes */ unsigned long fmt_hexdump(char* dest,const char* src,unsigned long len); -/* this changes '<' to '<' and '&' to '&' */ +/* change '<' to '<' and '&' to '&'; worst case: len*5 */ unsigned long fmt_html(char* dest,const char* src,unsigned long len); -/* change '\' to "\\", '\n' to "\n", ^A to "\x01" etc */ +/* change '\' to "\\", '\n' to "\n", ^A to "\x01" etc; worst case: len*4 */ unsigned long fmt_cescape(char* dest,const char* src,unsigned long len); +/* worst case: len*4 */ unsigned long fmt_cescape2(char* dest,const char* src,unsigned long len,const char* escapeme); /* fold awk whitespace to '_'; this is great for writing fields with * white spaces to a log file and still allow awk to do log analysis */ +/* worst case: same size */ unsigned long fmt_foldwhitespace(char* dest,const char* src,unsigned long len); +/* worst case: len*3 */ +unsigned long fmt_ldapescape(char* dest,const char* src,unsigned long len); /* These read one line from src, decoded it, and write the result to * dest. The number of decoded bytes is written to destlen. dest @@ -32,6 +45,7 @@ unsigned long scan_yenc(const char *src,char *dest,unsigned long *destlen); unsigned long scan_hexdump(const char *src,char *dest,unsigned long *destlen); unsigned long scan_html(const char *src,char *dest,unsigned long *destlen); unsigned long scan_cescape(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_ldapescape(const char* src,char* dest,unsigned long *destlen); #ifdef STRALLOC_H /* WARNING: these functions _append_ to the stralloc, not overwrite! */ diff --git a/textcode/fmt_ldapescape.c b/textcode/fmt_ldapescape.c new file mode 100644 index 0000000..4542306 --- /dev/null +++ b/textcode/fmt_ldapescape.c @@ -0,0 +1,23 @@ +#include "fmt.h" +#include "textcode.h" +#include "haveinline.h" +#include "str.h" + +unsigned long fmt_ldapescape(char* dest,const char* src,unsigned long len) { + register const unsigned char* s=(const unsigned char*) src; + unsigned long written=0,i; + for (i=0; i>4); + dest[written+2]=fmt_tohex(s[i]&15); + } + written+=3; + } else { + if (dest) dest[written]=s[i]; ++written; + } + } + return written; +} + diff --git a/textcode/scan_ldapescape.c b/textcode/scan_ldapescape.c new file mode 100644 index 0000000..1606ef4 --- /dev/null +++ b/textcode/scan_ldapescape.c @@ -0,0 +1,24 @@ +#include "fmt.h" +#include "textcode.h" +#include "scan.h" + +unsigned long scan_ldapescape(const char *src,char *dest,unsigned long *destlen) { + register const unsigned char* s=(const unsigned char*) src; + unsigned long written=0,i; + for (i=0; s[i]; ++i) { + if (s[i]=='\\') { + int j=scan_fromhex(s[i+1]); + if (j<0) break; + dest[written]=j<<4; + j=scan_fromhex(s[i+2]); + if (j<0) break; + dest[written]|=j; + i+=2; + } else { + dest[written]=s[i]; + } + ++written; + } + *destlen=written; + return i; +}