Skip to content

Commit 1bf5796

Browse files
benburkerttklauser
authored andcommitted
internal/poll: fall back on unsupported splice from unix socket
Gracefully fallback to a userspace copy when the kernel does not support splice(2) on a unix domain socket. EINVAL is returned by the splice syscall if it does not support unix domain sockets. Keeping the handled return value as false when the first splice call fails with EINVAL will cause the caller to fall back to a userspace copy. Fixes #27513 Change-Id: I4b10c1900ba3c096cb32edb7c8a6044f468efb52 Reviewed-on: https://go-review.googlesource.com/133575 Run-TryBot: Tobias Klauser <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Tobias Klauser <[email protected]>
1 parent 58c6afe commit 1bf5796

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

src/internal/poll/splice_linux.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,19 @@ func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string,
3232
return 0, false, sc, err
3333
}
3434
defer destroyTempPipe(prfd, pwfd)
35-
// From here on, the operation should be considered handled,
36-
// even if Splice doesn't transfer any data.
3735
var inPipe, n int
3836
for err == nil && remain > 0 {
3937
max := maxSpliceSize
4038
if int64(max) > remain {
4139
max = int(remain)
4240
}
4341
inPipe, err = spliceDrain(pwfd, src, max)
42+
// the operation is considered handled if splice returns no error, or
43+
// an error other than EINVAL. An EINVAL means the kernel does not
44+
// support splice for the socket type of dst and/or src. The failed
45+
// syscall does not consume any data so it is safe to fall back to a
46+
// generic copy.
47+
handled = handled || (err != syscall.EINVAL)
4448
// spliceDrain should never return EAGAIN, so if err != nil,
4549
// Splice cannot continue. If inPipe == 0 && err == nil,
4650
// src is at EOF, and the transfer is complete.
@@ -54,7 +58,7 @@ func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string,
5458
}
5559
}
5660
if err != nil {
57-
return written, true, "splice", err
61+
return written, handled, "splice", err
5862
}
5963
return written, true, "", nil
6064
}

0 commit comments

Comments
 (0)