authorgravatar for lauri@hacktheplanet.fiLauri Tirkkonen <lauri@hacktheplanet.fi> 2023-07-27 22:31:51+09:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-11-26 21:35:36-05:00
log19af8aac82510d9adc35fa11db9c57676d4abd23
tree9d14d2b31884f43fb714e951e03e26d76e3d1ca8
parent280140595fcfe9676ed32a7906eb7958a4c595b1

os: expect ETIMEDOUT, ECONNRESET, ENOTCONN from recvfrom & read family

reads on eg. connected TCP sockets can fail with ETIMEDOUT, and ENOTCONN happens eg. if you try to read a TCP socket that has not been connected yet. interestingly read() was already handling CONNRESET & TIMEDOUT, but readv(), pread(), and preadv() were somewhat inconsistent.

4 files changed, 24 insertions(+), 0 deletions(-)

lib/std/os.zig+21
......@@ -686,6 +686,7 @@ pub const ReadError = error{
686686 ConnectionResetByPeer,
687687 ConnectionTimedOut,
688688 NotOpenForReading,
689 SocketNotConnected,
689690
690691 // Windows only
691692 NetNameDeleted,
......@@ -732,6 +733,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
732733 .ISDIR => return error.IsDir,
733734 .NOBUFS => return error.SystemResources,
734735 .NOMEM => return error.SystemResources,
736 .NOTCONN => return error.SocketNotConnected,
735737 .CONNRESET => return error.ConnectionResetByPeer,
736738 .TIMEDOUT => return error.ConnectionTimedOut,
737739 .NOTCAPABLE => return error.AccessDenied,
......@@ -760,6 +762,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
760762 .ISDIR => return error.IsDir,
761763 .NOBUFS => return error.SystemResources,
762764 .NOMEM => return error.SystemResources,
765 .NOTCONN => return error.SocketNotConnected,
763766 .CONNRESET => return error.ConnectionResetByPeer,
764767 .TIMEDOUT => return error.ConnectionTimedOut,
765768 else => |err| return unexpectedErrno(err),
......@@ -800,6 +803,9 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
800803 .ISDIR => return error.IsDir,
801804 .NOBUFS => return error.SystemResources,
802805 .NOMEM => return error.SystemResources,
806 .NOTCONN => return error.SocketNotConnected,
807 .CONNRESET => return error.ConnectionResetByPeer,
808 .TIMEDOUT => return error.ConnectionTimedOut,
803809 .NOTCAPABLE => return error.AccessDenied,
804810 else => |err| return unexpectedErrno(err),
805811 }
......@@ -819,7 +825,9 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
819825 .ISDIR => return error.IsDir,
820826 .NOBUFS => return error.SystemResources,
821827 .NOMEM => return error.SystemResources,
828 .NOTCONN => return error.SocketNotConnected,
822829 .CONNRESET => return error.ConnectionResetByPeer,
830 .TIMEDOUT => return error.ConnectionTimedOut,
823831 else => |err| return unexpectedErrno(err),
824832 }
825833 }
......@@ -864,7 +872,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
864872 .ISDIR => return error.IsDir,
865873 .NOBUFS => return error.SystemResources,
866874 .NOMEM => return error.SystemResources,
875 .NOTCONN => return error.SocketNotConnected,
867876 .CONNRESET => return error.ConnectionResetByPeer,
877 .TIMEDOUT => return error.ConnectionTimedOut,
868878 .NXIO => return error.Unseekable,
869879 .SPIPE => return error.Unseekable,
870880 .OVERFLOW => return error.Unseekable,
......@@ -897,7 +907,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
897907 .ISDIR => return error.IsDir,
898908 .NOBUFS => return error.SystemResources,
899909 .NOMEM => return error.SystemResources,
910 .NOTCONN => return error.SocketNotConnected,
900911 .CONNRESET => return error.ConnectionResetByPeer,
912 .TIMEDOUT => return error.ConnectionTimedOut,
901913 .NXIO => return error.Unseekable,
902914 .SPIPE => return error.Unseekable,
903915 .OVERFLOW => return error.Unseekable,
......@@ -1009,6 +1021,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
10091021 .ISDIR => return error.IsDir,
10101022 .NOBUFS => return error.SystemResources,
10111023 .NOMEM => return error.SystemResources,
1024 .NOTCONN => return error.SocketNotConnected,
1025 .CONNRESET => return error.ConnectionResetByPeer,
1026 .TIMEDOUT => return error.ConnectionTimedOut,
10121027 .NXIO => return error.Unseekable,
10131028 .SPIPE => return error.Unseekable,
10141029 .OVERFLOW => return error.Unseekable,
......@@ -1035,6 +1050,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
10351050 .ISDIR => return error.IsDir,
10361051 .NOBUFS => return error.SystemResources,
10371052 .NOMEM => return error.SystemResources,
1053 .NOTCONN => return error.SocketNotConnected,
1054 .CONNRESET => return error.ConnectionResetByPeer,
1055 .TIMEDOUT => return error.ConnectionTimedOut,
10381056 .NXIO => return error.Unseekable,
10391057 .SPIPE => return error.Unseekable,
10401058 .OVERFLOW => return error.Unseekable,
......@@ -6624,6 +6642,7 @@ pub const RecvFromError = error{
66246642 SystemResources,
66256643
66266644 ConnectionResetByPeer,
6645 ConnectionTimedOut,
66276646
66286647 /// The socket has not been bound.
66296648 SocketNotBound,
......@@ -6663,6 +6682,7 @@ pub fn recvfrom(
66636682 .WSAENETDOWN => return error.NetworkSubsystemFailed,
66646683 .WSAENOTCONN => return error.SocketNotConnected,
66656684 .WSAEWOULDBLOCK => return error.WouldBlock,
6685 .WSAETIMEDOUT => return error.ConnectionTimedOut,
66666686 // TODO: handle more errors
66676687 else => |err| return windows.unexpectedWSAError(err),
66686688 }
......@@ -6682,6 +6702,7 @@ pub fn recvfrom(
66826702 .NOMEM => return error.SystemResources,
66836703 .CONNREFUSED => return error.ConnectionRefused,
66846704 .CONNRESET => return error.ConnectionResetByPeer,
6705 .TIMEDOUT => return error.ConnectionTimedOut,
66856706 else => |err| return unexpectedErrno(err),
66866707 }
66876708 }
lib/std/zig/system/NativeTargetInfo.zig+1
......@@ -917,6 +917,7 @@ fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize {
917917 error.Unseekable => return error.UnableToReadElfFile,
918918 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
919919 error.ConnectionTimedOut => return error.UnableToReadElfFile,
920 error.SocketNotConnected => return error.UnableToReadElfFile,
920921 error.NetNameDeleted => return error.UnableToReadElfFile,
921922 error.Unexpected => return error.Unexpected,
922923 error.InputOutput => return error.FileSystem,
src/link.zig+1
......@@ -531,6 +531,7 @@ pub const File = struct {
531531 BrokenPipe,
532532 ConnectionResetByPeer,
533533 ConnectionTimedOut,
534 SocketNotConnected,
534535 NotOpenForReading,
535536 WouldBlock,
536537 AccessDenied,
src/main.zig+1
......@@ -5682,6 +5682,7 @@ const FmtError = error{
56825682 NotOpenForWriting,
56835683 UnsupportedEncoding,
56845684 ConnectionResetByPeer,
5685 SocketNotConnected,
56855686 LockViolation,
56865687 NetNameDeleted,
56875688 InvalidArgument,