Commit 028011e59a

Andrew Kelley <andrew@ziglang.org>
2019-09-22 21:36:11
libc implementation of gethostname
1 parent e63daca
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;
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;
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;
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);
+}
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;
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);
-}
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),
         }
     }