rem: int n;
context: inline static int io_watch_add(	io_wait_h* h,								int fd,								fd_type type,								void* data){	/* helper macros */#define fd_array_setup \	do{ \		h->fd_array[h->fd_no].fd=fd; \		h->fd_array[h->fd_no].events=POLLIN; /* useless for select */ \		h->fd_array[h->fd_no].revents=0;     /* useless for select */ \	}while(0)	#define set_fd_flags(f) \	do{ \			flags=fcntl(fd, F_GETFL); \			if (flags==-1){ \				LOG(L_ERR, "ERROR: io_watch_add: fnctl: GETFL failed:" \						" %s [%d]\n", strerror(errno), errno); \				goto error; \			} \			if (fcntl(fd, F_SETFL, flags|(f))==-1){ \				LOG(L_ERR, "ERROR: io_watch_add: fnctl: SETFL" \							" failed: %s [%d]\n", strerror(errno), errno); \				goto error; \			} \	}while(0)			struct fd_map* e;	int flags;#ifdef HAVE_EPOLL	int n;	struct epoll_event ep_event;#endif#ifdef HAVE_DEVPOLL	struct pollfd pfd;#endif#if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL)	int idx;	int check_io;	struct pollfd pf;		check_io=0; /* set to 1 if we need to check for pre-existiing queued				   io/data on the fd */	idx=-1;#endif	e=0;	if (fd==-1){		LOG(L_CRIT, "BUG: io_watch_add: fd is -1!\n");		goto error;	}	/* check if not too big */	if (h->fd_no>=h->max_fd_no){		LOG(L_CRIT, "ERROR: io_watch_add: maximum fd number exceeded:"				" %d/%d\n", h->fd_no, h->max_fd_no);		goto error;	}	DBG("DBG: io_watch_add(%p, %d, %d, %p), fd_no=%d\n",			h, fd, type, data, h->fd_no);	/*  hash sanity check */	e=get_fd_map(h, fd);	if (e && (e->type!=0 /*F_NONE*/)){		LOG(L_ERR, "ERROR: io_watch_add: trying to overwrite entry %d"				" in the hash(%d, %d, %p) with (%d, %d, %p)\n",				fd, e->fd, e->type, e->data, fd, type, data);		goto error;	}		if ((e=hash_fd_map(h, fd, type, data))==0){		LOG(L_ERR, "ERROR: io_watch_add: failed to hash the fd %d\n", fd);		goto error;	}	switch(h->poll_method){ /* faster then pointer to functions */		case POLL_POLL:			fd_array_setup;			set_fd_flags(O_NONBLOCK);			break;#ifdef HAVE_SELECT		case POLL_SELECT:			fd_array_setup;			FD_SET(fd, &h->master_set);			if (h->max_fd_select<fd) h->max_fd_select=fd;			break;#endif#ifdef HAVE_SIGIO_RT		case POLL_SIGIO_RT:			fd_array_setup;			/* re-set O_ASYNC might be needed, if not done from 			 * io_watch_del (or if somebody wants to add a fd which has			 * already O_ASYNC/F_SETSIG set on a dupplicate)			 */			/* set async & signal */			if (fcntl(fd, F_SETOWN, my_pid())==-1){				LOG(L_ERR, "ERROR: io_watch_add: fnctl: SETOWN"				" failed: %s [%d]\n", strerror(errno), errno);				goto error;			}			if (fcntl(fd, F_SETSIG, h->signo)==-1){				LOG(L_ERR, "ERROR: io_watch_add: fnctl: SETSIG"					" failed: %s [%d]\n", strerror(errno), errno);				goto error;			}			/* set both non-blocking and async */			set_fd_flags(O_ASYNC| O_NONBLOCK);#ifdef EXTRA_DEBUG			DBG("io_watch_add: sigio_rt on f %d, signal %d to pid %d\n",					fd,  h->signo, my_pid());#endif			/* empty socket receive buffer, if buffer is already full			 * no more space to put packets			 * => no more signals are ever generated			 * also when moving fds, the freshly moved fd might have			 *  already some bytes queued, we want to get them now			 *  and not later -- andrei */			idx=h->fd_no;			check_io=1;			break;#endif#ifdef HAVE_EPOLL		case POLL_EPOLL_LT:			ep_event.events=EPOLLIN;			ep_event.data.ptr=e;again1:			n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);			if (n==-1){				if (errno==EAGAIN) goto again1;				LOG(L_ERR, "ERROR: io_watch_add: epoll_ctl failed: %s [%d]\n",					strerror(errno), errno);				goto error;			}			break;		case POLL_EPOLL_ET:			set_fd_flags(O_NONBLOCK);			ep_event.events=EPOLLIN|EPOLLET;			ep_event.data.ptr=e;again2:			n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);			if (n==-1){				if (errno==EAGAIN) goto again2;				LOG(L_ERR, "ERROR: io_watch_add: epoll_ctl failed: %s [%d]\n",					strerror(errno), errno);				goto error;			}			idx=-1;			check_io=1;			break;#endif#ifdef HAVE_KQUEUE		case POLL_KQUEUE:			if (kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e)==-1)				goto error;			break;#endif#ifdef HAVE_DEVPOLL		case POLL_DEVPOLL:			pfd.fd=fd;			pfd.events=POLLIN;			pfd.revents=0;again_devpoll:			if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){				if (errno==EAGAIN) goto again_devpoll;				LOG(L_ERR, "ERROR: io_watch_add: /dev/poll write failed:"							"%s [%d]\n", strerror(errno), errno);				goto error;			}			break;#endif					default:			LOG(L_CRIT, "BUG: io_watch_add: no support for poll method "					" %s (%d)\n", poll_method_str[h->poll_method],					h->poll_method);			goto error;	}		h->fd_no++; /* "activate" changes, for epoll/kqueue/devpoll it				   has only informative value */#if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL)	if (check_io){		/* handle possible pre-existing events */		pf.fd=fd;		pf.events=POLLIN;check_io_again:		while( ((n=poll(&pf, 1, 0))>0) && (handle_io(e, idx)>0));		if (n==-1){			if (errno==EINTR) goto check_io_again;			LOG(L_ERR, "ERROR: io_watch_add: check_io poll: %s [%d]\n",						strerror(errno), errno);		}	}#endif	return 0;error:	if (e) unhash_fd_map(e);	return -1;#undef fd_array_setup#undef set_fd_flags }