From 422a8cea73d7e4b45642a3772f05d7c49ef0dddf Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 15 Jan 2004 14:32:00 +0000 Subject: [PATCH] (io_select, io_init, io_open, io_close, io_output, io_flush, io_write, io_puts, iom_create, iom_getmask, iom_set, iom_clear, iom_zero): Portability bug: io_select() passed bit_fdmask to select(). This breaks the fd_set abstraction, and works only with the traditional Unix implementation of fd_set. Use fd_set and its operations instead. Remove unused source files. Note: the offending code is currently unsued. But it's a time bomb, and fixing it also replaces a bunch of code by standard library services. --- include/bit.h | 71 -------------- include/io_mask.h | 11 +-- src/lib/gen/Makefile | 4 +- src/lib/gen/bit.c | 206 ---------------------------------------- src/lib/gen/io.c | 39 ++++---- src/lib/gen/io_mask.c | 38 ++++---- src/lib/player/accept.c | 1 - 7 files changed, 49 insertions(+), 321 deletions(-) delete mode 100644 include/bit.h delete mode 100644 src/lib/gen/bit.c diff --git a/include/bit.h b/include/bit.h deleted file mode 100644 index 079b12ee..00000000 --- a/include/bit.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Empire - A multi-player, client/server Internet based war game. - * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak, - * Ken Stevens, Steve McClure - * - * This program 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 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * --- - * - * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the - * related information and legal notices. It is expected that any future - * projects/authors will amend these files as needed. - * - * --- - * - * bit.h: Definitions for variable sized bitfields - * - * Known contributors to this file: - * - */ - -#ifndef _BIT_H_ -#define _BIT_H_ - -typedef unsigned int bit_mask; -typedef bit_mask *bit_fdmask; - -#ifndef bit -#define bit(x) (1 << (x)) -#endif - -/* - * File descriptor bit manipulation macros for use with select(2) - */ -#define BIT_NBBY 8 -#define BIT_BITSPERMASK (sizeof(bit_mask) * BIT_NBBY) - -#define BIT_SETB(a,b) \ - ((b)[(a)/BIT_BITSPERMASK] |= 1 << ((a) % BIT_BITSPERMASK)) -#define BIT_CLRB(a,b) \ - ((b)[(a)/BIT_BITSPERMASK] &= ~(1<< ((a) % BIT_BITSPERMASK))) -#define BIT_ISSETB(a,b) \ - ((b)[(a)/BIT_BITSPERMASK] & (1<< ((a) % BIT_BITSPERMASK))) -#define BIT_ISCLRB(a,b) \ - (((b)[(a)/BIT_BITSPERMASK] & (1<<((a) % BIT_BITSPERMASK))) == 0) - -extern bit_fdmask bit_newfdmask(); - -extern bit_fdmask bit_newfdmask(void); -extern void bit_zero(bit_fdmask); -extern void bit_not(bit_fdmask); -extern void bit_copy(bit_fdmask, bit_fdmask); -extern void bit_or(bit_fdmask, bit_fdmask); -extern void bit_or3(bit_fdmask, bit_fdmask, bit_fdmask); -extern void bit_and(bit_fdmask, bit_fdmask); -extern void bit_and3(bit_fdmask, bit_fdmask, bit_fdmask); -extern int bit_fd(bit_fdmask); - -#endif /* _BIT_H_ */ diff --git a/include/io_mask.h b/include/io_mask.h index 850d9817..bf2e9358 100644 --- a/include/io_mask.h +++ b/include/io_mask.h @@ -37,15 +37,14 @@ struct io_mask { int what; int maxfd; - bit_fdmask readmask; - bit_fdmask user_readmask; - bit_fdmask writemask; - bit_fdmask user_writemask; + fd_set *readmask; + fd_set *user_readmask; + fd_set *writemask; + fd_set *user_writemask; }; extern struct io_mask *iom_create(int); -extern void iom_getmask(struct io_mask *, int *, bit_fdmask *, - bit_fdmask *); +extern void iom_getmask(struct io_mask *, int *, fd_set **, fd_set **); extern void iom_set(struct io_mask *, int, int); extern void iom_clear(struct io_mask *, int, int); extern void iom_zero(struct io_mask *, int); diff --git a/src/lib/gen/Makefile b/src/lib/gen/Makefile index 43a05681..37e01c88 100644 --- a/src/lib/gen/Makefile +++ b/src/lib/gen/Makefile @@ -35,13 +35,13 @@ include ../../make.defs LIB = $(SRCDIR)/lib/libgen.a NTLIB = $(SRCDIR)\lib\libgen.lib -OBJS = atoip.o bit.o chance.o copy.o disassoc.o dtable.o \ +OBJS = atoip.o chance.o copy.o disassoc.o dtable.o \ emp_config.o getstarg.o getstring.o inet.o io.o \ io_mask.o ioqueue.o lock.o mapdist.o minmax.o numstr.o onearg.o \ parse.o plur.o queue.o round.o scthash.o \ strdup.o -NTOBJS = atoip.obj bit.obj chance.obj copy.obj disassoc.obj dtable.obj \ +NTOBJS = atoip.obj chance.obj copy.obj disassoc.obj dtable.obj \ emp_config.obj getstarg.obj getstring.obj \ inet.obj io.obj io_mask.obj ioqueue.obj lock.obj mapdist.obj minmax.obj \ numstr.obj onearg.obj parse.obj plur.obj queue.obj round.obj \ diff --git a/src/lib/gen/bit.c b/src/lib/gen/bit.c deleted file mode 100644 index 31406947..00000000 --- a/src/lib/gen/bit.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Empire - A multi-player, client/server Internet based war game. - * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak, - * Ken Stevens, Steve McClure - * - * This program 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 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * --- - * - * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the - * related information and legal notices. It is expected that any future - * projects/authors will amend these files as needed. - * - * --- - * - * bit.c: Allocate and search select bitfields - * - * Known contributors to this file: - * Steve McClure, 2000 - */ - -#include "misc.h" -#include "bit.h" -#include "gen.h" /* getfdtablesize etc. */ - -static int bit_nbytes; - -bit_fdmask -bit_newfdmask(void) -{ - bit_fdmask mask; - int nfile; - - if (bit_nbytes == 0) { - nfile = getfdtablesize(); - bit_nbytes = (nfile + (BIT_BITSPERMASK - 1)) / BIT_NBBY; - } - mask = (bit_fdmask)malloc(bit_nbytes); - (void)bit_zero(mask); - return mask; -} - -/* - * zero the bitfield - */ -void -bit_zero(bit_fdmask bitp) -{ - bit_mask *mask; - register int i; - register int nwords; - - mask = bitp; - nwords = bit_nbytes / sizeof(*mask); - for (i = 0; i < nwords; i++) - *mask++ = 0; -} - -/* - * zero the bitfield - */ -void -bit_not(bit_fdmask bitp) -{ - register bit_mask *mask; - register int i; - register int nwords; - - mask = bitp; - nwords = bit_nbytes / sizeof(*mask); - for (i = 0; i < nwords; i++, mask++) - *mask = ~(*mask); -} - -/* - * zero the bitfield - */ -void -bit_copy(bit_fdmask bitsrc, bit_fdmask bitdst) -{ - register bit_mask *src; - register bit_mask *dst; - register int i; - register int nwords; - - dst = bitdst; - src = bitsrc; - nwords = bit_nbytes / sizeof(*dst); - for (i = 0; i < nwords; i++) - *dst++ = *src++; -} - -/* - * zero the bitfield - */ -void -bit_or(bit_fdmask bitsrc, bit_fdmask bitdst) -{ - register bit_mask *src; - register bit_mask *dst; - register int i; - register int nwords; - - nwords = bit_nbytes / sizeof(*dst); - src = bitsrc; - dst = bitdst; - for (i = 0; i < nwords; i++) - *dst++ |= *src++; -} - -/* - * zero the bitfield - */ -void -bit_or3(bit_fdmask bitsrc1, bit_fdmask bitsrc2, bit_fdmask bitdst) -{ - register bit_mask *src1; - register bit_mask *src2; - register bit_mask *dst; - register int i; - register int nwords; - - src1 = bitsrc1; - src2 = bitsrc2; - dst = bitdst; - nwords = bit_nbytes / sizeof(*dst); - for (i = 0; i < nwords; i++) - *dst++ = *src1++ | *src2++; -} - -/* - * zero the bitfield - */ -void -bit_and(bit_fdmask bitsrc, bit_fdmask bitdst) -{ - register bit_mask *src; - register bit_mask *dst; - register int i; - register int nwords; - - nwords = bit_nbytes / sizeof(*src); - src = bitsrc; - dst = bitdst; - for (i = 0; i < nwords; i++) - *dst++ &= *src++; -} - -/* - * zero the bitfield - */ -void -bit_and3(bit_fdmask bitsrc1, bit_fdmask bitsrc2, bit_fdmask bitdst) -{ - register bit_mask *src1; - register bit_mask *src2; - register bit_mask *dst; - register int i; - register int nwords; - - src1 = bitsrc1; - src2 = bitsrc2; - dst = bitdst; - nwords = bit_nbytes / sizeof(*dst); - for (i = 0; i < nwords; i++) - *dst++ = *src1++ & *src2++; -} - -/* - * Return first bit set in fd mask. - * speedy version, not using BIT_ISSETB() - */ -int -bit_fd(bit_fdmask bitp) -{ - register bit_mask *mask; - register unsigned int j; - register bit_mask m; - register int i; - int nwords; - - mask = bitp; - nwords = bit_nbytes / sizeof(m); - for (i = 0; i < nwords; i++, mask++) { - if ((m = *mask) == 0) - continue; - for (j = 0; j < BIT_BITSPERMASK; j++) { - if (m & bit(j)) - return i * BIT_BITSPERMASK + j; - } - /*NOTREACHED*/ - } - return -1; -} diff --git a/src/lib/gen/io.c b/src/lib/gen/io.c index 72f7694f..00f971f1 100644 --- a/src/lib/gen/io.c +++ b/src/lib/gen/io.c @@ -56,7 +56,6 @@ #endif #include "misc.h" -#include "bit.h" #include "queue.h" #include "ioqueue.h" #include "io_mask.h" @@ -69,7 +68,8 @@ extern struct player *player; /* XXX */ static struct iop **io_list; static struct io_mask *iom; -static bit_fdmask newoutput; +static int fdmax; /* largest file descriptor seen */ +static fd_set newoutput; struct iop { int fd; @@ -86,7 +86,8 @@ io_init(void) { iom = iom_create(IO_READ | IO_WRITE); io_list = (struct iop **)calloc(getfdtablesize(), sizeof(*io_list)); - newoutput = bit_newfdmask(); + fdmax = 0; + FD_ZERO(&newoutput); } struct iop * @@ -119,6 +120,7 @@ io_open(int fd, int flags, int bufsize, int (*notify) (void), iop->notify = notify; io_list[fd] = iop; iom_set(iom, flags, fd); + if (fd > fdmax) fdmax = fd; return iop; } @@ -131,7 +133,7 @@ io_close(struct iop *iop) if (iop->output != 0) ioq_destroy(iop->output); iom_clear(iom, iop->flags, iop->fd); - BIT_CLRB(iop->fd, newoutput); + FD_CLR(iop->fd, &newoutput); io_list[iop->fd] = 0; #if !defined(_WIN32) (void)close(iop->fd); @@ -225,7 +227,7 @@ io_output(struct iop *iop, int waitforoutput) return 0; /* bit clear */ - BIT_CLRB(iop->fd, newoutput); + FD_CLR(iop->fd, &newoutput); /* If the iop is not write enabled. */ if ((iop->flags & IO_WRITE) == 0) @@ -332,33 +334,35 @@ io_output(struct iop *iop, int waitforoutput) int io_select(struct timeval *tv) { - bit_fdmask readmask; - bit_fdmask writemask; + fd_set *readmask; + fd_set *writemask; int n; - int nfds; + int maxfd; int fd; struct iop *iop; - iom_getmask(iom, &nfds, &readmask, &writemask); - n = select(nfds + 1, (fd_set *) readmask, (fd_set *) writemask, 0, tv); + iom_getmask(iom, &maxfd, &readmask, &writemask); + n = select(maxfd + 1, readmask, writemask, NULL, tv); if (n <= 0) { if (errno == EINTR) return 0; return -1; } - while ((fd = bit_fd(readmask)) >= 0) { + for (fd = 0; fd <= maxfd; ++fd) { + if (!FD_ISSET(fd, readmask)) continue; iop = io_list[fd]; if ((iop->flags & IO_NEWSOCK) == 0) (void)io_input(iop, IO_NOWAIT); if (iop->notify != 0) iop->notify(iop, IO_READ, iop->assoc); - BIT_CLRB(fd, readmask); + FD_CLR(fd, readmask); } - while ((fd = bit_fd(writemask)) >= 0) { + for (fd = 0; fd <= maxfd; ++fd) { + if (!FD_ISSET(fd, writemask)) continue; iop = io_list[fd]; if (io_output(iop, IO_NOWAIT) < 0 && iop->notify != 0) iop->notify(iop, IO_WRITE, iop->assoc); - BIT_CLRB(fd, writemask); + FD_CLR(fd, writemask); } return n; } @@ -369,7 +373,8 @@ io_flush(int doWait) int fd; struct iop *iop; - while ((fd = bit_fd(newoutput)) >= 0) { + for (fd = 0; fd <= fdmax; ++fd) { + if (!FD_ISSET(fd, &newoutput)) continue; iop = io_list[fd]; if (io_output(iop, doWait) < 0 && iop->notify != 0) iop->notify(iop, IO_WRITE, iop->assoc); @@ -405,7 +410,7 @@ io_write(struct iop *iop, s_char *buf, int nbytes, int doWait) if ((iop->flags & IO_WRITE) == 0) return -1; ioq_append(iop->output, buf, nbytes); - BIT_SETB(iop->fd, newoutput); + FD_SET(iop->fd, &newoutput); len = ioq_qsize(iop->output); if (len > iop->bufsize) { if (doWait) { @@ -443,7 +448,7 @@ io_puts(struct iop *iop, s_char *buf) { if ((iop->flags & IO_WRITE) == 0) return -1; - BIT_SETB(iop->fd, newoutput); + FD_SET(iop->fd, &newoutput); return ioq_puts(iop->output, buf); } diff --git a/src/lib/gen/io_mask.c b/src/lib/gen/io_mask.c index f83f7d24..457472bf 100644 --- a/src/lib/gen/io_mask.c +++ b/src/lib/gen/io_mask.c @@ -31,10 +31,8 @@ * */ -#include /* malloc */ -#include +#include #include "misc.h" -#include "bit.h" #include "empio.h" #include "io_mask.h" @@ -45,15 +43,19 @@ iom_create(int what) imp = (struct io_mask *)malloc(sizeof(*imp)); if (what & IO_READ) { - imp->readmask = bit_newfdmask(); - imp->user_readmask = bit_newfdmask(); + imp->readmask = malloc(sizeof(*imp->readmask)); + FD_ZERO(imp->readmask); + imp->user_readmask = malloc(sizeof(*imp->user_readmask)); + FD_ZERO(imp->user_readmask); } else { imp->readmask = 0; imp->user_readmask = 0; } if (what & IO_WRITE) { - imp->writemask = bit_newfdmask(); - imp->user_writemask = bit_newfdmask(); + imp->writemask = malloc(sizeof(*imp->writemask)); + FD_ZERO(imp->writemask); + imp->user_writemask = malloc(sizeof(*imp->user_writemask)); + FD_ZERO(imp->user_writemask); } else { imp->writemask = 0; imp->user_writemask = 0; @@ -64,16 +66,16 @@ iom_create(int what) } void -iom_getmask(struct io_mask *mask, int *nfdp, bit_fdmask *readp, - bit_fdmask *writep) +iom_getmask(struct io_mask *mask, + int *maxfdp, fd_set **readp, fd_set **writep) { if (mask->what & IO_READ) - bit_copy(mask->readmask, mask->user_readmask); + *mask->user_readmask = *mask->readmask; if (mask->what & IO_WRITE) - bit_copy(mask->writemask, mask->user_writemask); + *mask->user_writemask = *mask->writemask; *readp = mask->user_readmask; *writep = mask->user_writemask; - *nfdp = mask->maxfd; + *maxfdp = mask->maxfd; } void @@ -82,9 +84,9 @@ iom_set(struct io_mask *mask, int what, int fd) if ((mask->what & what) == 0) return; if (what & IO_READ) - BIT_SETB(fd, mask->readmask); + FD_SET(fd, mask->readmask); if (what & IO_WRITE) - BIT_SETB(fd, mask->writemask); + FD_SET(fd, mask->writemask); if (fd > mask->maxfd) mask->maxfd = fd; } @@ -95,9 +97,9 @@ iom_clear(struct io_mask *mask, int what, int fd) if ((mask->what & what) == 0) return; if (what & IO_READ) - BIT_CLRB(fd, mask->readmask); + FD_CLR(fd, mask->readmask); if (what & IO_WRITE) - BIT_CLRB(fd, mask->writemask); + FD_CLR(fd, mask->writemask); } void @@ -106,7 +108,7 @@ iom_zero(struct io_mask *mask, int what) if ((mask->what & what) == 0) return; if (what & IO_READ) - bit_zero(mask->readmask); + FD_ZERO(mask->readmask); if (what & IO_WRITE) - bit_zero(mask->writemask); + FD_ZERO(mask->writemask); } diff --git a/src/lib/player/accept.c b/src/lib/player/accept.c index dbf2f980..aa9ee30e 100644 --- a/src/lib/player/accept.c +++ b/src/lib/player/accept.c @@ -33,7 +33,6 @@ #include "prototypes.h" #include "misc.h" -#include "bit.h" #include "proto.h" #include "empthread.h" #include "player.h"