diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index 6197b8d45..443f70d81 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -97,18 +97,35 @@ class AlphaLinux : public Linux //@{ /// ioctl() command codes. - static const unsigned TIOCGETP_ = 0x40067408; - static const unsigned TIOCSETP_ = 0x80067409; - static const unsigned TIOCSETN_ = 0x8006740a; - static const unsigned TIOCSETC_ = 0x80067411; - static const unsigned TIOCGETC_ = 0x40067412; - static const unsigned FIONREAD_ = 0x4004667f; - static const unsigned TIOCISATTY_ = 0x2000745e; - static const unsigned TIOCGETS_ = 0x402c7413; - static const unsigned TIOCGETA_ = 0x40127417; - static const unsigned TCSETAW_ = 0x80147419; // 2.6.15 kernel + static const unsigned TGT_TIOCGETP = 0x40067408; + static const unsigned TGT_TIOCSETP = 0x80067409; + static const unsigned TGT_TIOCSETN = 0x8006740a; + static const unsigned TGT_TIOCSETC = 0x80067411; + static const unsigned TGT_TIOCGETC = 0x40067412; + static const unsigned TGT_FIONREAD = 0x4004667f; + static const unsigned TGT_TCGETS = 0x402c7413; + static const unsigned TGT_TCGETA = 0x40127417; + static const unsigned TGT_TCSETAW = 0x80147419; // 2.6.15 kernel //@} + static bool + isTtyReq(unsigned req) + { + switch (req) { + case TGT_TIOCGETP: + case TGT_TIOCSETP: + case TGT_TIOCSETN: + case TGT_TIOCSETC: + case TGT_TIOCGETC: + case TGT_TCGETS: + case TGT_TCGETA: + case TGT_TCSETAW: + return true; + default: + return false; + } + } + /// For table(). static const int TBL_SYSINFO = 12; diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index f0cad8289..5751da8d4 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -91,18 +91,38 @@ class AlphaTru64 : public Tru64 //@{ /// ioctl() command codes. - static const unsigned TIOCGETP_ = 0x40067408; - static const unsigned TIOCSETP_ = 0x80067409; - static const unsigned TIOCSETN_ = 0x8006740a; - static const unsigned TIOCSETC_ = 0x80067411; - static const unsigned TIOCGETC_ = 0x40067412; - static const unsigned FIONREAD_ = 0x4004667f; - static const unsigned TIOCISATTY_ = 0x2000745e; - static const unsigned TIOCGETS_ = 0x402c7413; - static const unsigned TIOCGETA_ = 0x40127417; - static const unsigned TCSETAW_ = 0x80147419; + static const unsigned TGT_TIOCGETP = 0x40067408; + static const unsigned TGT_TIOCSETP = 0x80067409; + static const unsigned TGT_TIOCSETN = 0x8006740a; + static const unsigned TGT_TIOCSETC = 0x80067411; + static const unsigned TGT_TIOCGETC = 0x40067412; + static const unsigned TGT_FIONREAD = 0x4004667f; + static const unsigned TGT_TIOCISATTY = 0x2000745e; + static const unsigned TGT_TCGETS = 0x402c7413; + static const unsigned TGT_TCGETA = 0x40127417; + static const unsigned TGT_TCSETAW = 0x80147419; // 2.6.15 kernel //@} + static bool + isTtyReq(unsigned req) + { + switch (req) { + case TGT_TIOCGETP: + case TGT_TIOCSETP: + case TGT_TIOCSETN: + case TGT_TIOCSETC: + case TGT_TIOCGETC: + case TGT_FIONREAD: + case TGT_TIOCISATTY: + case TGT_TCGETS: + case TGT_TCGETA: + case TGT_TCSETAW: + return true; + default: + return false; + } + } + //@{ /// For table(). static const int TBL_SYSINFO = 12; diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index 40d586aaf..55af574d3 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -100,20 +100,6 @@ class ArmLinux : public Linux static const int TGT_RUSAGE_BOTH = -2; //@} - //@{ - /// ioctl() command codes. - static const unsigned TIOCGETP_ = 0x5401; - static const unsigned TIOCSETP_ = 0x80067409; - static const unsigned TIOCSETN_ = 0x8006740a; - static const unsigned TIOCSETC_ = 0x80067411; - static const unsigned TIOCGETC_ = 0x40067412; - static const unsigned FIONREAD_ = 0x4004667f; - static const unsigned TIOCISATTY_ = 0x2000745e; - static const unsigned TIOCGETS_ = 0x402c7413; - static const unsigned TIOCGETA_ = 0x5405; - static const unsigned TCSETAW_ = 0x5407; // 2.6.15 kernel - //@} - /// For table(). static const int TBL_SYSINFO = 12; diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index 949cce8aa..85a647e3d 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -92,18 +92,32 @@ class MipsLinux : public Linux //@{ /// ioctl() command codes. - static const unsigned TIOCGETP_ = 0x7408; - static const unsigned TIOCSETP_ = 0x7409; - static const unsigned TIOCSETN_ = 0x740a; - static const unsigned TIOCSETC_ = 0x7411; - static const unsigned TIOCGETC_ = 0x7412; - static const unsigned FIONREAD_ = 0x467f; - static const unsigned TIOCISATTY_ = 0x5480; - static const unsigned TIOCGETS_ = 0x540d; - static const unsigned TIOCGETA_ = 0x7417; - static const unsigned TCSETAW_ = 0x5403; // 2.6.15 kernel + static const unsigned TGT_TCGETA = 0x5401; + static const unsigned TGT_TCSETAW = 0x5403; + static const unsigned TGT_TCGETS = 0x540d; + static const unsigned TGT_FIONREAD = 0x467f; + static const unsigned TGT_TIOCGETP = 0x7408; + static const unsigned TGT_TIOCSETP = 0x7409; + static const unsigned TGT_TIOCSETN = 0x740a; //@} + static bool + isTtyReq(unsigned req) + { + switch (req) { + case TGT_TIOCGETP: + case TGT_TIOCSETP: + case TGT_TIOCSETN: + case TGT_FIONREAD: + case TGT_TCGETS: + case TGT_TCGETA: + case TGT_TCSETAW: + return true; + default: + return false; + } + } + /// For table(). static const int TBL_SYSINFO = 12; diff --git a/src/arch/power/linux/linux.hh b/src/arch/power/linux/linux.hh index 45ca048a0..effb39277 100644 --- a/src/arch/power/linux/linux.hh +++ b/src/arch/power/linux/linux.hh @@ -131,19 +131,34 @@ class PowerLinux : public Linux //@{ /// ioctl() command codes. - /// These are for the 2.6.15 kernel. Some have changed for - /// later versions. - static const unsigned TIOCGETP_ = 0x40067408; - static const unsigned TIOCSETP_ = 0x80067409; - static const unsigned TIOCSETN_ = 0x8006740a; - static const unsigned TIOCSETC_ = 0x80067411; - static const unsigned TIOCGETC_ = 0x40067412; - static const unsigned FIONREAD_ = 0x4004667f; - static const unsigned TIOCISATTY_ = 0x2000745e; - static const unsigned TIOCGETS_ = 0x402c7413; - static const unsigned TIOCGETA_ = 0x40147417; - static const unsigned TCSETAW_ = 0x80147419; + static const unsigned TGT_TIOCGETP = 0x40067408; + static const unsigned TGT_TIOCSETP = 0x80067409; + static const unsigned TGT_TIOCSETN = 0x8006740a; + static const unsigned TGT_TIOCSETC = 0x80067411; + static const unsigned TGT_TIOCGETC = 0x40067412; + static const unsigned TGT_FIONREAD = 0x4004667f; + static const unsigned TGT_TCGETS = 0x402c7413; + static const unsigned TGT_TCGETA = 0x40127417; + static const unsigned TGT_TCSETAW = 0x80147419; // 2.6.15 kernel //@} + + static bool + isTtyReq(unsigned req) + { + switch (req) { + case TGT_TIOCGETP: + case TGT_TIOCSETP: + case TGT_TIOCSETN: + case TGT_TIOCSETC: + case TGT_TIOCGETC: + case TGT_TCGETS: + case TGT_TCGETA: + case TGT_TCSETAW: + return true; + default: + return false; + } + } }; #endif // __ARCH_POWER_LINUX_LINUX_HH__ diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index 8ac408812..7b708cbcb 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -94,6 +94,35 @@ class SparcLinux : public Linux uint64_t mem_unit; /* Memory unit size in bytes */ } tgt_sysinfo; + //@{ + /// ioctl() command codes. + /// These were calculated using the SPARC Linux headers on an x86 + /// machine and thus may not be correct. It would be good to + /// verify/update these values on an actual SPARC Linux machine. + static const unsigned TGT_TCGETA = 0x40125401; + static const unsigned TGT_TCSETAW = 0x80125403; + static const unsigned TGT_TCGETS = 0x40385408; + static const unsigned TGT_FIONREAD = 0x4004667f; + static const unsigned TGT_TIOCGETP = 0x40067408; + static const unsigned TGT_TIOCSETP = 0x80067409; + static const unsigned TGT_TIOCSETN = 0x8006740a; + //@} + + static bool + isTtyReq(unsigned req) + { + switch (req) { + case TGT_TIOCGETP: + case TGT_TIOCSETP: + case TGT_TIOCSETN: + case TGT_TCGETS: + case TGT_TCGETA: + case TGT_TCSETAW: + return true; + default: + return false; + } + } }; class Sparc32Linux : public SparcLinux diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index e9322f5eb..322868ee1 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -229,7 +229,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 13 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 14 */ SyscallDesc("rt_sigprocmask", ignoreFunc), /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc), - /* 16 */ SyscallDesc("ioctl", unimplementedFunc), + /* 16 */ SyscallDesc("ioctl", ioctlFunc), /* 17 */ SyscallDesc("pread64", unimplementedFunc), /* 18 */ SyscallDesc("pwrite64", unimplementedFunc), /* 19 */ SyscallDesc("readv", unimplementedFunc), @@ -546,7 +546,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc), - /* 54 */ SyscallDesc("ioctl", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), /* 55 */ SyscallDesc("fcntl", unimplementedFunc), /* 56 */ SyscallDesc("mpx", unimplementedFunc), /* 57 */ SyscallDesc("setpgid", unimplementedFunc), diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 5721e5a58..bc3da60e4 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -147,6 +147,32 @@ class Linux : public OperatingSystem uint64_t iov_len; }; + //@{ + /// ioctl() command codes. + static const unsigned TGT_TCGETS = 0x5401; + static const unsigned TGT_TCGETA = 0x5405; + static const unsigned TGT_TCSETAW = 0x5407; + static const unsigned TGT_FIONREAD = 0x541B; + //@} + + /// Return true for the ioctl codes for which we return ENOTTY + /// *without* printing a warning, since we know that ENOTTY is the + /// correct thing to return (and not just a sign that we don't + /// recognize the ioctl code. + static bool + isTtyReq(unsigned req) + { + switch (req) { + case TGT_FIONREAD: + case TGT_TCSETAW: + case TGT_TCGETS: + case TGT_TCGETA: + return true; + default: + return false; + } + } + /// For getrusage(). struct rusage { diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index c174fde57..0627d8d91 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -567,7 +567,8 @@ copyOutStat64Buf(SETranslatingPortProxy &mem, Addr addr, /// Target ioctl() handler. For the most part, programs call ioctl() /// only to find out if their stdout is a tty, to determine whether to -/// do line or block buffering. +/// do line or block buffering. We always claim that output fds are +/// not TTYs to provide repeatable results. template SyscallReturn ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, @@ -584,22 +585,13 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return -EBADF; } - switch (req) { - case OS::TIOCISATTY_: - case OS::TIOCGETP_: - case OS::TIOCSETP_: - case OS::TIOCSETN_: - case OS::TIOCSETC_: - case OS::TIOCGETC_: - case OS::TIOCGETS_: - case OS::TIOCGETA_: - case OS::TCSETAW_: + if (OS::isTtyReq(req)) { return -ENOTTY; - - default: - fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ \n", - fd, req, tc->pcState()); } + + warn("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ \n", + fd, req, tc->pcState()); + return -ENOTTY; } /// Target open() handler.