mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add FIONREAD to host file description
Closes #8544 PiperOrigin-RevId: 535456427
This commit is contained in:
committed by
gVisor bot
parent
e672476d06
commit
919cfd12bd
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user