vfs2: implement fcntl(fd, F_SETFL, flags)
PiperOrigin-RevId: 316148074
This commit is contained in:
parent
61d6c059ac
commit
6ec9d60403
|
@ -458,6 +458,29 @@ func (f *FDTable) SetFlags(fd int32, flags FDFlags) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFlagsVFS2 sets the flags for the given file descriptor.
|
||||||
|
//
|
||||||
|
// True is returned iff flags were changed.
|
||||||
|
func (f *FDTable) SetFlagsVFS2(fd int32, flags FDFlags) error {
|
||||||
|
if fd < 0 {
|
||||||
|
// Don't accept negative FDs.
|
||||||
|
return syscall.EBADF
|
||||||
|
}
|
||||||
|
|
||||||
|
f.mu.Lock()
|
||||||
|
defer f.mu.Unlock()
|
||||||
|
|
||||||
|
file, _, _ := f.getVFS2(fd)
|
||||||
|
if file == nil {
|
||||||
|
// No file found.
|
||||||
|
return syscall.EBADF
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the flags.
|
||||||
|
f.setVFS2(fd, file, flags)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Get returns a reference to the file and the flags for the FD or nil if no
|
// Get returns a reference to the file and the flags for the FD or nil if no
|
||||||
// file is defined for the given fd.
|
// file is defined for the given fd.
|
||||||
//
|
//
|
||||||
|
|
|
@ -935,10 +935,10 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
|
||||||
return uintptr(flags.ToLinuxFDFlags()), nil, nil
|
return uintptr(flags.ToLinuxFDFlags()), nil, nil
|
||||||
case linux.F_SETFD:
|
case linux.F_SETFD:
|
||||||
flags := args[2].Uint()
|
flags := args[2].Uint()
|
||||||
t.FDTable().SetFlags(fd, kernel.FDFlags{
|
err := t.FDTable().SetFlags(fd, kernel.FDFlags{
|
||||||
CloseOnExec: flags&linux.FD_CLOEXEC != 0,
|
CloseOnExec: flags&linux.FD_CLOEXEC != 0,
|
||||||
})
|
})
|
||||||
return 0, nil, nil
|
return 0, nil, err
|
||||||
case linux.F_GETFL:
|
case linux.F_GETFL:
|
||||||
return uintptr(file.Flags().ToLinux()), nil, nil
|
return uintptr(file.Flags().ToLinux()), nil, nil
|
||||||
case linux.F_SETFL:
|
case linux.F_SETFL:
|
||||||
|
|
|
@ -134,10 +134,10 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
|
||||||
return uintptr(flags.ToLinuxFDFlags()), nil, nil
|
return uintptr(flags.ToLinuxFDFlags()), nil, nil
|
||||||
case linux.F_SETFD:
|
case linux.F_SETFD:
|
||||||
flags := args[2].Uint()
|
flags := args[2].Uint()
|
||||||
t.FDTable().SetFlags(fd, kernel.FDFlags{
|
err := t.FDTable().SetFlagsVFS2(fd, kernel.FDFlags{
|
||||||
CloseOnExec: flags&linux.FD_CLOEXEC != 0,
|
CloseOnExec: flags&linux.FD_CLOEXEC != 0,
|
||||||
})
|
})
|
||||||
return 0, nil, nil
|
return 0, nil, err
|
||||||
case linux.F_GETFL:
|
case linux.F_GETFL:
|
||||||
return uintptr(file.StatusFlags()), nil, nil
|
return uintptr(file.StatusFlags()), nil, nil
|
||||||
case linux.F_SETFL:
|
case linux.F_SETFL:
|
||||||
|
|
|
@ -115,6 +115,15 @@ PosixErrorOr<Cleanup> SubprocessLock(std::string const& path, bool for_write,
|
||||||
return std::move(cleanup);
|
return std::move(cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FcntlTest, SetCloExecBadFD) {
|
||||||
|
// Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set.
|
||||||
|
FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
|
||||||
|
auto fd = f.get();
|
||||||
|
f.reset();
|
||||||
|
ASSERT_THAT(fcntl(fd, F_GETFD), SyscallFailsWithErrno(EBADF));
|
||||||
|
ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), SyscallFailsWithErrno(EBADF));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FcntlTest, SetCloExec) {
|
TEST(FcntlTest, SetCloExec) {
|
||||||
// Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set.
|
// Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set.
|
||||||
FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
|
FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
|
||||||
|
|
Loading…
Reference in New Issue