Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/core/kernel/src/wasm/posix/netdb.zig
1068 views
1
pub fn keepalive() void {}
2
const std = @import("std");
3
const netdb = @cImport(@cInclude("netdb.h"));
4
const inet = @cImport(@cInclude("arpa/inet.h"));
5
const util = @import("util.zig");
6
7
export fn sendAddrinfo(ai_flags: c_int, ai_family: c_int, ai_socktype: c_int, ai_protocol: c_int, ai_addrlen: netdb.socklen_t, ai_addr: *netdb.sockaddr, ai_canonname: ?[*]u8, ai_next: ?*netdb.addrinfo) ?*netdb.addrinfo {
8
const addrinfo = util.mallocType(netdb.addrinfo, "sendAddrinfo") orelse return null;
9
addrinfo.ai_flags = ai_flags;
10
addrinfo.ai_family = ai_family;
11
addrinfo.ai_socktype = ai_socktype;
12
addrinfo.ai_protocol = ai_protocol;
13
addrinfo.ai_addrlen = ai_addrlen;
14
addrinfo.ai_addr = ai_addr;
15
addrinfo.ai_canonname = ai_canonname;
16
addrinfo.ai_next = ai_next;
17
return addrinfo;
18
}
19
20
// part of the posix api
21
export fn freeaddrinfo(addrinfo: *netdb.addrinfo) void {
22
// This is complicated because it is a linked list, and
23
// also some fields in it are pointers.
24
if (addrinfo.ai_next != null) { // handle linked list part via recurssion (it is a small list)
25
freeaddrinfo(addrinfo.ai_next);
26
}
27
if (addrinfo.ai_canonname != null) {
28
std.c.free(addrinfo.ai_canonname);
29
}
30
std.c.free(addrinfo.ai_addr);
31
std.c.free(addrinfo);
32
}
33
34
export fn recvAddr(addr: *anyopaque, addrtype: c_int) ?[*]u8 {
35
const dst = util.mallocString(40, "recvAddr") orelse return null;
36
if (inet.inet_ntop(addrtype, addr, dst, 40) == null) {
37
std.debug.print("recvAddr -- failed to convert address to string via inet_ntop\n", .{});
38
std.c.free(dst);
39
return null;
40
}
41
return dst;
42
}
43
44
export fn sendHostent(h_name: [*:0]u8, h_aliases: [*c][*c]u8, h_addrtype: c_int, h_length: c_int, h_addr_list: [*c][*c]u8, h_addr_list_len: usize) ?*netdb.hostent {
45
const hostent = util.mallocType(netdb.hostent, "sendHostent") orelse return null;
46
hostent.h_name = h_name;
47
hostent.h_aliases = h_aliases;
48
hostent.h_addrtype = h_addrtype;
49
hostent.h_length = h_length;
50
var binary = if (h_addrtype == netdb.AF_INET) convert_h_addr_list_ToBinary_v4(h_addr_list, h_addr_list_len) else convert_h_addr_list_ToBinary_v6(h_addr_list, h_addr_list_len);
51
hostent.h_addr_list = binary orelse return null;
52
freeNullTerminatedArrayOfStrings(h_addr_list);
53
return hostent;
54
}
55
56
fn freeNullTerminatedArrayOfStrings(v: [*c][*c]u8) void {
57
var i: usize = 0;
58
while (v[i] != null) : (i += 1) {
59
std.c.free(v[i]);
60
}
61
std.c.free(@ptrCast(*anyopaque, v));
62
}
63
64
fn convert_h_addr_list_ToBinary_v4(h_addr_list: [*c][*c]u8, len: usize) ?[*c][*c]u8 {
65
// Need to use
66
// int inet_pton(int af, const char *restrict src, void *restrict dst);
67
// to convert the h_addr_list from text to binary form.
68
var h_addr_binary_list = util.mallocArray(*allowzero netdb.in_addr, len + 1, "convert_h_addr_list_ToBinary_v4") orelse return null;
69
var i: usize = 0;
70
while (i < len) : (i += 1) {
71
var dst = util.mallocType(netdb.in_addr, "allocating in_addr in convert_h_addr_list_ToBinary_v4") orelse return null;
72
const ret = inet.inet_pton(netdb.AF_INET, h_addr_list[i], dst);
73
if (ret != 1) {
74
// TODO: slight memory leak here!
75
std.debug.print("inet_pton failed when doing convert_h_addr_list_ToBinary_v4 - h_addr_list[{d}]='{s}', ret={d}\n", .{ i, h_addr_list[i], ret });
76
return null;
77
}
78
h_addr_binary_list[i] = dst;
79
}
80
h_addr_binary_list[len] = @intToPtr(*allowzero netdb.in_addr, 0);
81
return @ptrCast([*c][*c]u8, h_addr_binary_list);
82
}
83
84
fn convert_h_addr_list_ToBinary_v6(h_addr_list: [*c][*c]u8, len: usize) ?[*c][*c]u8 {
85
var h_addr_binary_list = util.mallocArray(*allowzero netdb.in6_addr, len + 1, "convert_h_addr_list_ToBinary_v4") orelse return null;
86
var i: usize = 0;
87
while (i < len) : (i += 1) {
88
var dst = util.mallocType(netdb.in6_addr, "allocating in_addr in convert_h_addr_list_ToBinary_v4") orelse return null;
89
const ret = inet.inet_pton(netdb.AF_INET6, h_addr_list[i], dst);
90
if (ret != 1) {
91
// TODO: slight memory leak here!
92
std.debug.print("inet_pton failed when doing convert_h_addr_list_ToBinary_v4 - h_addr_list[{d}]='{s}', ret={d}\n", .{ i, h_addr_list[i], ret });
93
return null;
94
}
95
h_addr_binary_list[i] = dst;
96
}
97
h_addr_binary_list[len] = @intToPtr(*allowzero netdb.in6_addr, 0);
98
return @ptrCast([*c][*c]u8, h_addr_binary_list);
99
}
100
101
pub const constants = .{
102
.c_import = netdb,
103
.names = [_][:0]const u8{
104
"AF_UNSPEC", "AF_UNIX", "AF_INET", "AF_INET6", // AF_= address format
105
"AI_PASSIVE", "AI_CANONNAME", "AI_NUMERICHOST", "AI_V4MAPPED", "AI_ALL", "AI_ADDRCONFIG", "AI_NUMERICSERV", // AI = address info
106
"EAI_BADFLAGS", "EAI_NONAME", "EAI_AGAIN", "EAI_FAIL", "EAI_FAMILY", "EAI_SOCKTYPE", "EAI_SERVICE", "EAI_MEMORY", "EAI_SYSTEM", "EAI_OVERFLOW", // errors for the getaddrinfo function
107
"SOCK_STREAM", "SOCK_DGRAM", "SOCK_CLOEXEC",
108
},
109
};
110
111