| ... | @@ -46,6 +46,9 @@ pub const Address = extern union { | ... | @@ -46,6 +46,9 @@ pub const Address = extern union { |
| 46 | .path = undefined, | 46 | .path = undefined, |
| 47 | }; | 47 | }; |
| 48 | | 48 | |
| | 49 | // this enables us to have the proper length of the socket in getOsSockLen |
| | 50 | mem.zero(&sock_addr.path); |
| | 51 | |
| 49 | if (path.len > sock_addr.path.len) return error.NameTooLong; | 52 | if (path.len > sock_addr.path.len) return error.NameTooLong; |
| 50 | mem.copy(u8, &sock_addr.path, path); | 53 | mem.copy(u8, &sock_addr.path, path); |
| 51 | | 54 | |
| ... | @@ -344,6 +347,10 @@ pub const Address = extern union { | ... | @@ -344,6 +347,10 @@ pub const Address = extern union { |
| 344 | switch (self.any.family) { | 347 | switch (self.any.family) { |
| 345 | os.AF_INET => return @sizeOf(os.sockaddr_in), | 348 | os.AF_INET => return @sizeOf(os.sockaddr_in), |
| 346 | os.AF_INET6 => return @sizeOf(os.sockaddr_in6), | 349 | os.AF_INET6 => return @sizeOf(os.sockaddr_in6), |
| | 350 | os.AF_UNIX => blk: { |
| | 351 | const path_len = std.mem.len(self.un.path.len); |
| | 352 | break :blk @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len); |
| | 353 | }, |
| 347 | else => unreachable, | 354 | else => unreachable, |
| 348 | } | 355 | } |
| 349 | } | 356 | } |
| ... | @@ -1264,7 +1271,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8) | ... | @@ -1264,7 +1271,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8) |
| 1264 | } | 1271 | } |
| 1265 | } | 1272 | } |
| 1266 | | 1273 | |
| 1267 | pub const TcpServer = struct { | 1274 | pub const StreamServer = struct { |
| 1268 | /// Copied from `Options` on `init`. | 1275 | /// Copied from `Options` on `init`. |
| 1269 | kernel_backlog: u32, | 1276 | kernel_backlog: u32, |
| 1270 | | 1277 | |
| ... | @@ -1282,21 +1289,21 @@ pub const TcpServer = struct { | ... | @@ -1282,21 +1289,21 @@ pub const TcpServer = struct { |
| 1282 | | 1289 | |
| 1283 | /// After this call succeeds, resources have been acquired and must | 1290 | /// After this call succeeds, resources have been acquired and must |
| 1284 | /// be released with `deinit`. | 1291 | /// be released with `deinit`. |
| 1285 | pub fn init(options: Options) TcpServer { | 1292 | pub fn init(options: Options) StreamServer { |
| 1286 | return TcpServer{ | 1293 | return StreamServer{ |
| 1287 | .sockfd = null, | 1294 | .sockfd = null, |
| 1288 | .kernel_backlog = options.kernel_backlog, | 1295 | .kernel_backlog = options.kernel_backlog, |
| 1289 | .listen_address = undefined, | 1296 | .listen_address = undefined, |
| 1290 | }; | 1297 | }; |
| 1291 | } | 1298 | } |
| 1292 | | 1299 | |
| 1293 | /// Release all resources. The `TcpServer` memory becomes `undefined`. | 1300 | /// Release all resources. The `StreamServer` memory becomes `undefined`. |
| 1294 | pub fn deinit(self: *TcpServer) void { | 1301 | pub fn deinit(self: *StreamServer) void { |
| 1295 | self.close(); | 1302 | self.close(); |
| 1296 | self.* = undefined; | 1303 | self.* = undefined; |
| 1297 | } | 1304 | } |
| 1298 | | 1305 | |
| 1299 | pub fn listen(self: *TcpServer, address: Address) !void { | 1306 | pub fn listen(self: *StreamServer, address: Address) !void { |
| 1300 | const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0; | 1307 | const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0; |
| 1301 | const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock; | 1308 | const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock; |
| 1302 | const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP); | 1309 | const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP); |
| ... | @@ -1315,7 +1322,7 @@ pub const TcpServer = struct { | ... | @@ -1315,7 +1322,7 @@ pub const TcpServer = struct { |
| 1315 | /// Stop listening. It is still necessary to call `deinit` after stopping listening. | 1322 | /// Stop listening. It is still necessary to call `deinit` after stopping listening. |
| 1316 | /// Calling `deinit` will automatically call `close`. It is safe to call `close` when | 1323 | /// Calling `deinit` will automatically call `close`. It is safe to call `close` when |
| 1317 | /// not listening. | 1324 | /// not listening. |
| 1318 | pub fn close(self: *TcpServer) void { | 1325 | pub fn close(self: *StreamServer) void { |
| 1319 | if (self.sockfd) |fd| { | 1326 | if (self.sockfd) |fd| { |
| 1320 | os.close(fd); | 1327 | os.close(fd); |
| 1321 | self.sockfd = null; | 1328 | self.sockfd = null; |
| ... | @@ -1343,7 +1350,7 @@ pub const TcpServer = struct { | ... | @@ -1343,7 +1350,7 @@ pub const TcpServer = struct { |
| 1343 | } || os.UnexpectedError; | 1350 | } || os.UnexpectedError; |
| 1344 | | 1351 | |
| 1345 | /// If this function succeeds, the returned `fs.File` is a caller-managed resource. | 1352 | /// If this function succeeds, the returned `fs.File` is a caller-managed resource. |
| 1346 | pub fn accept(self: *TcpServer) AcceptError!fs.File { | 1353 | pub fn accept(self: *StreamServer) AcceptError!fs.File { |
| 1347 | const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0; | 1354 | const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0; |
| 1348 | const accept_flags = nonblock | os.SOCK_CLOEXEC; | 1355 | const accept_flags = nonblock | os.SOCK_CLOEXEC; |
| 1349 | var accepted_addr: Address = undefined; | 1356 | var accepted_addr: Address = undefined; |