#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 in_addr {
  scalar_t__ s_addr;
};
typedef int /*<<< orphan*/ a;

/* Variables and functions */
int EFAULT;
scalar_t__ INADDR_NONE;
int /*<<< orphan*/ close(int);
int errno;
int /*<<< orphan*/ exit(int /*<<< orphan*/);
int fork();
int /*<<< orphan*/ free(struct in_addr *);
int /*<<< orphan*/ gg_debug(int, char *, int *, int *, char const *);
struct in_addr *gg_gethostbyname(char const *);
scalar_t__ inet_addr(char const *);
int pipe(int *);
int /*<<< orphan*/ write(int, struct in_addr *, int);
int gg_resolve(int *fd, int *pid, const char *hostname) {
  int pipes[2], res;
  struct in_addr a;
  int errno2;
  gg_debug(8, "** gg_resolve(%p, %p, \"%s\");\n", fd, pid, hostname);
  if (!fd || !pid) {
    errno = EFAULT;
    return -1;
  }
  if (pipe(pipes) == -1)
    return -1;
  if ((res = fork()) == -1) {
    errno2 = errno;
    close(pipes[0]);
    close(pipes[1]);
    errno = errno2;
    return -1;
  }
  if (!res) {
    if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) {
      struct in_addr *hn;
      if (!(hn = gg_gethostbyname(hostname)))
        a.s_addr = INADDR_NONE;
      else {
        a.s_addr = hn->s_addr;
        free(hn);
      }
    }
    write(pipes[1], &a, sizeof(a));
    exit(0);
  }
  close(pipes[1]);
  *fd = pipes[0];
  *pid = res;
  return 0;
}


x86 assembly (clang, -O0):
<gg_resolve>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x10(%rbp),%rdx
mov    -0x18(%rbp),%rcx
mov    -0x20(%rbp),%r8
mov    $0x8,%edi
lea    0xe44(%rip),%rsi
call   1090 <gg_debug@plt>
cmpq   $0x0,-0x10(%rbp)
je     11d7 <gg_resolve+0x47>
cmpq   $0x0,-0x18(%rbp)
jne    11f5 <gg_resolve+0x65>
mov    0x2e1a(%rip),%rax
mov    (%rax),%ecx
mov    0x2de9(%rip),%rax
mov    %ecx,(%rax)
movl   $0xffffffff,-0x4(%rbp)
jmp    12fd <gg_resolve+0x16d>
lea    -0x28(%rbp),%rdi
call   1070 <pipe@plt>
cmp    $0xffffffff,%eax
jne    1213 <gg_resolve+0x83>
movl   $0xffffffff,-0x4(%rbp)
jmp    12fd <gg_resolve+0x16d>
mov    $0x0,%al
call   10b0 <fork@plt>
mov    %eax,-0x2c(%rbp)
cmp    $0xffffffff,%eax
jne    125a <gg_resolve+0xca>
mov    0x2da3(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x28(%rbp),%edi
call   1060 <close@plt>
mov    -0x24(%rbp),%edi
call   1060 <close@plt>
mov    -0x3c(%rbp),%ecx
mov    0x2d84(%rip),%rax
mov    %ecx,(%rax)
movl   $0xffffffff,-0x4(%rbp)
jmp    12fd <gg_resolve+0x16d>
cmpl   $0x0,-0x2c(%rbp)
jne    12dc <gg_resolve+0x14c>
mov    -0x20(%rbp),%rdi
call   1080 <inet_addr@plt>
mov    %rax,-0x38(%rbp)
mov    0x2d68(%rip),%rcx
cmp    (%rcx),%rax
jne    12c4 <gg_resolve+0x134>
mov    -0x20(%rbp),%rdi
call   1040 <gg_gethostbyname@plt>
mov    %rax,-0x48(%rbp)
cmp    $0x0,%rax
jne    12ab <gg_resolve+0x11b>
mov    0x2d41(%rip),%rax
mov    (%rax),%rax
mov    %rax,-0x38(%rbp)
jmp    12bf <gg_resolve+0x12f>
mov    -0x48(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x38(%rbp)
mov    -0x48(%rbp),%rdi
call   1030 <free@plt>
jmp    12c4 <gg_resolve+0x134>
mov    -0x24(%rbp),%edi
lea    -0x38(%rbp),%rsi
mov    $0x8,%edx
call   1050 <write@plt>
xor    %edi,%edi
call   10a0 <exit@plt>
mov    -0x24(%rbp),%edi
call   1060 <close@plt>
mov    -0x28(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x2c(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gg_resolve>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x10,%rsp
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%rbx
lea    0xe54(%rip),%rsi
mov    $0x8,%edi
mov    %rbx,%rdx
mov    %r15,%rcx
mov    %r14,%r8
call   1090 <gg_debug@plt>
test   %rbx,%rbx
je     1203 <gg_resolve+0x73>
test   %r15,%r15
je     1203 <gg_resolve+0x73>
mov    %rsp,%rdi
call   1070 <pipe@plt>
mov    $0xffffffff,%ebp
cmp    $0xffffffff,%eax
je     123a <gg_resolve+0xaa>
xor    %eax,%eax
call   10b0 <fork@plt>
cmp    $0xffffffff,%eax
je     121c <gg_resolve+0x8c>
mov    %eax,%r12d
test   %eax,%eax
je     1249 <gg_resolve+0xb9>
mov    0x4(%rsp),%edi
call   1060 <close@plt>
mov    (%rsp),%eax
mov    %eax,(%rbx)
mov    %r12d,(%r15)
xor    %ebp,%ebp
jmp    123a <gg_resolve+0xaa>
mov    0x2dee(%rip),%rax
mov    (%rax),%eax
mov    0x2dbd(%rip),%rcx
mov    %eax,(%rcx)
mov    $0xffffffff,%ebp
jmp    123a <gg_resolve+0xaa>
mov    0x2dad(%rip),%r14
mov    (%r14),%ebx
mov    (%rsp),%edi
call   1060 <close@plt>
mov    0x4(%rsp),%edi
call   1060 <close@plt>
mov    %ebx,(%r14)
mov    %ebp,%eax
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %r14,%rdi
call   1080 <inet_addr@plt>
mov    %rax,0x8(%rsp)
mov    0x2d83(%rip),%rbx
cmp    (%rbx),%rax
jne    1289 <gg_resolve+0xf9>
mov    %r14,%rdi
call   1040 <gg_gethostbyname@plt>
test   %rax,%rax
jne    1279 <gg_resolve+0xe9>
mov    (%rbx),%rax
mov    %rax,0x8(%rsp)
jmp    1289 <gg_resolve+0xf9>
mov    (%rax),%rcx
mov    %rcx,0x8(%rsp)
mov    %rax,%rdi
call   1030 <free@plt>
mov    0x4(%rsp),%edi
lea    0x8(%rsp),%rsi
mov    $0x8,%edx
call   1050 <write@plt>
xor    %edi,%edi
call   10a0 <exit@plt>

LLVM IR (-O0):
%struct.in_addr = type { i64 }
@.str = [30 x i8] c"** gg_resolve(%p, %p, \22%s\22);\0A\00"
@EFAULT = global i32 0
@errno = global i32 0
@INADDR_NONE = global i64 0
define i32 @gg_resolve(i32* %0, i32* %1, i8* %2) {
%4 = alloca i32
%5 = alloca i32*
%6 = alloca i32*
%7 = alloca i8*
%8 = alloca [2 x i32]
%9 = alloca i32
%10 = alloca %struct.in_addr
%11 = alloca i32
%12 = alloca %struct.in_addr*
store i32* %0, i32** %5
store i32* %1, i32** %6
store i8* %2, i8** %7
%13 = load i32*, i32** %5
%14 = load i32*, i32** %6
%15 = load i8*, i8** %7
%16 = call i32 @gg_debug(i32 8, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str, i64 0, i64 0), i32* %13, i32* %14, i8* %15)
%17 = load i32*, i32** %5
%18 = icmp ne i32* %17, null
br i1 %18, label %19, label %22
19: ; preds = %3
%20 = load i32*, i32** %6
%21 = icmp ne i32* %20, null
br i1 %21, label %24, label %22
22: ; preds = %19, %3
%23 = load i32, i32* @EFAULT
store i32 %23, i32* @errno
store i32 -1, i32* %4
br label %79
24: ; preds = %19
%25 = getelementptr inbounds [2 x i32], [2 x i32]* %8, i64 0, i64 0
%26 = call i32 @pipe(i32* %25)
%27 = icmp eq i32 %26, -1
br i1 %27, label %28, label %29
28: ; preds = %24
store i32 -1, i32* %4
br label %79
29: ; preds = %24
%30 = call i32 (...) @fork()
store i32 %30, i32* %9
%31 = icmp eq i32 %30, -1
br i1 %31, label %32, label %41
32: ; preds = %29
%33 = load i32, i32* @errno
store i32 %33, i32* %11
%34 = getelementptr inbounds [2 x i32], [2 x i32]* %8, i64 0, i64 0
%35 = load i32, i32* %34
%36 = call i32 @close(i32 %35)
%37 = getelementptr inbounds [2 x i32], [2 x i32]* %8, i64 0, i64 1
%38 = load i32, i32* %37
%39 = call i32 @close(i32 %38)
%40 = load i32, i32* %11
store i32 %40, i32* @errno
store i32 -1, i32* %4
br label %79
41: ; preds = %29
%42 = load i32, i32* %9
%43 = icmp ne i32 %42, 0
br i1 %43, label %70, label %44
44: ; preds = %41
%45 = load i8*, i8** %7
%46 = call i64 @inet_addr(i8* %45)
%47 = getelementptr inbounds %struct.in_addr, %struct.in_addr* %10, i32 0, i32 0
store i64 %46, i64* %47
%48 = load i64, i64* @INADDR_NONE
%49 = icmp eq i64 %46, %48
br i1 %49, label %50, label %65
50: ; preds = %44
%51 = load i8*, i8** %7
%52 = call %struct.in_addr* @gg_gethostbyname(i8* %51)
store %struct.in_addr* %52, %struct.in_addr** %12
%53 = icmp ne %struct.in_addr* %52, null
br i1 %53, label %57, label %54
54: ; preds = %50
%55 = load i64, i64* @INADDR_NONE
%56 = getelementptr inbounds %struct.in_addr, %struct.in_addr* %10, i32 0, i32 0
store i64 %55, i64* %56
br label %64
57: ; preds = %50
%58 = load %struct.in_addr*, %struct.in_addr** %12
%59 = getelementptr inbounds %struct.in_addr, %struct.in_addr* %58, i32 0, i32 0
%60 = load i64, i64* %59
%61 = getelementptr inbounds %struct.in_addr, %struct.in_addr* %10, i32 0, i32 0
store i64 %60, i64* %61
%62 = load %struct.in_addr*, %struct.in_addr** %12
%63 = call i32 @free(%struct.in_addr* %62)
br label %64
64: ; preds = %57, %54
br label %65
65: ; preds = %64, %44
%66 = getelementptr inbounds [2 x i32], [2 x i32]* %8, i64 0, i64 1
%67 = load i32, i32* %66
%68 = call i32 @write(i32 %67, %struct.in_addr* %10, i32 8)
%69 = call i32 @exit(i32 0)
unreachable
70: ; preds = %41
%71 = getelementptr inbounds [2 x i32], [2 x i32]* %8, i64 0, i64 1
%72 = load i32, i32* %71
%73 = call i32 @close(i32 %72)
%74 = getelementptr inbounds [2 x i32], [2 x i32]* %8, i64 0, i64 0
%75 = load i32, i32* %74
%76 = load i32*, i32** %5
store i32 %75, i32* %76
%77 = load i32, i32* %9
%78 = load i32*, i32** %6
store i32 %77, i32* %78
store i32 0, i32* %4
br label %79
79: ; preds = %70, %32, %28, %22
%80 = load i32, i32* %4
ret i32 %80
}

LLVM IR (-O2):
%struct.in_addr = type { i64 }
@.str = [30 x i8] c"** gg_resolve(%p, %p, \22%s\22);\0A\00"
@EFAULT = global i32 0
@errno = global i32 0
@INADDR_NONE = global i64 0
define i32 @gg_resolve(i32* %0, i32* %1, i8* %2) {
%4 = alloca [2 x i32]
%5 = alloca %struct.in_addr
%6 = bitcast [2 x i32]* %4 to i8*
%7 = bitcast %struct.in_addr* %5 to i8*
%8 = tail call i32 @gg_debug(i32 8, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str, i64 0, i64 0), i32* %0, i32* %1, i8* %2)
%9 = icmp ne i32* %0, null
%10 = icmp ne i32* %1, null
%11 = and i1 %9, %10
br i1 %11, label %14, label %12
12: ; preds = %3
%13 = load i32, i32* @EFAULT
store i32 %13, i32* @errno
br label %51
14: ; preds = %3
%15 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%16 = call i32 @pipe(i32* %15)
%17 = icmp eq i32 %16, -1
br i1 %17, label %51, label %18
18: ; preds = %14
%19 = call i32 (...) @fork()
switch i32 %19, label %46 [
i32 -1, label %20
i32 0, label %27
]
20: ; preds = %18
%21 = load i32, i32* @errno
%22 = load i32, i32* %15
%23 = call i32 @close(i32 %22)
%24 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 1
%25 = load i32, i32* %24
%26 = call i32 @close(i32 %25)
store i32 %21, i32* @errno
br label %51
27: ; preds = %18
%28 = call i64 @inet_addr(i8* %2)
%29 = getelementptr inbounds %struct.in_addr, %struct.in_addr* %5, i64 0, i32 0
store i64 %28, i64* %29
%30 = load i64, i64* @INADDR_NONE
%31 = icmp eq i64 %28, %30
br i1 %31, label %32, label %41
32: ; preds = %27
%33 = call %struct.in_addr* @gg_gethostbyname(i8* %2)
%34 = icmp eq %struct.in_addr* %33, null
br i1 %34, label %35, label %37
35: ; preds = %32
%36 = load i64, i64* @INADDR_NONE
store i64 %36, i64* %29
br label %41
37: ; preds = %32
%38 = getelementptr inbounds %struct.in_addr, %struct.in_addr* %33, i64 0, i32 0
%39 = load i64, i64* %38
store i64 %39, i64* %29
%40 = call i32 @free(%struct.in_addr* %33)
br label %41
41: ; preds = %35, %37, %27
%42 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 1
%43 = load i32, i32* %42
%44 = call i32 @write(i32 %43, %struct.in_addr* %5, i32 8)
%45 = call i32 @exit(i32 0)
unreachable
46: ; preds = %18
%47 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 1
%48 = load i32, i32* %47
%49 = call i32 @close(i32 %48)
%50 = load i32, i32* %15
store i32 %50, i32* %0
store i32 %19, i32* %1
br label %51
51: ; preds = %14, %46, %20, %12
%52 = phi i32 [ -1, %20 ], [ 0, %46 ], [ -1, %12 ], [ -1, %14 ]
ret i32 %52
}