X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=cprogs%2Frwbuffer.c;h=10b86ca0d1ec8e2d268ab9fe68aef1e2465cef54;hp=d91a96eb639fc42dc8fdb3833456bf8fc164f647;hb=812c3e1f13c35ab65d0eb4aafbaab0ac5d4ea8b8;hpb=737b84851cd8b3dd1d9f1920201127eac693dffb diff --git a/cprogs/rwbuffer.c b/cprogs/rwbuffer.c index d91a96e..10b86ca 100644 --- a/cprogs/rwbuffer.c +++ b/cprogs/rwbuffer.c @@ -27,17 +27,6 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "rwbuffer.h" #ifndef RWBUFFER_SIZE_MB_DEF @@ -49,11 +38,13 @@ #endif unsigned char *buf, *wp, *rp; -int used, seeneof; -size_t buffersize; +int used, seeneof, maxselfd; +size_t buffersize= RWBUFFER_SIZE_MB_DEF*1024*1024; fd_set readfds; fd_set writefds; +static int opt_mlock=0; + int min(int a, int b) { return a<=b ? a : b; } static void usage(FILE *f) { @@ -67,7 +58,7 @@ static void usageerr(const char *what) { exit(12); } -static void nonblock(int fd, int yesno) { +void nonblock(int fd, int yesno) { int r; r= fcntl(fd,F_GETFL,0); if (r == -1) { perror("fcntl getfl"); exit(8); } if (yesno) r |= O_NDELAY; @@ -79,11 +70,21 @@ static void unnonblock(void) { nonblock(0,0); nonblock(1,0); } +void startupcore(void) { + buf= xmalloc(buffersize); + + if (opt_mlock) { + if (mlock(buf,buffersize)) { perror("mlock"); exit(2); } + } + + used=0; wp=rp=buf; seeneof=0; + if (atexit(unnonblock)) { perror("atexit"); exit(16); } +} + void startup(const char *const *argv) { const char *arg; char *ep; - unsigned long opt_buffersize=RWBUFFER_SIZE_MB_DEF; - int opt_mlock=0; + int shift=-1; assert(argv[0]); @@ -91,23 +92,23 @@ void startup(const char *const *argv) { if (!strcmp(arg,"--mlock")) { opt_mlock= 1; } else if (isdigit((unsigned char)arg[0])) { - opt_buffersize= strtoul(arg,&ep,0); - if (opt_buffersize > RWBUFFER_SIZE_MB_MAX) + buffersize= strtoul(arg,&ep,0); + if (ep[0] && ep[1]) usageerr("buffer size spec. invalid"); + switch (ep[0]) { + case 0: case 'm': shift= 20; break; + case 'k': shift= 10; break; + case 'b': shift= 0; break; + default: usageerr("buffer size unit unknown"); + } + if (buffersize > ((RWBUFFER_SIZE_MB_MAX << 20) >> shift)) usageerr("buffer size too big"); + buffersize <<= shift; } else { usageerr("invalid option"); } } - buffersize= opt_buffersize*1024*1024; - buf= xmalloc(buffersize); - - if (opt_mlock) { - if (mlock(buf,buffersize)) { perror("mlock"); exit(2); } - } - - used=0; wp=rp=buf; seeneof=0; - if (atexit(unnonblock)) { perror("atexit"); exit(16); } + startupcore(); nonblock(0,1); nonblock(1,1); } @@ -119,7 +120,7 @@ void callselect(void) { int r; for (;;) { - r= select(2,&readfds,&writefds,0,0); + r= select(maxselfd,&readfds,&writefds,0,0); if (r != -1) return; if (errno != EINTR) { perror("select"); exit(4);