Add FIONREAD to host file description

Closes #8544

PiperOrigin-RevId: 535456427
This commit is contained in:
Fabricio Voznika
2023-05-25 18:25:42 -07:00
committed by gVisor bot
parent e672476d06
commit 919cfd12bd
3 changed files with 59 additions and 1 deletions
+21
View File
@@ -14,12 +14,17 @@
#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <unistd.h>
// Flag to indicate that TTY is being used in the container.
static int tty = 0;
// Tests that FIONREAD is supported with host FD.
void testFionread() {
int size = 0;
@@ -34,6 +39,10 @@ void testFionread() {
// Docker maps stdin to /dev/null which doesn't support epoll. Check that error
// is correctly propagated.
void testEpoll() {
if (tty) {
// stdin is not /dev/null when TTY is used for the container.
return;
}
int fd = epoll_create(1);
if (fd < 0) {
err(1, "epoll_create");
@@ -67,6 +76,18 @@ void testSelect() {
}
int main(int argc, char** argv) {
int opt;
while ((opt = getopt(argc, argv, "t")) != -1) {
switch (opt) {
case 't':
tty = 1;
break;
default:
fprintf(stderr, "Usage: %s [-t]\n", argv[0]);
return 1;
}
}
testFionread();
testEpoll();
testSelect();
+12
View File
@@ -18,6 +18,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/marshal/primitive"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
@@ -154,6 +155,17 @@ func (t *TTYFileDescription) Ioctl(ctx context.Context, io usermem.IO, sysno uin
fd := t.inode.hostFD
ioctl := args[1].Uint64()
switch ioctl {
case linux.FIONREAD:
v, err := ioctlFionread(fd)
if err != nil {
return 0, err
}
var buf [4]byte
hostarch.ByteOrder.PutUint32(buf[:], v)
_, err = io.CopyOut(ctx, args[2].Pointer(), buf[:], usermem.IOOpts{})
return 0, err
case linux.TCGETS:
termios, err := ioctlGetTermios(fd)
if err != nil {
+26 -1
View File
@@ -533,7 +533,32 @@ func TestStickyDir(t *testing.T) {
}
func TestHostFD(t *testing.T) {
runIntegrationTest(t, nil, "./host_fd")
t.Run("regular", func(t *testing.T) {
runIntegrationTest(t, nil, "./host_fd")
})
t.Run("tty", func(t *testing.T) {
ctx := context.Background()
d := dockerutil.MakeContainer(ctx, t)
defer d.CleanUp(ctx)
// Start the container with an attached PTY.
p, err := d.SpawnProcess(ctx, dockerutil.RunOpts{
Image: "basic/integrationtest",
WorkDir: "/root",
}, "./host_fd", "-t")
if err != nil {
t.Fatalf("docker run failed: %v", err)
}
if err := d.Wait(ctx); err != nil {
t.Fatalf("Wait failed: %v", err)
}
if out, err := p.Logs(); err != nil {
t.Fatal(err)
} else if len(out) > 0 {
t.Errorf("test failed:\n%s", out)
}
})
}
func runIntegrationTest(t *testing.T, capAdd []string, args ...string) {