commit 989cd4233e14d592c19d458fee24ff0fa9fd9638 (tree)
parent 8a15537c6e32a756d4bdd54723504174c61c8c6a
Author: Andrew Kelley <andrew@ziglang.org>
Date: Sun, 22 Sep 2019 18:19:37 -0400
Merge pull request #3298 from ziglang/gethostname
gethostname
Diffstat:
8 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/std/c.zig b/std/c.zig
@@ -107,6 +107,7 @@ pub extern "c" fn sysctl(name: [*]const c_int, namelen: c_uint, oldp: ?*c_void,
pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
+pub extern "c" fn gethostname(name: [*]u8, len: usize) c_int;
pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int;
pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;
diff --git a/std/os.zig b/std/os.zig
@@ -2688,6 +2688,38 @@ pub fn futimens(fd: fd_t, times: *const [2]timespec) FutimensError!void {
}
}
+pub const GetHostNameError = error{
+ PermissionDenied,
+ Unexpected,
+};
+
+pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
+ if (builtin.link_libc) {
+ switch (errno(system.gethostname(name_buffer, name_buffer.len))) {
+ 0 => return mem.toSlice(u8, name_buffer),
+ EFAULT => unreachable,
+ ENAMETOOLONG => unreachable, // HOST_NAME_MAX prevents this
+ EPERM => return error.PermissionDenied,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+ if (linux.is_the_target) {
+ var uts: utsname = undefined;
+ switch (errno(system.uname(&uts))) {
+ 0 => {
+ const hostname = mem.toSlice(u8, &uts.nodename);
+ mem.copy(u8, name_buffer, hostname);
+ return name_buffer[0..hostname.len];
+ },
+ EFAULT => unreachable,
+ EPERM => return error.PermissionDenied,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ @compileError("TODO implement gethostname for this OS");
+}
+
test "" {
_ = @import("os/darwin.zig");
_ = @import("os/freebsd.zig");
diff --git a/std/os/bits/darwin.zig b/std/os/bits/darwin.zig
@@ -1175,3 +1175,4 @@ pub fn S_ISSOCK(m: u32) bool {
pub fn S_IWHT(m: u32) bool {
return m & S_IFMT == S_IFWHT;
}
+pub const HOST_NAME_MAX = 72;
diff --git a/std/os/bits/freebsd.zig b/std/os/bits/freebsd.zig
@@ -935,3 +935,5 @@ pub fn S_ISSOCK(m: u32) bool {
pub fn S_IWHT(m: u32) bool {
return m & S_IFMT == S_IFWHT;
}
+
+pub const HOST_NAME_MAX = 255;
diff --git a/std/os/bits/linux.zig b/std/os/bits/linux.zig
@@ -1175,3 +1175,13 @@ pub const IORING_REGISTER_FILES = 2;
pub const IORING_UNREGISTER_FILES = 3;
pub const IORING_REGISTER_EVENTFD = 4;
pub const IORING_UNREGISTER_EVENTFD = 5;
+
+pub const utsname = extern struct {
+ sysname: [65]u8,
+ nodename: [65]u8,
+ release: [65]u8,
+ version: [65]u8,
+ machine: [65]u8,
+ domainname: [65]u8,
+};
+pub const HOST_NAME_MAX = 64;
diff --git a/std/os/bits/netbsd.zig b/std/os/bits/netbsd.zig
@@ -819,3 +819,5 @@ pub fn S_ISSOCK(m: u32) bool {
pub fn S_IWHT(m: u32) bool {
return m & S_IFMT == S_IFWHT;
}
+
+pub const HOST_NAME_MAX = 255;
diff --git a/std/os/linux.zig b/std/os/linux.zig
@@ -965,6 +965,10 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) usize {
return syscall2(SYS_sigaltstack, @ptrToInt(ss), @ptrToInt(old_ss));
}
+pub fn uname(uts: *utsname) usize {
+ return syscall1(SYS_uname, @ptrToInt(uts));
+}
+
// XXX: This should be weak
extern const __ehdr_start: elf.Ehdr = undefined;
diff --git a/std/os/test.zig b/std/os/test.zig
@@ -210,3 +210,12 @@ test "dl_iterate_phdr" {
expect(os.dl_iterate_phdr(usize, iter_fn, &counter) != 0);
expect(counter != 0);
}
+
+test "gethostname" {
+ if (os.windows.is_the_target)
+ return error.SkipZigTest;
+
+ var buf: [os.HOST_NAME_MAX]u8 = undefined;
+ const hostname = try os.gethostname(&buf);
+ expect(hostname.len != 0);
+}