From e63daca92e959495be347525415ef1e520b01f44 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 11 Sep 2019 21:21:00 -0400 Subject: [PATCH 1/2] linux implementation of std.net.getHostName --- std/net.zig | 8 ++++++++ std/os.zig | 22 ++++++++++++++++++++++ std/os/bits/linux.zig | 10 ++++++++++ std/os/linux.zig | 4 ++++ 4 files changed, 44 insertions(+) diff --git a/std/net.zig b/std/net.zig index be9d18056c03a2e4ef315932d944c40091bb0902..3a1656d14df0ab78648337da28dbd6a8d5c5eadd 100644 --- a/std/net.zig +++ b/std/net.zig @@ -245,3 +245,11 @@ pub fn connectUnixSocket(path: []const u8) !std.fs.File { return std.fs.File.openHandle(sockfd); } + +pub const getHostName = os.gethostname; + +test "getHostName" { + var buf: [os.HOST_NAME_MAX]u8 = undefined; + const hostname = try getHostName(&buf); + expect(hostname.len != 0); +} diff --git a/std/os.zig b/std/os.zig index b32c8a0b7ed1e731c23bcd54009d859771b1a41e..63e6338f8162bea9e84b3274d7dd7898daf57c9a 100644 --- a/std/os.zig +++ b/std/os.zig @@ -2688,6 +2688,28 @@ pub fn futimens(fd: fd_t, times: *const [2]timespec) FutimensError!void { } } +pub const GetHostNameError = error{Unexpected}; + +pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 { + if (builtin.link_libc) { + @compileError("TODO implement gethostname when linking libc"); + } + 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, + 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/linux.zig b/std/os/bits/linux.zig index c489592c4b2abcc7187713b6f1a05aca6165992e..939d203e8daa9ab0424f6a6af4cc2bd35a33ebaf 100644 --- 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/linux.zig b/std/os/linux.zig index 74c71ee2c45969e68510273d12d08d5dcf05b337..47fc1841e99a5354ab05305e59ad17a58900ff9f 100644 --- 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; -- 2.54.0 From 028011e59a486bf39db8c97e44a1bd79e09082ef Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 15:36:11 -0400 Subject: [PATCH 2/2] libc implementation of gethostname --- std/c.zig | 1 + std/net.zig | 8 -------- std/os.zig | 14 ++++++++++++-- std/os/bits/darwin.zig | 1 + std/os/bits/freebsd.zig | 2 ++ std/os/bits/netbsd.zig | 2 ++ std/os/test.zig | 9 +++++++++ 7 files changed, 27 insertions(+), 10 deletions(-) diff --git a/std/c.zig b/std/c.zig index 45d93bfd9f635abd231409dfd09073a9bad97a93..dcde3b8ebb35b3c74e3ace7cc05608081fb0a071 100644 --- 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/net.zig b/std/net.zig index 3a1656d14df0ab78648337da28dbd6a8d5c5eadd..be9d18056c03a2e4ef315932d944c40091bb0902 100644 --- a/std/net.zig +++ b/std/net.zig @@ -245,11 +245,3 @@ pub fn connectUnixSocket(path: []const u8) !std.fs.File { return std.fs.File.openHandle(sockfd); } - -pub const getHostName = os.gethostname; - -test "getHostName" { - var buf: [os.HOST_NAME_MAX]u8 = undefined; - const hostname = try getHostName(&buf); - expect(hostname.len != 0); -} diff --git a/std/os.zig b/std/os.zig index 63e6338f8162bea9e84b3274d7dd7898daf57c9a..a8677666adb05c6337e5a37839722ddb332d8f99 100644 --- a/std/os.zig +++ b/std/os.zig @@ -2688,11 +2688,20 @@ pub fn futimens(fd: fd_t, times: *const [2]timespec) FutimensError!void { } } -pub const GetHostNameError = error{Unexpected}; +pub const GetHostNameError = error{ + PermissionDenied, + Unexpected, +}; pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 { if (builtin.link_libc) { - @compileError("TODO implement gethostname when linking 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; @@ -2703,6 +2712,7 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 { return name_buffer[0..hostname.len]; }, EFAULT => unreachable, + EPERM => return error.PermissionDenied, else => |err| return unexpectedErrno(err), } } diff --git a/std/os/bits/darwin.zig b/std/os/bits/darwin.zig index 483d4cda908f157d9a585339ee07cfaa7b6ad9b0..b21498ba2d0b8fa71f3b301ccc26d50ad0c1c22d 100644 --- 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 index 45432a6c076d82ac2845651a70e0f10ce89d8408..f94ff07f58d68b0e6d87dc06542682644a801436 100644 --- 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/netbsd.zig b/std/os/bits/netbsd.zig index ff19d090af715c2b8b05be9f134f8b3a4d9d995d..5036e1e9a11bb00784e49b1be8875f13c18f99cb 100644 --- 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/test.zig b/std/os/test.zig index a821c5dd9fe2acd9e1fbdbcfc7b63a72137c0c0a..d886597a381089ca9231477cae981d018ec58ff3 100644 --- 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); +} -- 2.54.0