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{...@@ -686,6 +686,7 @@ pub const ReadError = error{
686 ConnectionResetByPeer,686 ConnectionResetByPeer,
687 ConnectionTimedOut,687 ConnectionTimedOut,
688 NotOpenForReading,688 NotOpenForReading,
689 SocketNotConnected,
689690
690 // Windows only691 // Windows only
691 NetNameDeleted,692 NetNameDeleted,
...@@ -732,6 +733,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {...@@ -732,6 +733,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
732 .ISDIR => return error.IsDir,733 .ISDIR => return error.IsDir,
733 .NOBUFS => return error.SystemResources,734 .NOBUFS => return error.SystemResources,
734 .NOMEM => return error.SystemResources,735 .NOMEM => return error.SystemResources,
736 .NOTCONN => return error.SocketNotConnected,
735 .CONNRESET => return error.ConnectionResetByPeer,737 .CONNRESET => return error.ConnectionResetByPeer,
736 .TIMEDOUT => return error.ConnectionTimedOut,738 .TIMEDOUT => return error.ConnectionTimedOut,
737 .NOTCAPABLE => return error.AccessDenied,739 .NOTCAPABLE => return error.AccessDenied,
...@@ -760,6 +762,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {...@@ -760,6 +762,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
760 .ISDIR => return error.IsDir,762 .ISDIR => return error.IsDir,
761 .NOBUFS => return error.SystemResources,763 .NOBUFS => return error.SystemResources,
762 .NOMEM => return error.SystemResources,764 .NOMEM => return error.SystemResources,
765 .NOTCONN => return error.SocketNotConnected,
763 .CONNRESET => return error.ConnectionResetByPeer,766 .CONNRESET => return error.ConnectionResetByPeer,
764 .TIMEDOUT => return error.ConnectionTimedOut,767 .TIMEDOUT => return error.ConnectionTimedOut,
765 else => |err| return unexpectedErrno(err),768 else => |err| return unexpectedErrno(err),
...@@ -800,6 +803,9 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {...@@ -800,6 +803,9 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
800 .ISDIR => return error.IsDir,803 .ISDIR => return error.IsDir,
801 .NOBUFS => return error.SystemResources,804 .NOBUFS => return error.SystemResources,
802 .NOMEM => return error.SystemResources,805 .NOMEM => return error.SystemResources,
806 .NOTCONN => return error.SocketNotConnected,
807 .CONNRESET => return error.ConnectionResetByPeer,
808 .TIMEDOUT => return error.ConnectionTimedOut,
803 .NOTCAPABLE => return error.AccessDenied,809 .NOTCAPABLE => return error.AccessDenied,
804 else => |err| return unexpectedErrno(err),810 else => |err| return unexpectedErrno(err),
805 }811 }
...@@ -819,7 +825,9 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {...@@ -819,7 +825,9 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
819 .ISDIR => return error.IsDir,825 .ISDIR => return error.IsDir,
820 .NOBUFS => return error.SystemResources,826 .NOBUFS => return error.SystemResources,
821 .NOMEM => return error.SystemResources,827 .NOMEM => return error.SystemResources,
828 .NOTCONN => return error.SocketNotConnected,
822 .CONNRESET => return error.ConnectionResetByPeer,829 .CONNRESET => return error.ConnectionResetByPeer,
830 .TIMEDOUT => return error.ConnectionTimedOut,
823 else => |err| return unexpectedErrno(err),831 else => |err| return unexpectedErrno(err),
824 }832 }
825 }833 }
...@@ -864,7 +872,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {...@@ -864,7 +872,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
864 .ISDIR => return error.IsDir,872 .ISDIR => return error.IsDir,
865 .NOBUFS => return error.SystemResources,873 .NOBUFS => return error.SystemResources,
866 .NOMEM => return error.SystemResources,874 .NOMEM => return error.SystemResources,
875 .NOTCONN => return error.SocketNotConnected,
867 .CONNRESET => return error.ConnectionResetByPeer,876 .CONNRESET => return error.ConnectionResetByPeer,
877 .TIMEDOUT => return error.ConnectionTimedOut,
868 .NXIO => return error.Unseekable,878 .NXIO => return error.Unseekable,
869 .SPIPE => return error.Unseekable,879 .SPIPE => return error.Unseekable,
870 .OVERFLOW => return error.Unseekable,880 .OVERFLOW => return error.Unseekable,
...@@ -897,7 +907,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {...@@ -897,7 +907,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
897 .ISDIR => return error.IsDir,907 .ISDIR => return error.IsDir,
898 .NOBUFS => return error.SystemResources,908 .NOBUFS => return error.SystemResources,
899 .NOMEM => return error.SystemResources,909 .NOMEM => return error.SystemResources,
910 .NOTCONN => return error.SocketNotConnected,
900 .CONNRESET => return error.ConnectionResetByPeer,911 .CONNRESET => return error.ConnectionResetByPeer,
912 .TIMEDOUT => return error.ConnectionTimedOut,
901 .NXIO => return error.Unseekable,913 .NXIO => return error.Unseekable,
902 .SPIPE => return error.Unseekable,914 .SPIPE => return error.Unseekable,
903 .OVERFLOW => return error.Unseekable,915 .OVERFLOW => return error.Unseekable,
...@@ -1009,6 +1021,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {...@@ -1009,6 +1021,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
1009 .ISDIR => return error.IsDir,1021 .ISDIR => return error.IsDir,
1010 .NOBUFS => return error.SystemResources,1022 .NOBUFS => return error.SystemResources,
1011 .NOMEM => return error.SystemResources,1023 .NOMEM => return error.SystemResources,
1024 .NOTCONN => return error.SocketNotConnected,
1025 .CONNRESET => return error.ConnectionResetByPeer,
1026 .TIMEDOUT => return error.ConnectionTimedOut,
1012 .NXIO => return error.Unseekable,1027 .NXIO => return error.Unseekable,
1013 .SPIPE => return error.Unseekable,1028 .SPIPE => return error.Unseekable,
1014 .OVERFLOW => return error.Unseekable,1029 .OVERFLOW => return error.Unseekable,
...@@ -1035,6 +1050,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {...@@ -1035,6 +1050,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
1035 .ISDIR => return error.IsDir,1050 .ISDIR => return error.IsDir,
1036 .NOBUFS => return error.SystemResources,1051 .NOBUFS => return error.SystemResources,
1037 .NOMEM => return error.SystemResources,1052 .NOMEM => return error.SystemResources,
1053 .NOTCONN => return error.SocketNotConnected,
1054 .CONNRESET => return error.ConnectionResetByPeer,
1055 .TIMEDOUT => return error.ConnectionTimedOut,
1038 .NXIO => return error.Unseekable,1056 .NXIO => return error.Unseekable,
1039 .SPIPE => return error.Unseekable,1057 .SPIPE => return error.Unseekable,
1040 .OVERFLOW => return error.Unseekable,1058 .OVERFLOW => return error.Unseekable,
...@@ -6624,6 +6642,7 @@ pub const RecvFromError = error{...@@ -6624,6 +6642,7 @@ pub const RecvFromError = error{
6624 SystemResources,6642 SystemResources,
66256643
6626 ConnectionResetByPeer,6644 ConnectionResetByPeer,
6645 ConnectionTimedOut,
66276646
6628 /// The socket has not been bound.6647 /// The socket has not been bound.
6629 SocketNotBound,6648 SocketNotBound,
...@@ -6663,6 +6682,7 @@ pub fn recvfrom(...@@ -6663,6 +6682,7 @@ pub fn recvfrom(
6663 .WSAENETDOWN => return error.NetworkSubsystemFailed,6682 .WSAENETDOWN => return error.NetworkSubsystemFailed,
6664 .WSAENOTCONN => return error.SocketNotConnected,6683 .WSAENOTCONN => return error.SocketNotConnected,
6665 .WSAEWOULDBLOCK => return error.WouldBlock,6684 .WSAEWOULDBLOCK => return error.WouldBlock,
6685 .WSAETIMEDOUT => return error.ConnectionTimedOut,
6666 // TODO: handle more errors6686 // TODO: handle more errors
6667 else => |err| return windows.unexpectedWSAError(err),6687 else => |err| return windows.unexpectedWSAError(err),
6668 }6688 }
...@@ -6682,6 +6702,7 @@ pub fn recvfrom(...@@ -6682,6 +6702,7 @@ pub fn recvfrom(
6682 .NOMEM => return error.SystemResources,6702 .NOMEM => return error.SystemResources,
6683 .CONNREFUSED => return error.ConnectionRefused,6703 .CONNREFUSED => return error.ConnectionRefused,
6684 .CONNRESET => return error.ConnectionResetByPeer,6704 .CONNRESET => return error.ConnectionResetByPeer,
6705 .TIMEDOUT => return error.ConnectionTimedOut,
6685 else => |err| return unexpectedErrno(err),6706 else => |err| return unexpectedErrno(err),
6686 }6707 }
6687 }6708 }
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 {...@@ -917,6 +917,7 @@ fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize {
917 error.Unseekable => return error.UnableToReadElfFile,917 error.Unseekable => return error.UnableToReadElfFile,
918 error.ConnectionResetByPeer => return error.UnableToReadElfFile,918 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
919 error.ConnectionTimedOut => return error.UnableToReadElfFile,919 error.ConnectionTimedOut => return error.UnableToReadElfFile,
920 error.SocketNotConnected => return error.UnableToReadElfFile,
920 error.NetNameDeleted => return error.UnableToReadElfFile,921 error.NetNameDeleted => return error.UnableToReadElfFile,
921 error.Unexpected => return error.Unexpected,922 error.Unexpected => return error.Unexpected,
922 error.InputOutput => return error.FileSystem,923 error.InputOutput => return error.FileSystem,
src/link.zig+1
...@@ -531,6 +531,7 @@ pub const File = struct {...@@ -531,6 +531,7 @@ pub const File = struct {
531 BrokenPipe,531 BrokenPipe,
532 ConnectionResetByPeer,532 ConnectionResetByPeer,
533 ConnectionTimedOut,533 ConnectionTimedOut,
534 SocketNotConnected,
534 NotOpenForReading,535 NotOpenForReading,
535 WouldBlock,536 WouldBlock,
536 AccessDenied,537 AccessDenied,
src/main.zig+1
...@@ -5682,6 +5682,7 @@ const FmtError = error{...@@ -5682,6 +5682,7 @@ const FmtError = error{
5682 NotOpenForWriting,5682 NotOpenForWriting,
5683 UnsupportedEncoding,5683 UnsupportedEncoding,
5684 ConnectionResetByPeer,5684 ConnectionResetByPeer,
5685 SocketNotConnected,
5685 LockViolation,5686 LockViolation,
5686 NetNameDeleted,5687 NetNameDeleted,
5687 InvalidArgument,5688 InvalidArgument,