X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=cprogs%2Frwbuffer.c;h=4d8503cfa9ff24b04e68944ff7e1116a12c374f5;hp=d91a96eb639fc42dc8fdb3833456bf8fc164f647;hb=a1b737d1580fe8ad5aea50e003c7d0334cf6b663;hpb=737b84851cd8b3dd1d9f1920201127eac693dffb diff --git a/cprogs/rwbuffer.c b/cprogs/rwbuffer.c index d91a96e..4d8503c 100644 --- a/cprogs/rwbuffer.c +++ b/cprogs/rwbuffer.c @@ -13,7 +13,7 @@ * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, + * published by the Free Software Foundation; either version 3, * or (at your option) any later version. * * This is distributed in the hope that it will be useful, but @@ -22,22 +22,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public - * License along with this file; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this file; if not, consult the Free Software + * Foundation's website at www.fsf.org, or the GNU Project website at + * www.gnu.org. * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "rwbuffer.h" #ifndef RWBUFFER_SIZE_MB_DEF @@ -49,11 +39,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 +59,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 +71,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 +93,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 +121,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);