authorgravatar for kenta@lithdew.netKenta Iwasaki <kenta@lithdew.net> 2021-05-31 19:29:17+09:00
committergravatar for kenta@lithdew.netKenta Iwasaki <kenta@lithdew.net> 2021-06-01 18:24:43+09:00
logaad8491dbd98052e97b395ea572b186482d3b38f
treec58fd0921a6082a39f388b46d36c543d191974cf
parent6950e4c2943d7eee1868aff1bf9e24f6bb310f60

os: make msghdr, msghdr_const, and sockaddr_storage backwards-compatible

`msghdr` and `msghdr_const` definitions have been added back the way they were in std.os. std.os.sendmsg has also been modified to accept a msghdr_const again to ensure backwards-compatibility with this PR. Underneath the hood, std.os.sendmsg will @ptrCast the provided msghdr_const into a std.x.os.Socket.Message. `sockaddr_storage` definitions have been added back the way they were in std.os, except that it now simply aliases std.x.os.Socket.Address.Native.Storage as all of std.x.os.Socket.Address.Native.Storage's fields are equivalent to the fields that were previously defined for std.x.os.bits.sockaddr_storage. std.x.os.Socket.sendMessage now no longer is a stub that aliases std.os.sendmsg, but instead calls and handles errors from std.os.system.sendmsg directly. Addresses feedback to urge backwards compatibility from @andrewrk.

17 files changed, 413 insertions(+), 5 deletions(-)

lib/std/os.zig+2-2
......@@ -4994,11 +4994,11 @@ pub fn sendmsg(
49944994 /// The file descriptor of the sending socket.
49954995 sockfd: socket_t,
49964996 /// Message header and iovecs
4997 msg: std.x.os.Socket.Message,
4997 msg: msghdr_const,
49984998 flags: u32,
49994999) SendMsgError!usize {
50005000 while (true) {
5001 const rc = system.sendmsg(sockfd, &msg, @intCast(c_int, flags));
5001 const rc = system.sendmsg(sockfd, @ptrCast(*const std.x.os.Socket.Message, &msg), @intCast(c_int, flags));
50025002 if (builtin.os.tag == .windows) {
50035003 if (rc == windows.ws2_32.SOCKET_ERROR) {
50045004 switch (windows.ws2_32.WSAGetLastError()) {
lib/std/os/bits/darwin.zig+1
......@@ -23,6 +23,7 @@ pub const sockaddr = extern struct {
2323 family: sa_family_t,
2424 data: [14]u8,
2525};
26pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
2627pub const sockaddr_in = extern struct {
2728 len: u8 = @sizeOf(sockaddr_in),
2829 family: sa_family_t = AF_INET,
lib/std/os/bits/dragonfly.zig+11
......@@ -396,6 +396,8 @@ pub const sockaddr = extern struct {
396396 data: [14]u8,
397397};
398398
399pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
400
399401pub const Kevent = extern struct {
400402 ident: usize,
401403 filter: c_short,
......@@ -773,6 +775,15 @@ pub const cmsghdr = extern struct {
773775 cmsg_level: c_int,
774776 cmsg_type: c_int,
775777};
778pub const msghdr = extern struct {
779 msg_name: ?*c_void,
780 msg_namelen: socklen_t,
781 msg_iov: [*c]iovec,
782 msg_iovlen: c_int,
783 msg_control: ?*c_void,
784 msg_controllen: socklen_t,
785 msg_flags: c_int,
786};
776787pub const cmsgcred = extern struct {
777788 cmcred_pid: pid_t,
778789 cmcred_uid: uid_t,
lib/std/os/bits/freebsd.zig+48
......@@ -82,6 +82,52 @@ pub const Flock = extern struct {
8282 __unused: [4]u8,
8383};
8484
85pub const msghdr = extern struct {
86 /// optional address
87 msg_name: ?*sockaddr,
88
89 /// size of address
90 msg_namelen: socklen_t,
91
92 /// scatter/gather array
93 msg_iov: [*]iovec,
94
95 /// # elements in msg_iov
96 msg_iovlen: i32,
97
98 /// ancillary data
99 msg_control: ?*c_void,
100
101 /// ancillary data buffer len
102 msg_controllen: socklen_t,
103
104 /// flags on received message
105 msg_flags: i32,
106};
107
108pub const msghdr_const = extern struct {
109 /// optional address
110 msg_name: ?*const sockaddr,
111
112 /// size of address
113 msg_namelen: socklen_t,
114
115 /// scatter/gather array
116 msg_iov: [*]iovec_const,
117
118 /// # elements in msg_iov
119 msg_iovlen: i32,
120
121 /// ancillary data
122 msg_control: ?*c_void,
123
124 /// ancillary data buffer len
125 msg_controllen: socklen_t,
126
127 /// flags on received message
128 msg_flags: i32,
129};
130
85131pub const libc_stat = extern struct {
86132 dev: dev_t,
87133 ino: ino_t,
......@@ -160,6 +206,8 @@ pub const sockaddr = extern struct {
160206 data: [14]u8,
161207};
162208
209pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
210
163211pub const sockaddr_in = extern struct {
164212 len: u8 = @sizeOf(sockaddr_in),
165213 family: sa_family_t = AF_INET,
lib/std/os/bits/haiku.zig+48
......@@ -73,6 +73,52 @@ pub const Flock = extern struct {
7373 __unused: [4]u8,
7474};
7575
76pub const msghdr = extern struct {
77 /// optional address
78 msg_name: ?*sockaddr,
79
80 /// size of address
81 msg_namelen: socklen_t,
82
83 /// scatter/gather array
84 msg_iov: [*]iovec,
85
86 /// # elements in msg_iov
87 msg_iovlen: i32,
88
89 /// ancillary data
90 msg_control: ?*c_void,
91
92 /// ancillary data buffer len
93 msg_controllen: socklen_t,
94
95 /// flags on received message
96 msg_flags: i32,
97};
98
99pub const msghdr_const = extern struct {
100 /// optional address
101 msg_name: ?*const sockaddr,
102
103 /// size of address
104 msg_namelen: socklen_t,
105
106 /// scatter/gather array
107 msg_iov: [*]iovec_const,
108
109 /// # elements in msg_iov
110 msg_iovlen: i32,
111
112 /// ancillary data
113 msg_control: ?*c_void,
114
115 /// ancillary data buffer len
116 msg_controllen: socklen_t,
117
118 /// flags on received message
119 msg_flags: i32,
120};
121
76122pub const off_t = i64;
77123pub const ino_t = u64;
78124
......@@ -193,6 +239,8 @@ pub const sockaddr = extern struct {
193239 data: [14]u8,
194240};
195241
242pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
243
196244pub const sockaddr_in = extern struct {
197245 len: u8 = @sizeOf(sockaddr_in),
198246 family: sa_family_t = AF_INET,
lib/std/os/bits/linux.zig+4-2
......@@ -1149,6 +1149,8 @@ pub const sockaddr = extern struct {
11491149 data: [14]u8,
11501150};
11511151
1152pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
1153
11521154/// IPv4 socket address
11531155pub const sockaddr_in = extern struct {
11541156 family: sa_family_t = AF_INET,
......@@ -1173,12 +1175,12 @@ pub const sockaddr_un = extern struct {
11731175};
11741176
11751177pub const mmsghdr = extern struct {
1176 msg_hdr: std.x.os.Socket.Message,
1178 msg_hdr: msghdr,
11771179 msg_len: u32,
11781180};
11791181
11801182pub const mmsghdr_const = extern struct {
1181 msg_hdr: std.x.os.Socket.Message,
1183 msg_hdr: msghdr_const,
11821184 msg_len: u32,
11831185};
11841186
lib/std/os/bits/linux/arm-eabi.zig+20
......@@ -526,6 +526,26 @@ pub const Flock = extern struct {
526526 __unused: [4]u8,
527527};
528528
529pub const msghdr = extern struct {
530 msg_name: ?*sockaddr,
531 msg_namelen: socklen_t,
532 msg_iov: [*]iovec,
533 msg_iovlen: i32,
534 msg_control: ?*c_void,
535 msg_controllen: socklen_t,
536 msg_flags: i32,
537};
538
539pub const msghdr_const = extern struct {
540 msg_name: ?*const sockaddr,
541 msg_namelen: socklen_t,
542 msg_iov: [*]iovec_const,
543 msg_iovlen: i32,
544 msg_control: ?*c_void,
545 msg_controllen: socklen_t,
546 msg_flags: i32,
547};
548
529549pub const blksize_t = i32;
530550pub const nlink_t = u32;
531551pub const time_t = isize;
lib/std/os/bits/linux/arm64.zig+24
......@@ -395,6 +395,30 @@ pub const Flock = extern struct {
395395 __unused: [4]u8,
396396};
397397
398pub const msghdr = extern struct {
399 msg_name: ?*sockaddr,
400 msg_namelen: socklen_t,
401 msg_iov: [*]iovec,
402 msg_iovlen: i32,
403 __pad1: i32 = 0,
404 msg_control: ?*c_void,
405 msg_controllen: socklen_t,
406 __pad2: socklen_t = 0,
407 msg_flags: i32,
408};
409
410pub const msghdr_const = extern struct {
411 msg_name: ?*const sockaddr,
412 msg_namelen: socklen_t,
413 msg_iov: [*]iovec_const,
414 msg_iovlen: i32,
415 __pad1: i32 = 0,
416 msg_control: ?*c_void,
417 msg_controllen: socklen_t,
418 __pad2: socklen_t = 0,
419 msg_flags: i32,
420};
421
398422pub const blksize_t = i32;
399423pub const nlink_t = u32;
400424pub const time_t = isize;
lib/std/os/bits/linux/i386.zig+20
......@@ -523,6 +523,26 @@ pub const Flock = extern struct {
523523 l_pid: pid_t,
524524};
525525
526pub const msghdr = extern struct {
527 msg_name: ?*sockaddr,
528 msg_namelen: socklen_t,
529 msg_iov: [*]iovec,
530 msg_iovlen: i32,
531 msg_control: ?*c_void,
532 msg_controllen: socklen_t,
533 msg_flags: i32,
534};
535
536pub const msghdr_const = extern struct {
537 msg_name: ?*const sockaddr,
538 msg_namelen: socklen_t,
539 msg_iov: [*]iovec_const,
540 msg_iovlen: i32,
541 msg_control: ?*c_void,
542 msg_controllen: socklen_t,
543 msg_flags: i32,
544};
545
526546pub const blksize_t = i32;
527547pub const nlink_t = u32;
528548pub const time_t = isize;
lib/std/os/bits/linux/powerpc.zig+20
......@@ -515,6 +515,26 @@ pub const Flock = extern struct {
515515 l_pid: pid_t,
516516};
517517
518pub const msghdr = extern struct {
519 msg_name: ?*sockaddr,
520 msg_namelen: socklen_t,
521 msg_iov: [*]iovec,
522 msg_iovlen: usize,
523 msg_control: ?*c_void,
524 msg_controllen: socklen_t,
525 msg_flags: i32,
526};
527
528pub const msghdr_const = extern struct {
529 msg_name: ?*const sockaddr,
530 msg_namelen: socklen_t,
531 msg_iov: [*]iovec_const,
532 msg_iovlen: usize,
533 msg_control: ?*c_void,
534 msg_controllen: socklen_t,
535 msg_flags: i32,
536};
537
518538pub const blksize_t = i32;
519539pub const nlink_t = u32;
520540pub const time_t = isize;
lib/std/os/bits/linux/powerpc64.zig+20
......@@ -491,6 +491,26 @@ pub const Flock = extern struct {
491491 __unused: [4]u8,
492492};
493493
494pub const msghdr = extern struct {
495 msg_name: ?*sockaddr,
496 msg_namelen: socklen_t,
497 msg_iov: [*]iovec,
498 msg_iovlen: usize,
499 msg_control: ?*c_void,
500 msg_controllen: usize,
501 msg_flags: i32,
502};
503
504pub const msghdr_const = extern struct {
505 msg_name: ?*const sockaddr,
506 msg_namelen: socklen_t,
507 msg_iov: [*]iovec_const,
508 msg_iovlen: usize,
509 msg_control: ?*c_void,
510 msg_controllen: usize,
511 msg_flags: i32,
512};
513
494514pub const blksize_t = i64;
495515pub const nlink_t = u64;
496516pub const time_t = i64;
lib/std/os/bits/linux/sparc64.zig+20
......@@ -465,6 +465,26 @@ pub const Flock = extern struct {
465465 l_pid: pid_t,
466466};
467467
468pub const msghdr = extern struct {
469 msg_name: ?*sockaddr,
470 msg_namelen: socklen_t,
471 msg_iov: [*]iovec,
472 msg_iovlen: u64,
473 msg_control: ?*c_void,
474 msg_controllen: u64,
475 msg_flags: i32,
476};
477
478pub const msghdr_const = extern struct {
479 msg_name: ?*const sockaddr,
480 msg_namelen: socklen_t,
481 msg_iov: [*]iovec_const,
482 msg_iovlen: u64,
483 msg_control: ?*c_void,
484 msg_controllen: u64,
485 msg_flags: i32,
486};
487
468488pub const off_t = i64;
469489pub const ino_t = u64;
470490pub const mode_t = u32;
lib/std/os/bits/linux/x86_64.zig+24
......@@ -489,6 +489,30 @@ pub const Flock = extern struct {
489489 l_pid: pid_t,
490490};
491491
492pub const msghdr = extern struct {
493 msg_name: ?*sockaddr,
494 msg_namelen: socklen_t,
495 msg_iov: [*]iovec,
496 msg_iovlen: i32,
497 __pad1: i32 = 0,
498 msg_control: ?*c_void,
499 msg_controllen: socklen_t,
500 __pad2: socklen_t = 0,
501 msg_flags: i32,
502};
503
504pub const msghdr_const = extern struct {
505 msg_name: ?*const sockaddr,
506 msg_namelen: socklen_t,
507 msg_iov: [*]iovec_const,
508 msg_iovlen: i32,
509 __pad1: i32 = 0,
510 msg_control: ?*c_void,
511 msg_controllen: socklen_t,
512 __pad2: socklen_t = 0,
513 msg_flags: i32,
514};
515
492516pub const off_t = i64;
493517pub const ino_t = u64;
494518pub const dev_t = u64;
lib/std/os/bits/netbsd.zig+48
......@@ -108,6 +108,52 @@ pub const EAI = enum(c_int) {
108108
109109pub const EAI_MAX = 15;
110110
111pub const msghdr = extern struct {
112 /// optional address
113 msg_name: ?*sockaddr,
114
115 /// size of address
116 msg_namelen: socklen_t,
117
118 /// scatter/gather array
119 msg_iov: [*]iovec,
120
121 /// # elements in msg_iov
122 msg_iovlen: i32,
123
124 /// ancillary data
125 msg_control: ?*c_void,
126
127 /// ancillary data buffer len
128 msg_controllen: socklen_t,
129
130 /// flags on received message
131 msg_flags: i32,
132};
133
134pub const msghdr_const = extern struct {
135 /// optional address
136 msg_name: ?*const sockaddr,
137
138 /// size of address
139 msg_namelen: socklen_t,
140
141 /// scatter/gather array
142 msg_iov: [*]iovec_const,
143
144 /// # elements in msg_iov
145 msg_iovlen: i32,
146
147 /// ancillary data
148 msg_control: ?*c_void,
149
150 /// ancillary data buffer len
151 msg_controllen: socklen_t,
152
153 /// flags on received message
154 msg_flags: i32,
155};
156
111157pub const libc_stat = extern struct {
112158 dev: dev_t,
113159 mode: mode_t,
......@@ -180,6 +226,8 @@ pub const sockaddr = extern struct {
180226 data: [14]u8,
181227};
182228
229pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
230
183231pub const sockaddr_in = extern struct {
184232 len: u8 = @sizeOf(sockaddr_in),
185233 family: sa_family_t = AF_INET,
lib/std/os/bits/openbsd.zig+48
......@@ -124,6 +124,52 @@ pub const EAI = enum(c_int) {
124124
125125pub const EAI_MAX = 15;
126126
127pub const msghdr = extern struct {
128 /// optional address
129 msg_name: ?*sockaddr,
130
131 /// size of address
132 msg_namelen: socklen_t,
133
134 /// scatter/gather array
135 msg_iov: [*]iovec,
136
137 /// # elements in msg_iov
138 msg_iovlen: c_uint,
139
140 /// ancillary data
141 msg_control: ?*c_void,
142
143 /// ancillary data buffer len
144 msg_controllen: socklen_t,
145
146 /// flags on received message
147 msg_flags: c_int,
148};
149
150pub const msghdr_const = extern struct {
151 /// optional address
152 msg_name: ?*const sockaddr,
153
154 /// size of address
155 msg_namelen: socklen_t,
156
157 /// scatter/gather array
158 msg_iov: [*]iovec_const,
159
160 /// # elements in msg_iov
161 msg_iovlen: c_uint,
162
163 /// ancillary data
164 msg_control: ?*c_void,
165
166 /// ancillary data buffer len
167 msg_controllen: socklen_t,
168
169 /// flags on received message
170 msg_flags: c_int,
171};
172
127173pub const libc_stat = extern struct {
128174 mode: mode_t,
129175 dev: dev_t,
......@@ -200,6 +246,8 @@ pub const sockaddr = extern struct {
200246 data: [14]u8,
201247};
202248
249pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
250
203251pub const sockaddr_in = extern struct {
204252 len: u8 = @sizeOf(sockaddr_in),
205253 family: sa_family_t = AF_INET,
lib/std/os/windows/ws2_32.zig+23
......@@ -1059,6 +1059,8 @@ pub const sockaddr = extern struct {
10591059 data: [14]u8,
10601060};
10611061
1062pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
1063
10621064/// IPv4 socket address
10631065pub const sockaddr_in = extern struct {
10641066 family: ADDRESS_FAMILY = AF_INET,
......@@ -1087,6 +1089,27 @@ pub const WSABUF = extern struct {
10871089 buf: [*]u8,
10881090};
10891091
1092pub const msghdr = WSAMSG;
1093pub const msghdr_const = WSAMSG_const;
1094
1095pub const WSAMSG_const = extern struct {
1096 name: *const sockaddr,
1097 namelen: INT,
1098 lpBuffers: [*]WSABUF,
1099 dwBufferCount: DWORD,
1100 Control: WSABUF,
1101 dwFlags: DWORD,
1102};
1103
1104pub const WSAMSG = extern struct {
1105 name: *sockaddr,
1106 namelen: INT,
1107 lpBuffers: [*]WSABUF,
1108 dwBufferCount: DWORD,
1109 Control: WSABUF,
1110 dwFlags: DWORD,
1111};
1112
10901113pub const WSAPOLLFD = pollfd;
10911114
10921115pub const pollfd = extern struct {
lib/std/x/os/socket_posix.zig+32-1
......@@ -79,7 +79,38 @@ pub fn Mixin(comptime Socket: type) type {
7979 /// with a set of flags specified. It returns the number of bytes that are
8080 /// written to the socket.
8181 pub fn writeMessage(self: Socket, msg: Socket.Message, flags: u32) !usize {
82 return os.sendmsg(self.fd, msg, flags);
82 while (true) {
83 const rc = os.system.sendmsg(self.fd, &msg, @intCast(c_int, flags));
84 return switch (os.errno(rc)) {
85 0 => return @intCast(usize, rc),
86 os.EACCES => error.AccessDenied,
87 os.EAGAIN => error.WouldBlock,
88 os.EALREADY => error.FastOpenAlreadyInProgress,
89 os.EBADF => unreachable, // always a race condition
90 os.ECONNRESET => error.ConnectionResetByPeer,
91 os.EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
92 os.EFAULT => unreachable, // An invalid user space address was specified for an argument.
93 os.EINTR => continue,
94 os.EINVAL => unreachable, // Invalid argument passed.
95 os.EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
96 os.EMSGSIZE => error.MessageTooBig,
97 os.ENOBUFS => error.SystemResources,
98 os.ENOMEM => error.SystemResources,
99 os.ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
100 os.EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
101 os.EPIPE => error.BrokenPipe,
102 os.EAFNOSUPPORT => error.AddressFamilyNotSupported,
103 os.ELOOP => error.SymLinkLoop,
104 os.ENAMETOOLONG => error.NameTooLong,
105 os.ENOENT => error.FileNotFound,
106 os.ENOTDIR => error.NotDir,
107 os.EHOSTUNREACH => error.NetworkUnreachable,
108 os.ENETUNREACH => error.NetworkUnreachable,
109 os.ENOTCONN => error.SocketNotConnected,
110 os.ENETDOWN => error.NetworkSubsystemFailed,
111 else => |err| os.unexpectedErrno(err),
112 };
113 }
83114 }
84115
85116 /// Read multiple I/O vectors with a prepended message header from the socket