sim: Convert stat functions to use VPtr.

Change-Id: I1fe43ad7508b5fbbcbf6c84195858455fc8f3e85
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29402
Reviewed-by: Matthew Poremba <matthew.poremba@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2020-05-07 04:18:04 -07:00
parent 881c257c75
commit 02c023eebb

View File

@@ -554,11 +554,12 @@ getElapsedTimeNano(T1 &sec, T2 &nsec)
//// buffer. Also copies the target buffer out to the simulated
//// memory space. Used by stat(), fstat(), and lstat().
template <typename target_stat, typename host_stat>
template <typename OS, typename TgtStatPtr, typename HostStatPtr>
void
convertStatBuf(target_stat &tgt, host_stat *host,
ByteOrder bo, bool fakeTTY=false)
copyOutStatBuf(TgtStatPtr tgt, HostStatPtr host, bool fakeTTY=false)
{
constexpr ByteOrder bo = OS::byteOrder;
if (fakeTTY)
tgt->st_dev = 0xA;
else
@@ -602,13 +603,15 @@ convertStatBuf(target_stat &tgt, host_stat *host,
// Same for stat64
template <typename target_stat, typename host_stat64>
template <typename OS, typename TgtStatPtr, typename HostStatPtr>
void
convertStat64Buf(target_stat &tgt, host_stat64 *host,
ByteOrder bo, bool fakeTTY=false)
copyOutStat64Buf(TgtStatPtr tgt, HostStatPtr host,
bool fakeTTY=false)
{
convertStatBuf<target_stat, host_stat64>(tgt, host, bo, fakeTTY);
copyOutStatBuf<OS>(tgt, host, fakeTTY);
#if defined(STAT_HAVE_NSEC)
constexpr ByteOrder bo = OS::byteOrder;
tgt->st_atime_nsec = host->st_atime_nsec;
tgt->st_atime_nsec = htog(tgt->st_atime_nsec, bo);
tgt->st_mtime_nsec = host->st_mtime_nsec;
@@ -622,38 +625,11 @@ convertStat64Buf(target_stat &tgt, host_stat64 *host,
#endif
}
// Here are a couple of convenience functions
template<class OS>
template <class OS, typename TgtStatPtr, typename HostStatPtr>
void
copyOutStatBuf(PortProxy &mem, Addr addr,
hst_stat *host, bool fakeTTY = false)
copyOutStatfsBuf(TgtStatPtr tgt, HostStatPtr host)
{
typedef TypedBufferArg<typename OS::tgt_stat> tgt_stat_buf;
tgt_stat_buf tgt(addr);
convertStatBuf<tgt_stat_buf, hst_stat>(tgt, host, OS::byteOrder, fakeTTY);
tgt.copyOut(mem);
}
template<class OS>
void
copyOutStat64Buf(PortProxy &mem, Addr addr,
hst_stat64 *host, bool fakeTTY = false)
{
typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
tgt_stat_buf tgt(addr);
convertStat64Buf<tgt_stat_buf, hst_stat64>(
tgt, host, OS::byteOrder, fakeTTY);
tgt.copyOut(mem);
}
template <class OS>
void
copyOutStatfsBuf(PortProxy &mem, Addr addr,
hst_statfs *host)
{
TypedBufferArg<typename OS::tgt_statfs> tgt(addr);
const ByteOrder bo = OS::byteOrder;
constexpr ByteOrder bo = OS::byteOrder;
tgt->f_type = htog(host->f_type, bo);
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
@@ -687,8 +663,6 @@ copyOutStatfsBuf(PortProxy &mem, Addr addr,
*/
memset(&tgt->f_spare, 0, sizeof(tgt->f_spare));
#endif
tgt.copyOut(mem);
}
/// Target ioctl() handler. For the most part, programs call ioctl()
@@ -979,18 +953,15 @@ renameatFunc(SyscallDesc *desc, ThreadContext *tc,
/// Target sysinfo() handler.
template <class OS>
SyscallReturn
sysinfoFunc(SyscallDesc *desc, ThreadContext *tc, Addr info)
sysinfoFunc(SyscallDesc *desc, ThreadContext *tc,
VPtr<typename OS::tgt_sysinfo> sysinfo)
{
auto process = tc->getProcessPtr();
TypedBufferArg<typename OS::tgt_sysinfo> sysinfo(info);
sysinfo->uptime = seconds_since_epoch;
sysinfo->totalram = process->system->memSize();
sysinfo->mem_unit = 1;
sysinfo.copyOut(tc->getVirtProxy());
return 0;
}
@@ -1199,7 +1170,8 @@ mremapFunc(SyscallDesc *desc, ThreadContext *tc,
/// Target stat() handler.
template <class OS>
SyscallReturn
statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
statFunc(SyscallDesc *desc, ThreadContext *tc,
Addr pathname, VPtr<typename OS::tgt_stat> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
@@ -1216,7 +1188,7 @@ statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
copyOutStatBuf<OS>(tgt_stat, &hostBuf);
return 0;
}
@@ -1225,7 +1197,8 @@ statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
/// Target stat64() handler.
template <class OS>
SyscallReturn
stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
stat64Func(SyscallDesc *desc, ThreadContext *tc,
Addr pathname, VPtr<typename OS::tgt_stat64> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
@@ -1247,7 +1220,7 @@ stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
return 0;
}
@@ -1257,7 +1230,7 @@ stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
template <class OS>
SyscallReturn
fstatat64Func(SyscallDesc *desc, ThreadContext *tc,
int dirfd, Addr pathname, Addr bufPtr)
int dirfd, Addr pathname, VPtr<typename OS::tgt_stat64> tgt_stat)
{
auto process = tc->getProcessPtr();
if (dirfd != OS::TGT_AT_FDCWD)
@@ -1281,7 +1254,7 @@ fstatat64Func(SyscallDesc *desc, ThreadContext *tc,
if (result < 0)
return -errno;
copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
return 0;
}
@@ -1290,7 +1263,8 @@ fstatat64Func(SyscallDesc *desc, ThreadContext *tc,
/// Target fstat64() handler.
template <class OS>
SyscallReturn
fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
fstat64Func(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd, VPtr<typename OS::tgt_stat64> tgt_stat)
{
auto p = tc->getProcessPtr();
@@ -1310,7 +1284,7 @@ fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
copyOutStat64Buf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
return 0;
}
@@ -1319,7 +1293,8 @@ fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
/// Target lstat() handler.
template <class OS>
SyscallReturn
lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
lstatFunc(SyscallDesc *desc, ThreadContext *tc,
Addr pathname, VPtr<typename OS::tgt_stat> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
@@ -1336,7 +1311,7 @@ lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
copyOutStatBuf<OS>(tgt_stat, &hostBuf);
return 0;
}
@@ -1344,7 +1319,8 @@ lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
/// Target lstat64() handler.
template <class OS>
SyscallReturn
lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
lstat64Func(SyscallDesc *desc, ThreadContext *tc,
Addr pathname, VPtr<typename OS::tgt_stat64> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
@@ -1366,7 +1342,7 @@ lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
return 0;
}
@@ -1374,7 +1350,8 @@ lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
/// Target fstat() handler.
template <class OS>
SyscallReturn
fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
fstatFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd, VPtr<typename OS::tgt_stat> tgt_stat)
{
auto p = tc->getProcessPtr();
@@ -1391,7 +1368,7 @@ fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
copyOutStatBuf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
return 0;
}
@@ -1399,7 +1376,8 @@ fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
/// Target statfs() handler.
template <class OS>
SyscallReturn
statfsFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
statfsFunc(SyscallDesc *desc, ThreadContext *tc,
Addr pathname, VPtr<typename OS::tgt_statfs> tgt_stat)
{
#if defined(__linux__)
std::string path;
@@ -1417,7 +1395,7 @@ statfsFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStatfsBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
return 0;
#else
warnUnsupportedOS("statfs");
@@ -1551,7 +1529,8 @@ cloneBackwardsFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags,
/// Target fstatfs() handler.
template <class OS>
SyscallReturn
fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
fstatfsFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd, VPtr<typename OS::tgt_statfs> tgt_stat)
{
auto p = tc->getProcessPtr();
@@ -1566,7 +1545,7 @@ fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
if (result < 0)
return -errno;
copyOutStatfsBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
return 0;
}
@@ -1841,10 +1820,8 @@ mmap2Func(SyscallDesc *desc, ThreadContext *tc,
template <class OS>
SyscallReturn
getrlimitFunc(SyscallDesc *desc, ThreadContext *tc,
unsigned resource, Addr rlim)
unsigned resource, VPtr<typename OS::rlimit> rlp)
{
TypedBufferArg<typename OS::rlimit> rlp(rlim);
const ByteOrder bo = OS::byteOrder;
switch (resource) {
case OS::TGT_RLIMIT_STACK:
@@ -1873,24 +1850,22 @@ getrlimitFunc(SyscallDesc *desc, ThreadContext *tc,
break;
}
rlp.copyOut(tc->getVirtProxy());
return 0;
}
template <class OS>
SyscallReturn
prlimitFunc(SyscallDesc *desc, ThreadContext *tc,
int pid, int resource, Addr n, Addr o)
int pid, int resource, Addr n, VPtr<typename OS::rlimit> rlp)
{
if (pid != 0) {
warn("prlimit: ignoring rlimits for nonzero pid");
return -EPERM;
}
if (n != 0)
if (n)
warn("prlimit: ignoring new rlimit");
if (o != 0) {
if (rlp) {
const ByteOrder bo = OS::byteOrder;
TypedBufferArg<typename OS::rlimit> rlp(o);
switch (resource) {
case OS::TGT_RLIMIT_STACK:
// max stack size in bytes: make up a number (8MB for now)
@@ -1909,7 +1884,6 @@ prlimitFunc(SyscallDesc *desc, ThreadContext *tc,
return -EINVAL;
break;
}
rlp.copyOut(tc->getVirtProxy());
}
return 0;
}
@@ -1918,33 +1892,26 @@ prlimitFunc(SyscallDesc *desc, ThreadContext *tc,
template <class OS>
SyscallReturn
clock_gettimeFunc(SyscallDesc *desc, ThreadContext *tc,
int clk_id, Addr tp_ptr)
int clk_id, VPtr<typename OS::timespec> tp)
{
TypedBufferArg<typename OS::timespec> tp(tp_ptr);
getElapsedTimeNano(tp->tv_sec, tp->tv_nsec);
tp->tv_sec += seconds_since_epoch;
tp->tv_sec = htog(tp->tv_sec, OS::byteOrder);
tp->tv_nsec = htog(tp->tv_nsec, OS::byteOrder);
tp.copyOut(tc->getVirtProxy());
return 0;
}
/// Target clock_getres() function.
template <class OS>
SyscallReturn
clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, Addr tp_ptr)
clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id,
VPtr<typename OS::timespec> tp)
{
TypedBufferArg<typename OS::timespec> tp(tp_ptr);
// Set resolution at ns, which is what clock_gettime() returns
tp->tv_sec = 0;
tp->tv_nsec = 1;
tp.copyOut(tc->getVirtProxy());
return 0;
}
@@ -1952,17 +1919,13 @@ clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, Addr tp_ptr)
template <class OS>
SyscallReturn
gettimeofdayFunc(SyscallDesc *desc, ThreadContext *tc,
Addr tv_ptr, Addr tz_ptr)
VPtr<typename OS::timeval> tp, Addr tz_ptr)
{
TypedBufferArg<typename OS::timeval> tp(tv_ptr);
getElapsedTimeMicro(tp->tv_sec, tp->tv_usec);
tp->tv_sec += seconds_since_epoch;
tp->tv_sec = htog(tp->tv_sec, OS::byteOrder);
tp->tv_usec = htog(tp->tv_usec, OS::byteOrder);
tp.copyOut(tc->getVirtProxy());
return 0;
}
@@ -2090,10 +2053,9 @@ execveFunc(SyscallDesc *desc, ThreadContext *tc,
template <class OS>
SyscallReturn
getrusageFunc(SyscallDesc *desc, ThreadContext *tc,
int who /* THREAD, SELF, or CHILDREN */, Addr usage)
int who /* THREAD, SELF, or CHILDREN */,
VPtr<typename OS::rusage> rup)
{
TypedBufferArg<typename OS::rusage> rup(usage);
rup->ru_utime.tv_sec = 0;
rup->ru_utime.tv_usec = 0;
rup->ru_stime.tv_sec = 0;
@@ -2131,18 +2093,14 @@ getrusageFunc(SyscallDesc *desc, ThreadContext *tc,
who);
}
rup.copyOut(tc->getVirtProxy());
return 0;
}
/// Target times() function.
template <class OS>
SyscallReturn
timesFunc(SyscallDesc *desc, ThreadContext *tc, Addr bufPtr)
timesFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<typename OS::tms> bufp)
{
TypedBufferArg<typename OS::tms> bufp(bufPtr);
// Fill in the time structure (in clocks)
int64_t clocks = curTick() * OS::M5_SC_CLK_TCK / SimClock::Int::s;
bufp->tms_utime = clocks;
@@ -2153,9 +2111,6 @@ timesFunc(SyscallDesc *desc, ThreadContext *tc, Addr bufPtr)
// Convert to host endianness
bufp->tms_utime = htog(bufp->tms_utime, OS::byteOrder);
// Write back
bufp.copyOut(tc->getVirtProxy());
// Return clock ticks since system boot
return clocks;
}
@@ -2264,40 +2219,27 @@ socketpairFunc(SyscallDesc *desc, ThreadContext *tc,
template <class OS>
SyscallReturn
selectFunc(SyscallDesc *desc, ThreadContext *tc,
int nfds_t, Addr fds_read_ptr, Addr fds_writ_ptr,
Addr fds_excp_ptr, Addr time_val_ptr)
selectFunc(SyscallDesc *desc, ThreadContext *tc, int nfds,
VPtr<typename OS::fd_set> readfds,
VPtr<typename OS::fd_set> writefds,
VPtr<typename OS::fd_set> errorfds,
VPtr<typename OS::timeval> timeout)
{
int retval;
auto p = tc->getProcessPtr();
TypedBufferArg<typename OS::fd_set> rd_t(fds_read_ptr);
TypedBufferArg<typename OS::fd_set> wr_t(fds_writ_ptr);
TypedBufferArg<typename OS::fd_set> ex_t(fds_excp_ptr);
TypedBufferArg<typename OS::timeval> tp(time_val_ptr);
/**
* Host fields. Notice that these use the definitions from the system
* headers instead of the gem5 headers and libraries. If the host and
* target have different header file definitions, this will not work.
*/
fd_set rd_h;
FD_ZERO(&rd_h);
fd_set wr_h;
FD_ZERO(&wr_h);
fd_set ex_h;
FD_ZERO(&ex_h);
/**
* Copy in the fd_set from the target.
*/
if (fds_read_ptr)
rd_t.copyIn(tc->getVirtProxy());
if (fds_writ_ptr)
wr_t.copyIn(tc->getVirtProxy());
if (fds_excp_ptr)
ex_t.copyIn(tc->getVirtProxy());
fd_set readfds_h;
FD_ZERO(&readfds_h);
fd_set writefds_h;
FD_ZERO(&writefds_h);
fd_set errorfds_h;
FD_ZERO(&errorfds_h);
/**
* We need to translate the target file descriptor set into a host file
@@ -2310,7 +2252,7 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc,
*/
int nfds_h = 0;
std::map<int, int> trans_map;
auto try_add_host_set = [&](fd_set *tgt_set_entry,
auto try_add_host_set = [&](typename OS::fd_set *tgt_set_entry,
fd_set *hst_set_entry,
int iter) -> bool
{
@@ -2319,7 +2261,7 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc,
* descriptor set on the target. We need to check if the target file
* descriptor value passed in as iter is part of the set.
*/
if (FD_ISSET(iter, tgt_set_entry)) {
if (FD_ISSET(iter, (fd_set *)tgt_set_entry)) {
/**
* We know that the target file descriptor belongs to the set,
* but we do not yet know if the file descriptor is valid or
@@ -2353,22 +2295,25 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc,
return false;
};
for (int i = 0; i < nfds_t; i++) {
if (fds_read_ptr) {
bool ebadf = try_add_host_set((fd_set*)&*rd_t, &rd_h, i);
if (ebadf) return -EBADF;
for (int i = 0; i < nfds; i++) {
if (readfds) {
bool ebadf = try_add_host_set(readfds, &readfds_h, i);
if (ebadf)
return -EBADF;
}
if (fds_writ_ptr) {
bool ebadf = try_add_host_set((fd_set*)&*wr_t, &wr_h, i);
if (ebadf) return -EBADF;
if (writefds) {
bool ebadf = try_add_host_set(writefds, &writefds_h, i);
if (ebadf)
return -EBADF;
}
if (fds_excp_ptr) {
bool ebadf = try_add_host_set((fd_set*)&*ex_t, &ex_h, i);
if (ebadf) return -EBADF;
if (errorfds) {
bool ebadf = try_add_host_set(errorfds, &errorfds_h, i);
if (ebadf)
return -EBADF;
}
}
if (time_val_ptr) {
if (timeout) {
/**
* It might be possible to decrement the timeval based on some
* derivation of wall clock determined from elapsed simulator ticks
@@ -2376,14 +2321,14 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc,
* zero timeout. (There is no reason to block during the simulation
* as it only decreases simulator performance.)
*/
tp->tv_sec = 0;
tp->tv_usec = 0;
timeout->tv_sec = 0;
timeout->tv_usec = 0;
retval = select(nfds_h,
fds_read_ptr ? &rd_h : nullptr,
fds_writ_ptr ? &wr_h : nullptr,
fds_excp_ptr ? &ex_h : nullptr,
(timeval*)&*tp);
readfds ? &readfds_h : nullptr,
writefds ? &writefds_h : nullptr,
errorfds ? &errorfds_h : nullptr,
(timeval *)(typename OS::timeval *)timeout);
} else {
/**
* If the timeval pointer is null, setup a new timeval structure to
@@ -2395,9 +2340,9 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc,
struct timeval tv = { 0, 0 };
retval = select(nfds_h,
fds_read_ptr ? &rd_h : nullptr,
fds_writ_ptr ? &wr_h : nullptr,
fds_excp_ptr ? &ex_h : nullptr,
readfds ? &readfds_h : nullptr,
readfds ? &writefds_h : nullptr,
readfds ? &errorfds_h : nullptr,
&tv);
if (retval == 0) {
@@ -2416,9 +2361,9 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc,
if (retval == -1)
return -errno;
FD_ZERO((fd_set*)&*rd_t);
FD_ZERO((fd_set*)&*wr_t);
FD_ZERO((fd_set*)&*ex_t);
FD_ZERO(readfds);
FD_ZERO(writefds);
FD_ZERO(errorfds);
/**
* We need to translate the host file descriptor set into a target file
@@ -2426,31 +2371,16 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc,
* and the fd_set defined in header files.
*/
for (int i = 0; i < nfds_h; i++) {
if (fds_read_ptr) {
if (FD_ISSET(i, &rd_h))
FD_SET(trans_map[i], (fd_set*)&*rd_t);
}
if (readfds && FD_ISSET(i, &readfds_h))
FD_SET(trans_map[i], readfds);
if (fds_writ_ptr) {
if (FD_ISSET(i, &wr_h))
FD_SET(trans_map[i], (fd_set*)&*wr_t);
}
if (writefds && FD_ISSET(i, &writefds_h))
FD_SET(trans_map[i], writefds);
if (fds_excp_ptr) {
if (FD_ISSET(i, &ex_h))
FD_SET(trans_map[i], (fd_set*)&*ex_t);
}
if (errorfds && FD_ISSET(i, &errorfds_h))
FD_SET(trans_map[i], errorfds);
}
if (fds_read_ptr)
rd_t.copyOut(tc->getVirtProxy());
if (fds_writ_ptr)
wr_t.copyOut(tc->getVirtProxy());
if (fds_excp_ptr)
ex_t.copyOut(tc->getVirtProxy());
if (time_val_ptr)
tp.copyOut(tc->getVirtProxy());
return retval;
}