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
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
case linux.F_SETFD:
|
||||
flags := args[2].Uint()
|
||||
t.FDTable().SetFlags(fd, kernel.FDFlags{
|
||||
err := t.FDTable().SetFlags(fd, kernel.FDFlags{
|
||||
CloseOnExec: flags&linux.FD_CLOEXEC != 0,
|
||||
})
|
||||
return 0, nil, nil
|
||||
return 0, nil, err
|
||||
case linux.F_GETFL:
|
||||
return uintptr(file.Flags().ToLinux()), nil, nil
|
||||
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
|
||||
case linux.F_SETFD:
|
||||
flags := args[2].Uint()
|
||||
t.FDTable().SetFlags(fd, kernel.FDFlags{
|
||||
err := t.FDTable().SetFlagsVFS2(fd, kernel.FDFlags{
|
||||
CloseOnExec: flags&linux.FD_CLOEXEC != 0,
|
||||
})
|
||||
return 0, nil, nil
|
||||
return 0, nil, err
|
||||
case linux.F_GETFL:
|
||||
return uintptr(file.StatusFlags()), nil, nil
|
||||
case linux.F_SETFL:
|
||||
|
|
|
@ -115,6 +115,15 @@ PosixErrorOr<Cleanup> SubprocessLock(std::string const& path, bool for_write,
|
|||
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) {
|
||||
// Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set.
|
||||
FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
|
||||
|
|
Loading…
Reference in New Issue