add: fd_flags=fcntl(fd, F_GETFL); if (fd_flags==-1){ LOG(L_ERR, "ERROR: io_watch_del: fnctl: GETFL failed:" " %s [%d]\n", strerror(errno), errno); goto error; } if (fcntl(fd, F_SETFL, fd_flags&(~O_ASYNC))==-1){ LOG(L_ERR, "ERROR: io_watch_del: fnctl: SETFL" " failed: %s [%d]\n", strerror(errno), errno); goto error; }
context: inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags){	#define fix_fd_array \	do{\			if (idx==-1){ \				/* fix idx if -1 and needed */ \				for (idx=0; (idx<h->fd_no) && \							(h->fd_array[idx].fd!=fd); idx++); \			} \			if (idx<h->fd_no){ \				memmove(&h->fd_array[idx], &h->fd_array[idx+1], \					(h->fd_no-(idx+1))*sizeof(*(h->fd_array))); \			} \	}while(0)		struct fd_map* e;#ifdef HAVE_EPOLL	int n;	struct epoll_event ep_event;#endif#ifdef HAVE_DEVPOLL	struct pollfd pfd;#endif		if ((fd<0) || (fd>=h->max_fd_no)){		LOG(L_CRIT, "BUG: io_watch_del: invalid fd %d, not in [0, %d) \n",						fd, h->fd_no);		goto error;	}	DBG("DBG: io_watch_del (%p, %d, %d) fd_no=%d called\n",			h, fd, idx, h->fd_no);	e=get_fd_map(h, fd);	/* more sanity checks */	if (e==0){		LOG(L_CRIT, "BUG: io_watch_del: no corresponding hash entry for %d\n",					fd);		goto error;	}	if (e->type==0 /*F_NONE*/){		LOG(L_ERR, "ERROR: io_watch_del: trying to delete already erased"				" entry %d in the hash(%d, %d, %p) )\n",				fd, e->fd, e->type, e->data);		goto error;	}		unhash_fd_map(e);		switch(h->poll_method){		case POLL_POLL:			fix_fd_array;			break;#ifdef HAVE_SELECT		case POLL_SELECT:			fix_fd_array;			FD_CLR(fd, &h->master_set);			if (h->max_fd_select && (h->max_fd_select==fd))				/* we don't know the prev. max, so we just decrement it */				h->max_fd_select--; 			break;#endif#ifdef HAVE_SIGIO_RT		case POLL_SIGIO_RT:			fix_fd_array;			/* FIXME: re-set ASYNC? (not needed if the fd is/will be closed			 *        but might cause problems if the fd is "moved")			 *        update: probably not needed, the fd_map type!=0			 *        check should catch old queued signals or in-transit fd			 *        (so making another syscall to reset ASYNC is not 			 *         necessary)*/			break;#endif#ifdef HAVE_EPOLL		case POLL_EPOLL_LT:		case POLL_EPOLL_ET:			if (!(flags & IO_FD_CLOSING)){				n=epoll_ctl(h->epfd, EPOLL_CTL_DEL, fd, &ep_event);				if (n==-1){					LOG(L_ERR, "ERROR: io_watch_del: removing fd from epoll "							"list failed: %s [%d]\n", strerror(errno), errno);					goto error;				}			}			break;#endif#ifdef HAVE_KQUEUE		case POLL_KQUEUE:			if (!(flags & IO_FD_CLOSING)){				if (kq_ev_change(h, fd, EVFILT_READ, EV_DELETE, 0)==-1)					goto error;			}			break;#endif#ifdef HAVE_DEVPOLL		case POLL_DEVPOLL:				/* for /dev/poll the closed fds _must_ be removed				   (they are not removed automatically on close()) */				pfd.fd=fd;				pfd.events=POLLREMOVE;				pfd.revents=0;again_devpoll:				if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){					if (errno==EINTR) goto again_devpoll;					LOG(L_ERR, "ERROR: io_watch_del: removing fd from "								"/dev/poll failed: %s [%d]\n", 								strerror(errno), errno);					goto error;				}				break;#endif		default:			LOG(L_CRIT, "BUG: io_watch_del: no support for poll method "					" %s (%d)\n", poll_method_str[h->poll_method], 					h->poll_method);			goto error;	}	h->fd_no--;	return 0;error:	return -1;#undef fix_fd_array}