summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.cc
diff options
context:
space:
mode:
authorBrandon Potter <brandon.potter@amd.com>2015-07-20 09:15:21 -0500
committerBrandon Potter <brandon.potter@amd.com>2015-07-20 09:15:21 -0500
commit6f549419ebf588986daa99135c7cdb1b11002b56 (patch)
tree01746b0d343c40ae8fe24194f01307c5399694c7 /src/sim/syscall_emul.cc
parent748b87fc368800495e5906428bf748359d6bf19a (diff)
downloadgem5-6f549419ebf588986daa99135c7cdb1b11002b56.tar.xz
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.
Diffstat (limited to 'src/sim/syscall_emul.cc')
-rw-r--r--src/sim/syscall_emul.cc49
1 files changed, 24 insertions, 25 deletions
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index f4bfca6c2..281e4c021 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -620,47 +620,46 @@ dupFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
return (result == -1) ? -local_errno : p->fds->allocFD(new_fdep);
}
-
SyscallReturn
fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{
+ int arg;
int index = 0;
int tgt_fd = p->getSyscallArg(tc, index);
+ int cmd = p->getSyscallArg(tc, index);
auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
if (!hbfdp)
return -EBADF;
int sim_fd = hbfdp->getSimFD();
- int cmd = p->getSyscallArg(tc, index);
- switch (cmd) {
- case 0: // F_DUPFD
- // if we really wanted to support this, we'd need to do it
- // 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 2: // F_SETFD (set close-on-exec flag)
- return 0;
+ int coe = hbfdp->getCOE();
- case 3: // F_GETFL (get file flags)
- case 4: // F_SETFL (set file flags)
- // not sure if this is totally valid, but we'll pass it through
- // to the underlying OS
- warn("fcntl(%d, %d) passed through to host\n", tgt_fd, cmd);
- return fcntl(sim_fd, cmd);
- // return 0;
+ switch (cmd) {
+ case F_GETFD:
+ return coe & FD_CLOEXEC;
- case 7: // F_GETLK (get lock)
- case 8: // F_SETLK (set lock)
- case 9: // F_SETLKW (set lock and wait)
- // don't mess with file locking... just act like it's OK
- warn("File lock call (fcntl(%d, %d)) ignored.\n", tgt_fd, cmd);
+ case F_SETFD: {
+ arg = p->getSyscallArg(tc, index);
+ arg ? hbfdp->setCOE(true) : hbfdp->setCOE(false);
return 0;
+ }
+
+ // Rely on the host to maintain the file status flags for this file
+ // description rather than maintain it ourselves. Admittedly, this
+ // is suboptimal (and possibly error prone), but it is difficult to
+ // maintain the flags by tracking them across the different descriptors
+ // (that refer to this file description) caused by clone, dup, and
+ // subsequent fcntls.
+ case F_GETFL:
+ case F_SETFL: {
+ arg = p->getSyscallArg(tc, index);
+ int rv = fcntl(sim_fd, cmd, arg);
+ return (rv == -1) ? -errno : rv;
+ }
default:
- warn("Unknown fcntl command %d\n", cmd);
+ warn("fcntl: unsupported command %d\n", cmd);
return 0;
}
}