syscall_emul: [patch 11/22] extend functionality of fcntl

This changeset adds the ability to set a close-on-exec flag for a given
file descriptor. It also reworks some of the logic surrounding setting and
retrieving flags from the file description.
This commit is contained in:
Brandon Potter 2015-07-20 09:15:21 -05:00
parent 748b87fc36
commit 6f549419eb
3 changed files with 25 additions and 26 deletions

View file

@ -598,7 +598,7 @@ static SyscallDesc syscallDescs32[] = {
/* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 52 */ SyscallDesc("umount2", unimplementedFunc),
/* 53 */ SyscallDesc("lock", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<X86Linux32>), /* 54 */ SyscallDesc("ioctl", ioctlFunc<X86Linux32>),
/* 55 */ SyscallDesc("fcntl", unimplementedFunc), /* 55 */ SyscallDesc("fcntl", fcntlFunc),
/* 56 */ SyscallDesc("mpx", unimplementedFunc), /* 56 */ SyscallDesc("mpx", unimplementedFunc),
/* 57 */ SyscallDesc("setpgid", unimplementedFunc), /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
/* 58 */ SyscallDesc("ulimit", unimplementedFunc), /* 58 */ SyscallDesc("ulimit", unimplementedFunc),

View file

@ -620,47 +620,46 @@ dupFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
return (result == -1) ? -local_errno : p->fds->allocFD(new_fdep); return (result == -1) ? -local_errno : p->fds->allocFD(new_fdep);
} }
SyscallReturn SyscallReturn
fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{ {
int arg;
int index = 0; int index = 0;
int tgt_fd = p->getSyscallArg(tc, index); int tgt_fd = p->getSyscallArg(tc, index);
int cmd = p->getSyscallArg(tc, index);
auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]); auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
if (!hbfdp) if (!hbfdp)
return -EBADF; return -EBADF;
int sim_fd = hbfdp->getSimFD(); int sim_fd = hbfdp->getSimFD();
int cmd = p->getSyscallArg(tc, index); int coe = hbfdp->getCOE();
switch (cmd) { switch (cmd) {
case 0: // F_DUPFD case F_GETFD:
// if we really wanted to support this, we'd need to do it return coe & FD_CLOEXEC;
// in the target fd space.
warn("fcntl(%d, F_DUPFD) not supported, error returned\n", tgt_fd);
return -EMFILE;
case 1: // F_GETFD (get close-on-exec flag) case F_SETFD: {
case 2: // F_SETFD (set close-on-exec flag) arg = p->getSyscallArg(tc, index);
arg ? hbfdp->setCOE(true) : hbfdp->setCOE(false);
return 0; return 0;
}
case 3: // F_GETFL (get file flags) // Rely on the host to maintain the file status flags for this file
case 4: // F_SETFL (set file flags) // description rather than maintain it ourselves. Admittedly, this
// not sure if this is totally valid, but we'll pass it through // is suboptimal (and possibly error prone), but it is difficult to
// to the underlying OS // maintain the flags by tracking them across the different descriptors
warn("fcntl(%d, %d) passed through to host\n", tgt_fd, cmd); // (that refer to this file description) caused by clone, dup, and
return fcntl(sim_fd, cmd); // subsequent fcntls.
// return 0; case F_GETFL:
case F_SETFL: {
case 7: // F_GETLK (get lock) arg = p->getSyscallArg(tc, index);
case 8: // F_SETLK (set lock) int rv = fcntl(sim_fd, cmd, arg);
case 9: // F_SETLKW (set lock and wait) return (rv == -1) ? -errno : rv;
// don't mess with file locking... just act like it's OK }
warn("File lock call (fcntl(%d, %d)) ignored.\n", tgt_fd, cmd);
return 0;
default: default:
warn("Unknown fcntl command %d\n", cmd); warn("fcntl: unsupported command %d\n", cmd);
return 0; return 0;
} }
} }

View file

@ -230,7 +230,7 @@ SyscallReturn fchownFunc(SyscallDesc *desc, int num,
SyscallReturn dupFunc(SyscallDesc *desc, int num, SyscallReturn dupFunc(SyscallDesc *desc, int num,
Process *process, ThreadContext *tc); Process *process, ThreadContext *tc);
/// Target fnctl() handler. /// Target fcntl() handler.
SyscallReturn fcntlFunc(SyscallDesc *desc, int num, SyscallReturn fcntlFunc(SyscallDesc *desc, int num,
Process *process, ThreadContext *tc); Process *process, ThreadContext *tc);