@@ -10,6 +10,7 @@ const net = @This();
10
10
const mem = std .mem ;
11
11
const os = std .os ;
12
12
const fs = std .fs ;
13
+ const io = std .io ;
13
14
14
15
pub const has_unix_sockets = @hasDecl (os , "sockaddr_un" );
15
16
@@ -651,7 +652,7 @@ pub const AddressList = struct {
651
652
};
652
653
653
654
/// All memory allocated with `allocator` will be freed before this function returns.
654
- pub fn tcpConnectToHost (allocator : * mem.Allocator , name : []const u8 , port : u16 ) ! fs.File {
655
+ pub fn tcpConnectToHost (allocator : * mem.Allocator , name : []const u8 , port : u16 ) ! Stream {
655
656
const list = try getAddressList (allocator , name , port );
656
657
defer list .deinit ();
657
658
@@ -668,7 +669,7 @@ pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16)
668
669
return std .os .ConnectError .ConnectionRefused ;
669
670
}
670
671
671
- pub fn tcpConnectToAddress (address : Address ) ! fs.File {
672
+ pub fn tcpConnectToAddress (address : Address ) ! Stream {
672
673
const nonblock = if (std .io .is_async ) os .SOCK_NONBLOCK else 0 ;
673
674
const sock_flags = os .SOCK_STREAM | nonblock |
674
675
(if (builtin .os .tag == .windows ) 0 else os .SOCK_CLOEXEC );
@@ -682,7 +683,7 @@ pub fn tcpConnectToAddress(address: Address) !fs.File {
682
683
try os .connect (sockfd , & address .any , address .getOsSockLen ());
683
684
}
684
685
685
- return fs.File { .handle = sockfd };
686
+ return Stream { .handle = sockfd };
686
687
}
687
688
688
689
/// Call `AddressList.deinit` on the result.
@@ -1565,6 +1566,55 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
1565
1566
}
1566
1567
}
1567
1568
1569
+ pub const Stream = struct {
1570
+ // Underlying socket descriptor.
1571
+ // Note that on some platforms this may not be interchangeable with a
1572
+ // regular files descriptor.
1573
+ handle : os.socket_t ,
1574
+
1575
+ pub fn close (self : Stream ) void {
1576
+ os .closeSocket (self .handle );
1577
+ }
1578
+
1579
+ pub const ReadError = os .ReadError ;
1580
+ pub const WriteError = os .WriteError ;
1581
+
1582
+ pub const Reader = io .Reader (Stream , ReadError , read );
1583
+ pub const Writer = io .Writer (Stream , WriteError , write );
1584
+
1585
+ pub fn reader (self : Stream ) Reader {
1586
+ return .{ .context = self };
1587
+ }
1588
+
1589
+ pub fn writer (self : Stream ) Writer {
1590
+ return .{ .context = self };
1591
+ }
1592
+
1593
+ pub fn read (self : Stream , buffer : []u8 ) ReadError ! usize {
1594
+ if (std .Target .current .os .tag == .windows ) {
1595
+ return os .windows .ReadFile (self .handle , buffer , null , io .default_mode );
1596
+ }
1597
+
1598
+ if (std .io .is_async ) {
1599
+ return std .event .Loop .instance .? .read (self .handle , buffer , false );
1600
+ } else {
1601
+ return os .read (self .handle , buffer );
1602
+ }
1603
+ }
1604
+
1605
+ pub fn write (self : Stream , buffer : []const u8 ) WriteError ! usize {
1606
+ if (std .Target .current .os .tag == .windows ) {
1607
+ return os .windows .WriteFile (self .handle , buffer , null , io .default_mode );
1608
+ }
1609
+
1610
+ if (std .io .is_async ) {
1611
+ return std .event .Loop .instance .? .write (self .handle , buffer , false );
1612
+ } else {
1613
+ return os .write (self .handle , buffer );
1614
+ }
1615
+ }
1616
+ };
1617
+
1568
1618
pub const StreamServer = struct {
1569
1619
/// Copied from `Options` on `init`.
1570
1620
kernel_backlog : u31 ,
@@ -1675,7 +1725,7 @@ pub const StreamServer = struct {
1675
1725
} || os .UnexpectedError ;
1676
1726
1677
1727
pub const Connection = struct {
1678
- file : fs.File ,
1728
+ stream : Stream ,
1679
1729
address : Address ,
1680
1730
};
1681
1731
@@ -1694,7 +1744,7 @@ pub const StreamServer = struct {
1694
1744
1695
1745
if (accept_result ) | fd | {
1696
1746
return Connection {
1697
- .file = fs.File { .handle = fd },
1747
+ .stream = Stream { .handle = fd },
1698
1748
.address = accepted_addr ,
1699
1749
};
1700
1750
} else | err | switch (err ) {
0 commit comments