]> git.lizzy.rs Git - rust.git/commitdiff
Correct fcntl behavior
authorChristian Poveda <christianpoveda@protonmail.com>
Sun, 13 Oct 2019 01:12:26 +0000 (20:12 -0500)
committerChristian Poveda <christianpoveda@protonmail.com>
Sun, 13 Oct 2019 01:12:26 +0000 (20:12 -0500)
src/shims/fs.rs

index 443a61c46e9aa23b9da599375fee5dad5516488c..4d93ca4fd31b785cc23168451126f67ae88acd6a 100644 (file)
@@ -9,7 +9,6 @@
 
 pub struct FileHandle {
     file: File,
-    flag: i32,
 }
 
 pub struct FileHandler {
@@ -79,13 +78,14 @@ fn open(
         }
         let o_cloexec = this.eval_libc_i32("O_CLOEXEC")?;
         if flag & o_cloexec != 0 {
-            // This flag is a noop for now because `std` already sets it.
+            // We do not need to do anything for this flag because `std` already sets it.
+            // (Technically we do not support *not* setting this flag, but we ignore that.)
             mirror |= o_cloexec;
         }
         // If `flag` is not equal to `mirror`, there is an unsupported option enabled in `flag`,
         // then we throw an error.
         if flag != mirror {
-            throw_unsup_format!("unsupported flags {:#x}", flag);
+            throw_unsup_format!("unsupported flags {:#x}", flag & !mirror);
         }
 
         let path_bytes = this
@@ -97,7 +97,7 @@ fn open(
         let fd = options.open(path).map(|file| {
             let mut fh = &mut this.machine.file_handler;
             fh.low += 1;
-            fh.handles.insert(fh.low, FileHandle { file, flag });
+            fh.handles.insert(fh.low, FileHandle { file });
             fh.low
         });
 
@@ -108,7 +108,7 @@ fn fcntl(
         &mut self,
         fd_op: OpTy<'tcx, Tag>,
         cmd_op: OpTy<'tcx, Tag>,
-        _arg_op: Option<OpTy<'tcx, Tag>>,
+        _arg1_op: Option<OpTy<'tcx, Tag>>,
     ) -> InterpResult<'tcx, i32> {
         let this = self.eval_context_mut();
 
@@ -120,7 +120,12 @@ fn fcntl(
         let cmd = this.read_scalar(cmd_op)?.to_i32()?;
         // We only support getting the flags for a descriptor
         if cmd == this.eval_libc_i32("F_GETFD")? {
-            this.get_handle_and(fd, |handle| Ok(handle.flag))
+            // Currently this is the only flag that `F_GETFD` returns. It is OK to just return the
+            // `FD_CLOEXEC` value without checking if the flag is set for the file because `std`
+            // always sets this flag when opening a file. However we still need to check that the
+            // file itself is open.
+            this.get_handle_and(fd, |_| Ok(0))?;
+            this.eval_libc_i32("FD_CLOEXEC")
         } else {
             throw_unsup_format!("The {:#x} command is not supported for `fcntl`)", cmd);
         }