#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct addrinfo {
  char *ai_canonname;
  struct addrinfo *ai_next;
  int /*<<< orphan*/ ai_flags;
  int /*<<< orphan*/ ai_socktype;
  int /*<<< orphan*/ ai_family;
};
typedef int /*<<< orphan*/ host;

/* Variables and functions */
int /*<<< orphan*/ AF_UNSPEC;
int /*<<< orphan*/ AI_CANONNAME;
int /*<<< orphan*/ SOCK_DGRAM;
int /*<<< orphan*/ freeaddrinfo(struct addrinfo *);
scalar_t__ getaddrinfo(char *, char *, struct addrinfo *, struct addrinfo **);
scalar_t__ gethostname(char *, int);
int /*<<< orphan*/ memset(struct addrinfo *, int /*<<< orphan*/, int);
char *strdup(char *);
char *sockaddr_hostname(void) {
  char host[256] = "";
  if (gethostname(host, sizeof(host)) != 0) {
    return NULL;
  }
  host[sizeof(host) - 1] = '\0';
  struct addrinfo hints, *info = NULL;
  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_flags = AI_CANONNAME;
  if (getaddrinfo(host, "domain", &hints, &info) != 0) {
    return NULL;
  }
  char *hname = NULL;
  struct addrinfo *p = NULL;
  for (p = info; p != NULL; p = p->ai_next) {
    if (p->ai_canonname) {
      hname = strdup(p->ai_canonname);
      break;
    }
  }
  if (hname == NULL) {
    hname = strdup(host);
  }
  freeaddrinfo(info);
  return hname;
}


x86 assembly (clang, -O0):
<sockaddr_hostname>:
push   %rbp
mov    %rsp,%rbp
sub    $0x150,%rsp
lea    -0x110(%rbp),%rdi
xor    %esi,%esi
mov    $0x100,%edx
call   1030 <memset@plt>
lea    -0x110(%rbp),%rdi
mov    $0x100,%esi
call   1040 <gethostname@plt>
cmp    $0x0,%rax
je     1196 <sockaddr_hostname+0x46>
movq   $0x0,-0x8(%rbp)
jmp    12cf <sockaddr_hostname+0x17f>
movb   $0x0,-0x11(%rbp)
movq   $0x0,-0x138(%rbp)
lea    -0x130(%rbp),%rdi
xor    %esi,%esi
mov    $0x20,%edx
call   1030 <memset@plt>
mov    0x2e29(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x118(%rbp)
mov    0x2e0a(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x11c(%rbp)
mov    0x2e03(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x120(%rbp)
lea    -0x110(%rbp),%rdi
lea    0xe0d(%rip),%rsi
lea    -0x130(%rbp),%rdx
lea    -0x138(%rbp),%rcx
call   1050 <getaddrinfo@plt>
cmp    $0x0,%rax
je     121d <sockaddr_hostname+0xcd>
movq   $0x0,-0x8(%rbp)
jmp    12cf <sockaddr_hostname+0x17f>
movq   $0x0,-0x140(%rbp)
movq   $0x0,-0x148(%rbp)
mov    -0x138(%rbp),%rax
mov    %rax,-0x148(%rbp)
cmpq   $0x0,-0x148(%rbp)
je     1297 <sockaddr_hostname+0x147>
mov    -0x148(%rbp),%rax
cmpq   $0x0,(%rax)
je     127b <sockaddr_hostname+0x12b>
mov    -0x148(%rbp),%rax
mov    (%rax),%rdi
call   1060 <strdup@plt>
mov    %rax,-0x140(%rbp)
jmp    1297 <sockaddr_hostname+0x147>
jmp    1280 <sockaddr_hostname+0x130>
mov    -0x148(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x148(%rbp)
jmp    1241 <sockaddr_hostname+0xf1>
cmpq   $0x0,-0x140(%rbp)
jne    12b8 <sockaddr_hostname+0x168>
lea    -0x110(%rbp),%rdi
call   1060 <strdup@plt>
mov    %rax,-0x140(%rbp)
mov    -0x138(%rbp),%rdi
call   1070 <freeaddrinfo@plt>
mov    -0x140(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x150,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sockaddr_hostname>:
push   %r14
push   %rbx
sub    $0x138,%rsp
xorps  %xmm0,%xmm0
movaps %xmm0,0x120(%rsp)
movaps %xmm0,0x110(%rsp)
movaps %xmm0,0x100(%rsp)
movaps %xmm0,0xf0(%rsp)
movaps %xmm0,0xe0(%rsp)
movaps %xmm0,0xd0(%rsp)
movaps %xmm0,0xc0(%rsp)
movaps %xmm0,0xb0(%rsp)
movaps %xmm0,0xa0(%rsp)
movaps %xmm0,0x90(%rsp)
movaps %xmm0,0x80(%rsp)
movaps %xmm0,0x70(%rsp)
movaps %xmm0,0x60(%rsp)
movaps %xmm0,0x50(%rsp)
movaps %xmm0,0x40(%rsp)
movaps %xmm0,0x30(%rsp)
lea    0x30(%rsp),%rdi
mov    $0x100,%esi
call   1040 <gethostname@plt>
test   %rax,%rax
je     11e9 <sockaddr_hostname+0x99>
xor    %ebx,%ebx
jmp    12a5 <sockaddr_hostname+0x155>
movb   $0x0,0x12f(%rsp)
movq   $0x0,0x8(%rsp)
lea    0x10(%rsp),%r14
xor    %ebx,%ebx
mov    %r14,%rdi
xor    %esi,%esi
mov    $0x20,%edx
call   1030 <memset@plt>
mov    0x2dd1(%rip),%rax
mov    (%rax),%eax
mov    %eax,0x28(%rsp)
mov    0x2db4(%rip),%rax
mov    (%rax),%eax
mov    %eax,0x24(%rsp)
mov    0x2daf(%rip),%rax
mov    (%rax),%eax
mov    %eax,0x20(%rsp)
lea    0xdc2(%rip),%rsi
lea    0x30(%rsp),%rdi
lea    0x8(%rsp),%rcx
mov    %r14,%rdx
call   1050 <getaddrinfo@plt>
test   %rax,%rax
jne    12a5 <sockaddr_hostname+0x155>
mov    0x8(%rsp),%r14
test   %r14,%r14
je     1290 <sockaddr_hostname+0x140>
mov    %r14,%rax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    (%rax),%rdi
test   %rdi,%rdi
jne    1283 <sockaddr_hostname+0x133>
mov    0x8(%rax),%rax
test   %rax,%rax
jne    1270 <sockaddr_hostname+0x120>
jmp    1290 <sockaddr_hostname+0x140>
call   1060 <strdup@plt>
mov    %rax,%rbx
test   %rax,%rax
jne    129d <sockaddr_hostname+0x14d>
lea    0x30(%rsp),%rdi
call   1060 <strdup@plt>
mov    %rax,%rbx
mov    %r14,%rdi
call   1070 <freeaddrinfo@plt>
mov    %rbx,%rax
add    $0x138,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%struct.addrinfo = type { i8*, %struct.addrinfo*, i32, i32, i32 }
@AF_UNSPEC = global i32 0
@SOCK_DGRAM = global i32 0
@AI_CANONNAME = global i32 0
@.str = [7 x i8] c"domain\00"
define i8* @sockaddr_hostname() {
%1 = alloca i8*
%2 = alloca [256 x i8]
%3 = alloca %struct.addrinfo
%4 = alloca %struct.addrinfo*
%5 = alloca i8*
%6 = alloca %struct.addrinfo*
%7 = bitcast [256 x i8]* %2 to i8*
%8 = getelementptr inbounds [256 x i8], [256 x i8]* %2, i64 0, i64 0
%9 = call i64 @gethostname(i8* %8, i32 256)
%10 = icmp ne i64 %9, 0
br i1 %10, label %11, label %12
11: ; preds = %0
store i8* null, i8** %1
br label %55
12: ; preds = %0
%13 = getelementptr inbounds [256 x i8], [256 x i8]* %2, i64 0, i64 255
store i8 0, i8* %13
store %struct.addrinfo* null, %struct.addrinfo** %4
%14 = call i32 @memset(%struct.addrinfo* %3, i32 0, i32 32)
%15 = load i32, i32* @AF_UNSPEC
%16 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %3, i32 0, i32 4
store i32 %15, i32* %16
%17 = load i32, i32* @SOCK_DGRAM
%18 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %3, i32 0, i32 3
store i32 %17, i32* %18
%19 = load i32, i32* @AI_CANONNAME
%20 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %3, i32 0, i32 2
store i32 %19, i32* %20
%21 = getelementptr inbounds [256 x i8], [256 x i8]* %2, i64 0, i64 0
%22 = call i64 @getaddrinfo(i8* %21, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0), %struct.addrinfo* %3, %struct.addrinfo** %4)
%23 = icmp ne i64 %22, 0
br i1 %23, label %24, label %25
24: ; preds = %12
store i8* null, i8** %1
br label %55
25: ; preds = %12
store i8* null, i8** %5
store %struct.addrinfo* null, %struct.addrinfo** %6
%26 = load %struct.addrinfo*, %struct.addrinfo** %4
store %struct.addrinfo* %26, %struct.addrinfo** %6
br label %27
27: ; preds = %41, %25
%28 = load %struct.addrinfo*, %struct.addrinfo** %6
%29 = icmp ne %struct.addrinfo* %28, null
br i1 %29, label %30, label %45
30: ; preds = %27
%31 = load %struct.addrinfo*, %struct.addrinfo** %6
%32 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %31, i32 0, i32 0
%33 = load i8*, i8** %32
%34 = icmp ne i8* %33, null
br i1 %34, label %35, label %40
35: ; preds = %30
%36 = load %struct.addrinfo*, %struct.addrinfo** %6
%37 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %36, i32 0, i32 0
%38 = load i8*, i8** %37
%39 = call i8* @strdup(i8* %38)
store i8* %39, i8** %5
br label %45
40: ; preds = %30
br label %41
41: ; preds = %40
%42 = load %struct.addrinfo*, %struct.addrinfo** %6
%43 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %42, i32 0, i32 1
%44 = load %struct.addrinfo*, %struct.addrinfo** %43
store %struct.addrinfo* %44, %struct.addrinfo** %6
br label %27
45: ; preds = %35, %27
%46 = load i8*, i8** %5
%47 = icmp eq i8* %46, null
br i1 %47, label %48, label %51
48: ; preds = %45
%49 = getelementptr inbounds [256 x i8], [256 x i8]* %2, i64 0, i64 0
%50 = call i8* @strdup(i8* %49)
store i8* %50, i8** %5
br label %51
51: ; preds = %48, %45
%52 = load %struct.addrinfo*, %struct.addrinfo** %4
%53 = call i32 @freeaddrinfo(%struct.addrinfo* %52)
%54 = load i8*, i8** %5
store i8* %54, i8** %1
br label %55
55: ; preds = %51, %24, %11
%56 = load i8*, i8** %1
ret i8* %56
}

LLVM IR (-O2):
%struct.addrinfo = type { i8*, %struct.addrinfo*, i32, i32, i32 }
@AF_UNSPEC = global i32 0
@SOCK_DGRAM = global i32 0
@AI_CANONNAME = global i32 0
@.str = [7 x i8] c"domain\00"
define i8* @sockaddr_hostname() {
%1 = alloca [256 x i8]
%2 = alloca %struct.addrinfo
%3 = alloca %struct.addrinfo*
%4 = getelementptr inbounds [256 x i8], [256 x i8]* %1, i64 0, i64 0
%5 = call i64 @gethostname(i8* %4, i32 256)
%6 = icmp eq i64 %5, 0
br i1 %6, label %7, label %42
7: ; preds = %0
%8 = getelementptr inbounds [256 x i8], [256 x i8]* %1, i64 0, i64 255
store i8 0, i8* %8
%9 = bitcast %struct.addrinfo* %2 to i8*
%10 = bitcast %struct.addrinfo** %3 to i8*
store %struct.addrinfo* null, %struct.addrinfo** %3
%11 = call i32 @memset(%struct.addrinfo* %2, i32 0, i32 32)
%12 = load i32, i32* @AF_UNSPEC
%13 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %2, i64 0, i32 4
store i32 %12, i32* %13
%14 = load i32, i32* @SOCK_DGRAM
%15 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %2, i64 0, i32 3
store i32 %14, i32* %15
%16 = load i32, i32* @AI_CANONNAME
%17 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %2, i64 0, i32 2
store i32 %16, i32* %17
%18 = call i64 @getaddrinfo(i8* %4, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0), %struct.addrinfo* %2, %struct.addrinfo** %3)
%19 = icmp eq i64 %18, 0
br i1 %19, label %20, label %40
20: ; preds = %7
%21 = load %struct.addrinfo*, %struct.addrinfo** %3
%22 = icmp eq %struct.addrinfo* %21, null
br i1 %22, label %35, label %27
23: ; preds = %27
%24 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %28, i64 0, i32 1
%25 = load %struct.addrinfo*, %struct.addrinfo** %24
%26 = icmp eq %struct.addrinfo* %25, null
br i1 %26, label %35, label %27
27: ; preds = %20, %23
%28 = phi %struct.addrinfo* [ %25, %23 ], [ %21, %20 ]
%29 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %28, i64 0, i32 0
%30 = load i8*, i8** %29
%31 = icmp eq i8* %30, null
br i1 %31, label %23, label %32
32: ; preds = %27
%33 = call i8* @strdup(i8* %30)
%34 = icmp eq i8* %33, null
br i1 %34, label %35, label %37
35: ; preds = %23, %20, %32
%36 = call i8* @strdup(i8* %4)
br label %37
37: ; preds = %35, %32
%38 = phi i8* [ %36, %35 ], [ %33, %32 ]
%39 = call i32 @freeaddrinfo(%struct.addrinfo* %21)
br label %40
40: ; preds = %7, %37
%41 = phi i8* [ %38, %37 ], [ null, %7 ]
br label %42
42: ; preds = %0, %40
%43 = phi i8* [ %41, %40 ], [ null, %0 ]
ret i8* %43
}