void ufs_file_base::set_size(offset_type newsize) { scoped_mutex_lock fd_lock(fd_mutex); offset_type cur_size = _size(); if (!(mode_ & RDONLY)) { #ifdef BOOST_MSVC HANDLE hfile; stxxl_check_ge_0(hfile = (HANDLE) ::_get_osfhandle(file_des), io_error); LARGE_INTEGER desired_pos; desired_pos.QuadPart = newsize; if (!SetFilePointerEx(hfile, desired_pos, NULL, FILE_BEGIN)) stxxl_win_lasterror_exit("SetFilePointerEx in ufs_file_base::set_size(..) oldsize=" << cur_size << " newsize=" << newsize << " ", io_error); if (!SetEndOfFile(hfile)) stxxl_win_lasterror_exit("SetEndOfFile oldsize=" << cur_size << " newsize=" << newsize << " ", io_error); #else stxxl_check_ge_0(::ftruncate(file_des, newsize), io_error); #endif } #ifndef BOOST_MSVC if (newsize > cur_size) stxxl_check_ge_0(::lseek(file_des, newsize - 1, SEEK_SET), io_error); #endif }
int accept(int fd, struct sockaddr *addr, int *anamelen) { oskit_error_t rc; oskit_socket_t *newsock; int newfd; if (fd_check_socket(fd)) return -1; fd_access_lock(fd, FD_RDWR); /* Accept a new connection */ rc = oskit_socket_accept(fd_array[fd].socket, (struct oskit_sockaddr *)addr, anamelen, &newsock); fd_access_unlock(fd, FD_RDWR); if (rc) { errno = rc; return -1; } /* Allocate a file descriptor for it */ newfd = fd_alloc((oskit_iunknown_t*)newsock, 0); if (newfd < 0) { oskit_socket_release(newsock); return -1; } fd_lock(newfd); fd_array[newfd].socket = newsock; fd_unlock(newfd); return newfd; }
void WfsFileBase::lock() { std::unique_lock<std::mutex> fd_lock(fd_mutex_); if (locked) return; // already locked if (LockFile(file_des_, 0, 0, 0xffffffff, 0xffffffff) == 0) THRILL_THROW_WIN_LASTERROR(IoError, "LockFile() fd=" << file_des_); locked = true; }
void sim_disk_file::set_size(offset_type newsize) { scoped_mutex_lock fd_lock(fd_mutex); if (newsize > _size()) { STXXL_THROW_ERRNO_LT_0(::lseek(file_des, newsize - 1, SEEK_SET), io_error, "lseek() fd=" << file_des << " pos=" << newsize - 1); STXXL_THROW_ERRNO_LT_0(::write(file_des, "", 1), io_error, "write() fd=" << file_des << " size=1"); } }
void UfsFileBase::close() { std::unique_lock<std::mutex> fd_lock(fd_mutex_); if (file_des_ == -1) return; if (::close(file_des_) < 0) THRILL_THROW_ERRNO(IoError, "close() fd=" << file_des_); file_des_ = -1; }
void WfsFileBase::close() { std::unique_lock<std::mutex> fd_lock(fd_mutex_); if (file_des_ == INVALID_HANDLE_VALUE) return; if (!CloseHandle(file_des_)) THRILL_THROW_WIN_LASTERROR(IoError, "CloseHandle() of file fd=" << file_des_); file_des_ = INVALID_HANDLE_VALUE; }
/* ========================================================================== * _fxstat() */ int _fxstat(int __ver, int fd, struct stat *buf) { int ret; if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) { if ((ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf)) < OK) { SET_ERRNO(-ret); } fd_unlock(fd, FD_READ); } return(ret); }
char * ttyname_r(int fd, char * buf, size_t len) { char * ret; if (fd_lock(fd, FD_READ) == OK) { ret = __ttyname_r_basic(fd_table[fd]->fd.i, buf, len); fd_unlock(fd, FD_READ); } else { ret = NULL; } return(ret); }
void ufs_file_base::close() { scoped_mutex_lock fd_lock(fd_mutex); if (file_des == -1) return; if (::close(file_des) < 0) stxxl_function_error(io_error); file_des = -1; }
char * ttyname(int fd) { char * ret; if (fd_lock(fd, FD_READ) == OK) { ret = __ttyname_basic(fd_table[fd]->fd.i); fd_unlock(fd, FD_READ); } else { ret = NULL; } return(ret); }
void UfsFileBase::lock() { #if THRILL_WINDOWS || defined(__MINGW32__) // not yet implemented #else std::unique_lock<std::mutex> fd_lock(fd_mutex_); struct flock lock_struct; lock_struct.l_type = (short)(mode_ & RDONLY ? F_RDLCK : F_RDLCK | F_WRLCK); lock_struct.l_whence = SEEK_SET; lock_struct.l_start = 0; lock_struct.l_len = 0; // lock all bytes if ((::fcntl(file_des_, F_SETLK, &lock_struct)) < 0) THRILL_THROW_ERRNO(IoError, "fcntl(,F_SETLK,) path=" << path_ << " fd=" << file_des_); #endif }
void ufs_file_base::lock() { #ifdef BOOST_MSVC // not yet implemented #else scoped_mutex_lock fd_lock(fd_mutex); struct flock lock_struct; lock_struct.l_type = (mode_ & RDONLY) ? F_RDLCK : F_RDLCK | F_WRLCK; lock_struct.l_whence = SEEK_SET; lock_struct.l_start = 0; lock_struct.l_len = 0; // lock all bytes if ((::fcntl(file_des, F_SETLK, &lock_struct)) < 0) STXXL_THROW2(io_error, "::fcntl(,F_SETLK,) path=" << filename << " fd=" << file_des); #endif }
void sim_disk_file::serve(void* buffer, offset_type offset, size_type bytes, request::request_type type) { scoped_mutex_lock fd_lock(fd_mutex); double op_start = timestamp(); stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); void* mem = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, file_des, offset); if (mem == MAP_FAILED) { STXXL_THROW_ERRNO (io_error, " mmap() failed." << " Page size: " << sysconf(_SC_PAGESIZE) << " offset modulo page size " << (offset % sysconf(_SC_PAGESIZE))); } else if (mem == 0) { STXXL_THROW_ERRNO(io_error, "mmap() returned NULL"); } else { if (type == request::READ) { memcpy(buffer, mem, bytes); } else { memcpy(mem, buffer, bytes); } STXXL_THROW_ERRNO_NE_0(munmap(mem, bytes), io_error, "munmap() failed"); } double delay = get_delay(offset, bytes); delay = delay - timestamp() + op_start; assert(delay > 0.0); int seconds_to_wait = static_cast<int>(floor(delay)); if (seconds_to_wait) sleep(seconds_to_wait); usleep((useconds_t)((delay - seconds_to_wait) * 1000000.)); }
STXXL_BEGIN_NAMESPACE void mmap_file::serve(void* buffer, offset_type offset, size_type bytes, request::request_type type) { scoped_mutex_lock fd_lock(fd_mutex); //assert(offset + bytes <= _size()); stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); int prot = (type == request::READ) ? PROT_READ : PROT_WRITE; void* mem = mmap(NULL, bytes, prot, MAP_SHARED, file_des, offset); // void *mem = mmap (buffer, bytes, prot , MAP_SHARED|MAP_FIXED , file_des, offset); // STXXL_MSG("Mmaped to "<<mem<<" , buffer suggested at "<<buffer); if (mem == MAP_FAILED) { STXXL_THROW_ERRNO(io_error, " mmap() failed." << " path=" << filename << " bytes=" << bytes << " Page size: " << sysconf(_SC_PAGESIZE) << " offset modulo page size " << (offset % sysconf(_SC_PAGESIZE))); } else if (mem == 0) { STXXL_THROW_ERRNO(io_error, "mmap() returned NULL"); } else { if (type == request::READ) { memcpy(buffer, mem, bytes); } else { memcpy(mem, buffer, bytes); } STXXL_THROW_ERRNO_NE_0(munmap(mem, bytes), io_error, "munmap() failed"); } }
void WfsFileBase::set_size(offset_type newsize) { std::unique_lock<std::mutex> fd_lock(fd_mutex_); offset_type cur_size = _size(); if (!(mode_ & RDONLY)) { LARGE_INTEGER desired_pos; desired_pos.QuadPart = newsize; bool direct_with_bad_size = (mode_& FileBase::DIRECT) && (newsize % bytes_per_sector); if (direct_with_bad_size) { if (!CloseHandle(file_des_)) THRILL_THROW_WIN_LASTERROR(IoError, "closing file (call of ::CloseHandle() from set_size) "); file_des_ = INVALID_HANDLE_VALUE; file_des_ = open_file_impl(filename, WRONLY); } if (!SetFilePointerEx(file_des_, desired_pos, nullptr, FILE_BEGIN)) THRILL_THROW_WIN_LASTERROR(IoError, "SetFilePointerEx() in wfs_file_base::set_size(..) oldsize=" << cur_size << " newsize=" << newsize << " "); if (!SetEndOfFile(file_des_)) THRILL_THROW_WIN_LASTERROR(IoError, "SetEndOfFile() oldsize=" << cur_size << " newsize=" << newsize << " "); if (direct_with_bad_size) { if (!CloseHandle(file_des_)) THRILL_THROW_WIN_LASTERROR(IoError, "closing file (call of ::CloseHandle() from set_size) "); file_des_ = INVALID_HANDLE_VALUE; file_des_ = open_file_impl(filename, mode_ & ~TRUNC); } } }
/* compile unit test with: gcc -DUNIT_TEST_FILELOCK -o filelock_fd filelock_fd.c */ int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s FILE\n", argv[0]); exit(-1); } char* filepath = argv[1]; int fd = 0; if ((fd = open(filepath, O_RDWR|O_CREAT, 0664)) == -1) { perror("open"); exit(1); } int rc = 0; // lock file fprintf(stdout, "locking: %s\n", filepath); rc = fd_lock(fd, filepath); if (0 != rc) { exit(2); } fprintf(stdout, "locked: %s\n", filepath); // sleep interval int interval = 10; fprintf(stdout, "sleeping %d\n", interval); sleep(interval); // unlock file rc = fd_unlock(fd, filepath); if (0 != rc) { exit(3); } fprintf(stdout, "unlocked: %s\n", filepath); return rc; }
STXXL_BEGIN_NAMESPACE void wincall_file::serve(const request* req) throw (io_error) { scoped_mutex_lock fd_lock(fd_mutex); assert(req->get_file() == this); offset_type offset = req->get_offset(); void* buffer = req->get_buffer(); size_type bytes = req->get_size(); request::request_type type = req->get_type(); if (bytes > 32 * 1024 * 1024) { STXXL_ERRMSG("Using a block size larger than 32 MiB may not work with the " << io_type() << " filetype"); } HANDLE handle = file_des; LARGE_INTEGER desired_pos; desired_pos.QuadPart = offset; if (!SetFilePointerEx(handle, desired_pos, NULL, FILE_BEGIN)) { STXXL_THROW_WIN_LASTERROR(io_error, "SetFilePointerEx in wincall_request::serve()" << " offset=" << offset << " this=" << this << " buffer=" << buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE")); } else { stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); if (type == request::READ) { DWORD NumberOfBytesRead = 0; assert(bytes <= std::numeric_limits<DWORD>::max()); if (!ReadFile(handle, buffer, (DWORD)bytes, &NumberOfBytesRead, NULL)) { STXXL_THROW_WIN_LASTERROR(io_error, "ReadFile" << " this=" << this << " offset=" << offset << " buffer=" << buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE") << " NumberOfBytesRead= " << NumberOfBytesRead); } else if (NumberOfBytesRead != bytes) { STXXL_THROW_WIN_LASTERROR(io_error, " partial read: missing " << (bytes - NumberOfBytesRead) << " out of " << bytes << " bytes"); } } else { DWORD NumberOfBytesWritten = 0; assert(bytes <= std::numeric_limits<DWORD>::max()); if (!WriteFile(handle, buffer, (DWORD)bytes, &NumberOfBytesWritten, NULL)) { STXXL_THROW_WIN_LASTERROR(io_error, "WriteFile" << " this=" << this << " offset=" << offset << " buffer=" << buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE") << " NumberOfBytesWritten= " << NumberOfBytesWritten); } else if (NumberOfBytesWritten != bytes) { STXXL_THROW_WIN_LASTERROR(io_error, " partial write: missing " << (bytes - NumberOfBytesWritten) << " out of " << bytes << " bytes"); } } } }
FileBase::offset_type WfsFileBase::size() { std::unique_lock<std::mutex> fd_lock(fd_mutex_); return _size(); }
void UfsFileBase::set_size(offset_type newsize) { std::unique_lock<std::mutex> fd_lock(fd_mutex_); return _set_size(newsize); }
/* * Enters a players name on a hi-score table, if "legal", and in any * case, displays some relevant portion of the high score list. * * Assumes "signals_ignore_tstp()" has been called. */ errr top_twenty(void) { int j; high_score the_score; time_t ct = time((time_t*)0); errr err; /* Clear the record */ (void)WIPE(&the_score, high_score); /* Save the version */ sprintf(the_score.what, "%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH); /* Calculate and save the points */ sprintf(the_score.pts, "%9ld", (long)total_points()); the_score.pts[9] = '\0'; /* Save the current gold */ sprintf(the_score.gold, "%9d", p_ptr->au); the_score.gold[9] = '\0'; /* Save the current turn */ sprintf(the_score.turns, "%9d", turn_real(turn)); the_score.turns[9] = '\0'; #ifdef HIGHSCORE_DATE_HACK /* Save the date in a hacked up form (9 chars) */ (void)sprintf(the_score.day, "%-.6s %-.2s", ctime(&ct) + 4, ctime(&ct) + 22); #else /* Save the date in standard form (8 chars) */ /* (void)strftime(the_score.day, 9, "%m/%d/%y", localtime(&ct)); */ /* Save the date in standard encoded form (9 chars) */ strftime(the_score.day, 10, "@%Y%m%d", localtime(&ct)); #endif /* Save the player name (15 chars) */ sprintf(the_score.who, "%-.15s", player_name); /* Save the player info XXX XXX XXX */ sprintf(the_score.uid, "%7u", player_uid); sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f')); sprintf(the_score.p_r, "%2d", p_ptr->prace); sprintf(the_score.p_c, "%2d", p_ptr->pclass); sprintf(the_score.p_a, "%2d", p_ptr->personality); /* Save the level and such */ sprintf(the_score.cur_lev, "%3d", p_ptr->lev); sprintf(the_score.cur_dun, "%3d", dun_level); sprintf(the_score.max_lev, "%3d", p_ptr->max_plv); sprintf(the_score.max_dun, "%3d", max_dlv[dungeon_type]); /* Save the cause of death (31 chars) */ if (strlen(p_ptr->died_from) >= sizeof(the_score.how)) { my_strcpy(the_score.how, p_ptr->died_from, sizeof(the_score.how) - 3); strcat(the_score.how, "..."); } else { strcpy(the_score.how, p_ptr->died_from); } /* Grab permissions */ safe_setuid_grab(); /* Lock (for writing) the highscore file, or fail */ err = fd_lock(highscore_fd, F_WRLCK); /* Drop permissions */ safe_setuid_drop(); if (err) return (1); /* Add a new entry to the score list, see where it went */ j = highscore_add(&the_score); /* Grab permissions */ safe_setuid_grab(); /* Unlock the highscore file, or fail */ err = fd_lock(highscore_fd, F_UNLCK); /* Drop permissions */ safe_setuid_drop(); if (err) return (1); /* Hack -- Display the top fifteen scores */ if (j < 10) { display_scores_aux(0, 15, j, NULL); } /* Display the scores surrounding the player */ else { display_scores_aux(0, 5, j, NULL); display_scores_aux(j - 2, j + 7, j, NULL); } /* Success */ return (0); }
STXXL_BEGIN_NAMESPACE void syscall_file::serve(const request* req) throw (io_error) { scoped_mutex_lock fd_lock(fd_mutex); assert(req->get_file() == this); offset_type offset = req->get_offset(); char* buffer = static_cast<char*>(req->get_buffer()); size_type bytes = req->get_size(); request::request_type type = req->get_type(); stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); while (bytes > 0) { off_t rc = ::lseek(file_des, offset, SEEK_SET); if (rc < 0) { STXXL_THROW_ERRNO (io_error, " this=" << this << " call=::lseek(fd,offset,SEEK_SET)" << " path=" << filename << " fd=" << file_des << " offset=" << offset << " buffer=" << (void*)buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE") << " rc=" << rc); } if (type == request::READ) { #if STXXL_MSVC assert(bytes <= std::numeric_limits<unsigned int>::max()); if ((rc = ::read(file_des, buffer, (unsigned int)bytes)) <= 0) #else if ((rc = ::read(file_des, buffer, bytes)) <= 0) #endif { STXXL_THROW_ERRNO (io_error, " this=" << this << " call=::read(fd,buffer,bytes)" << " path=" << filename << " fd=" << file_des << " offset=" << offset << " buffer=" << (void*)buffer << " bytes=" << bytes << " type=" << "READ" << " rc=" << rc); } bytes -= rc; offset += rc; buffer += rc; if (bytes > 0 && offset == this->_size()) { // read request extends past end-of-file // fill reminder with zeroes memset(buffer, 0, bytes); bytes = 0; } } else { #if STXXL_MSVC assert(bytes <= std::numeric_limits<unsigned int>::max()); if ((rc = ::write(file_des, buffer, (unsigned int)bytes)) <= 0) #else if ((rc = ::write(file_des, buffer, bytes)) <= 0) #endif { STXXL_THROW_ERRNO (io_error, " this=" << this << " call=::write(fd,buffer,bytes)" << " path=" << filename << " fd=" << file_des << " offset=" << offset << " buffer=" << (void*)buffer << " bytes=" << bytes << " type=" << "WRITE" << " rc=" << rc); } bytes -= rc; offset += rc; buffer += rc; } } }
file::offset_type ufs_file_base::size() { scoped_mutex_lock fd_lock(fd_mutex); return _size(); }
/* ========================================================================== * select() */ int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */ fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p; fd_set read_locks, write_locks, rdwr_locks; struct timespec timeout_time, current_time; int i, j, ret = 0, got_all_locks = 1; struct pthread_select_data data; if (numfds > dtablesize) { numfds = dtablesize; } data.nfds = 0; FD_ZERO(&data.readfds); FD_ZERO(&data.writefds); FD_ZERO(&data.exceptfds); /* Do this first */ if (timeout) { machdep_gettimeofday(¤t_time); timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec; if ((timeout_time.tv_nsec = current_time.tv_nsec + (timeout->tv_usec * 1000)) > 1000000000) { timeout_time.tv_nsec -= 1000000000; timeout_time.tv_sec++; } } FD_ZERO(&read_locks); FD_ZERO(&write_locks); FD_ZERO(&rdwr_locks); FD_ZERO(&real_readfds); FD_ZERO(&real_writefds); FD_ZERO(&real_exceptfds); /* lock readfds */ if (readfds || writefds || exceptfds) { for (i = 0; i < numfds; i++) { if ((readfds && (FD_ISSET(i, readfds))) || (exceptfds && FD_ISSET(i, exceptfds))) { if (writefds && FD_ISSET(i ,writefds)) { if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) { got_all_locks = 0; break; } FD_SET(i, &rdwr_locks); FD_SET(fd_table[i]->fd.i,&real_writefds); } else { if ((ret = fd_lock(i, FD_READ, NULL)) != OK) { got_all_locks = 0; break; } FD_SET(i, &read_locks); } if (readfds && FD_ISSET(i,readfds)) { FD_SET(fd_table[i]->fd.i, &real_readfds); } if (exceptfds && FD_ISSET(i,exceptfds)) { FD_SET(fd_table[i]->fd.i, &real_exceptfds); } if (fd_table[i]->fd.i >= data.nfds) { data.nfds = fd_table[i]->fd.i + 1; } } else { if (writefds && FD_ISSET(i, writefds)) { if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) { got_all_locks = 0; break; } FD_SET(i, &write_locks); FD_SET(fd_table[i]->fd.i,&real_writefds); if (fd_table[i]->fd.i >= data.nfds) { data.nfds = fd_table[i]->fd.i + 1; } } } } } if (got_all_locks) { memcpy(&data.readfds,&real_readfds,sizeof(fd_set)); memcpy(&data.writefds,&real_writefds,sizeof(fd_set)); memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set)); real_readfds_p = (readfds == NULL) ? NULL : &real_readfds; real_writefds_p = (writefds == NULL) ? NULL : &real_writefds; real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds; pthread_run->sighandled=0; if ((ret = machdep_sys_select(data.nfds, real_readfds_p, real_writefds_p, real_exceptfds_p, &zero_timeout)) == OK) { pthread_sched_prevent(); real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds; real_writefds_p = (writefds == NULL) ? NULL : &data.writefds; real_readfds_p = (readfds == NULL) ? NULL : &data.readfds; pthread_queue_enq(&fd_wait_select, pthread_run); pthread_run->data.select_data = &data; SET_PF_WAIT_EVENT(pthread_run); if (timeout) { machdep_gettimeofday(¤t_time); sleep_schedule(¤t_time, &timeout_time); SET_PF_AT_CANCEL_POINT(pthread_run); pthread_resched_resume(PS_SELECT_WAIT); CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* We're awake */ if (sleep_cancel(pthread_run) == NOTOK) { ret = OK; } else { int count = 0; for (i = 0; i < numfds; i++) { if (real_readfds_p && (FD_ISSET(i, real_readfds_p))) count++; if (real_writefds_p && (FD_ISSET(i, real_writefds_p))) count++; if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p))) count++; } ret = count; } /* Moving this after the sleep_cancel() seemed * to fix intermittent crashes during heavy * socket use. (mevans) */ CLEAR_PF_DONE_EVENT(pthread_run); } else { int count = 0; SET_PF_AT_CANCEL_POINT(pthread_run); pthread_resched_resume(PS_SELECT_WAIT); CLEAR_PF_AT_CANCEL_POINT(pthread_run); CLEAR_PF_DONE_EVENT(pthread_run); for (i = 0; i < numfds; i++) { if (real_readfds_p && (FD_ISSET(i, real_readfds_p))) count++; if (real_writefds_p && (FD_ISSET(i, real_writefds_p))) count++; if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p))) count++; } ret = count; } if (pthread_run->sighandled) /* Added by monty */ { /* We where aborted */ ret= NOTOK; SET_ERRNO(EINTR); } } else if (ret < 0) { SET_ERRNO(-ret); ret = NOTOK; } } /* clean up the locks */ for (i = 0; i < numfds; i++) { /* Changed by monty */ if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ); if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR); if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE); } if (ret > 0) { if (readfds != NULL) { for (i = 0; i < numfds; i++) { if (! (FD_ISSET(i,readfds) && FD_ISSET(fd_table[i]->fd.i,real_readfds_p))) FD_CLR(i,readfds); } } if (writefds != NULL) { for (i = 0; i < numfds; i++) if (! (FD_ISSET(i,writefds) && FD_ISSET(fd_table[i]->fd.i,real_writefds_p))) FD_CLR(i,writefds); } if (exceptfds != NULL) { for (i = 0; i < numfds; i++) if (! (FD_ISSET(i,exceptfds) && FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p))) FD_CLR(i,exceptfds); } } else { if (exceptfds != NULL) FD_ZERO(exceptfds); if (writefds != NULL) FD_ZERO(writefds); if (readfds != NULL) FD_ZERO(readfds); } return(ret); }