#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 sockaddr_un {
  int /*<<< orphan*/ *sun_path;
  void *sun_family;
};
struct sockaddr {
  int dummy;
};
typedef int /*<<< orphan*/ addr1;
typedef int /*<<< orphan*/ addr0;

/* Variables and functions */
void *AF_UNIX;
int /*<<< orphan*/ PF_UNIX;
int /*<<< orphan*/ SOCK_DGRAM;
scalar_t__ bind(int, struct sockaddr *, int);
int /*<<< orphan*/ child_process(int, struct sockaddr *);
int /*<<< orphan*/ close(int);
int /*<<< orphan*/ exit(int);
int fork();
int /*<<< orphan*/ memset(struct sockaddr_un *, int /*<<< orphan*/, int);
int /*<<< orphan*/ parent_process(int, struct sockaddr *);
int /*<<< orphan*/ perror(char *);
int /*<<< orphan*/ printf(char *, int, int);
int socket(int /*<<< orphan*/, int /*<<< orphan*/, int /*<<< orphan*/);
int /*<<< orphan*/ strcpy(int /*<<< orphan*/ *, char *);
int /*<<< orphan*/ wait(int /*<<< orphan*/ *);
int main(void) {
  int sock[2];
  struct sockaddr_un addr0, addr1;
  memset(&addr0, 0, sizeof(addr0));
  addr0.sun_family = AF_UNIX;
  strcpy(&addr0.sun_path[1], "ancil_test_sock0");
  memset(&addr1, 0, sizeof(addr1));
  addr1.sun_family = AF_UNIX;
  strcpy(&addr1.sun_path[1], "ancil_test_sock1");
  sock[0] = socket(PF_UNIX, SOCK_DGRAM, 0);
  if (sock[0] < 0) {
    perror("socket");
    exit(1);
  }
  if (bind(sock[0], (struct sockaddr *)&addr0, sizeof(addr0)) < 0) {
    perror("bind");
    exit(1);
  }
  sock[1] = socket(PF_UNIX, SOCK_DGRAM, 0);
  if (sock[1] < 0) {
    perror("socket");
    exit(1);
  }
  if (bind(sock[1], (struct sockaddr *)&addr1, sizeof(addr1)) < 0) {
    perror("bind");
    exit(1);
  }
  printf("Established socket pair: (%d, %d)\n", sock[0], sock[1]);
  switch (fork()) {
  case 0:
    close(sock[0]);
    child_process(sock[1], (struct sockaddr *)&addr0);
    break;
  case -1:
    perror("fork");
    exit(1);
  default:
    close(sock[1]);
    parent_process(sock[0], (struct sockaddr *)&addr1);
    wait(NULL);
    break;
  }
  return (0);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movl   $0x0,-0x4(%rbp)
lea    -0x20(%rbp),%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1070 <memset@plt>
mov    0x2dfa(%rip),%rax
mov    (%rax),%rax
mov    %rax,-0x18(%rbp)
mov    -0x20(%rbp),%rdi
add    $0x4,%rdi
lea    0xe04(%rip),%rsi
call   1030 <strcpy@plt>
lea    -0x30(%rbp),%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1070 <memset@plt>
mov    0x2dc8(%rip),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rdi
add    $0x4,%rdi
lea    0xde3(%rip),%rsi
call   1030 <strcpy@plt>
mov    0x2dbe(%rip),%rax
mov    (%rax),%edi
mov    0x2d95(%rip),%rax
mov    (%rax),%esi
xor    %edx,%edx
call   10e0 <socket@plt>
mov    %eax,-0xc(%rbp)
cmpl   $0x0,-0xc(%rbp)
jge    126f <main+0xaf>
lea    0xdc2(%rip),%rdi
call   10a0 <perror@plt>
mov    $0x1,%edi
call   10b0 <exit@plt>
mov    -0xc(%rbp),%edi
lea    -0x20(%rbp),%rsi
mov    $0x10,%edx
call   1090 <bind@plt>
cmp    $0x0,%rax
jge    12a0 <main+0xe0>
lea    0xd98(%rip),%rdi
call   10a0 <perror@plt>
mov    $0x1,%edi
call   10b0 <exit@plt>
mov    0x2d51(%rip),%rax
mov    (%rax),%edi
mov    0x2d28(%rip),%rax
mov    (%rax),%esi
xor    %edx,%edx
call   10e0 <socket@plt>
mov    %eax,-0x8(%rbp)
cmpl   $0x0,-0x8(%rbp)
jge    12dc <main+0x11c>
lea    0xd55(%rip),%rdi
call   10a0 <perror@plt>
mov    $0x1,%edi
call   10b0 <exit@plt>
mov    -0x8(%rbp),%edi
lea    -0x30(%rbp),%rsi
mov    $0x10,%edx
call   1090 <bind@plt>
cmp    $0x0,%rax
jge    130d <main+0x14d>
lea    0xd2b(%rip),%rdi
call   10a0 <perror@plt>
mov    $0x1,%edi
call   10b0 <exit@plt>
mov    -0xc(%rbp),%esi
mov    -0x8(%rbp),%edx
lea    0xd14(%rip),%rdi
call   1050 <printf@plt>
xor    %eax,%eax
call   10d0 <fork@plt>
mov    %eax,%ecx
mov    %ecx,-0x34(%rbp)
sub    $0xffffffff,%eax
je     1362 <main+0x1a2>
jmp    1339 <main+0x179>
mov    -0x34(%rbp),%eax
test   %eax,%eax
jne    1378 <main+0x1b8>
jmp    1349 <main+0x189>
mov    -0xc(%rbp),%edi
call   1080 <close@plt>
mov    -0x8(%rbp),%edi
lea    -0x20(%rbp),%rsi
call   1060 <child_process@plt>
jmp    1395 <main+0x1d5>
lea    0xce8(%rip),%rdi
call   10a0 <perror@plt>
mov    $0x1,%edi
call   10b0 <exit@plt>
mov    -0x8(%rbp),%edi
call   1080 <close@plt>
mov    -0xc(%rbp),%edi
lea    -0x30(%rbp),%rsi
call   1040 <parent_process@plt>
xor    %eax,%eax
mov    %eax,%edi
call   10c0 <wait@plt>
xor    %eax,%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
lea    0x10(%rsp),%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1070 <memset@plt>
mov    0x2e00(%rip),%rbx
mov    (%rbx),%rax
mov    %rax,0x18(%rsp)
mov    0x10(%rsp),%rdi
add    $0x4,%rdi
lea    0xe08(%rip),%rsi
call   1030 <strcpy@plt>
mov    %rsp,%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1070 <memset@plt>
mov    (%rbx),%rax
mov    %rax,0x8(%rsp)
mov    (%rsp),%rdi
add    $0x4,%rdi
lea    0xdee(%rip),%rsi
call   1030 <strcpy@plt>
mov    0x2dc9(%rip),%r14
mov    (%r14),%edi
mov    0x2d9f(%rip),%rbp
mov    0x0(%rbp),%esi
xor    %edx,%edx
call   10e0 <socket@plt>
test   %eax,%eax
js     12e6 <main+0x126>
mov    %eax,%ebx
lea    0x10(%rsp),%rsi
mov    %eax,%edi
mov    $0x10,%edx
call   1090 <bind@plt>
test   %rax,%rax
js     12ef <main+0x12f>
mov    (%r14),%edi
mov    0x0(%rbp),%esi
xor    %edx,%edx
call   10e0 <socket@plt>
test   %eax,%eax
js     12e6 <main+0x126>
mov    %eax,%ebp
mov    %rsp,%rsi
mov    %eax,%edi
mov    $0x10,%edx
call   1090 <bind@plt>
test   %rax,%rax
js     12ef <main+0x12f>
lea    0xd99(%rip),%rdi
mov    %ebx,%esi
mov    %ebp,%edx
call   1050 <printf@plt>
xor    %eax,%eax
call   10d0 <fork@plt>
test   %eax,%eax
je     12c8 <main+0x108>
cmp    $0xffffffff,%eax
je     12f8 <main+0x138>
mov    %ebp,%edi
call   1080 <close@plt>
mov    %rsp,%rsi
mov    %ebx,%edi
call   1040 <parent_process@plt>
xor    %edi,%edi
call   10c0 <wait@plt>
jmp    12db <main+0x11b>
mov    %ebx,%edi
call   1080 <close@plt>
lea    0x10(%rsp),%rsi
mov    %ebp,%edi
call   1060 <child_process@plt>
xor    %eax,%eax
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret
lea    0xd35(%rip),%rdi
jmp    12ff <main+0x13f>
lea    0xd33(%rip),%rdi
jmp    12ff <main+0x13f>
lea    0xd52(%rip),%rdi
call   10a0 <perror@plt>
mov    $0x1,%edi
call   10b0 <exit@plt>

LLVM IR (-O0):
%struct.sockaddr_un = type { i32*, i8* }
%struct.sockaddr = type { i32 }
@AF_UNIX = global i8* null
@.str = [17 x i8] c"ancil_test_sock0\00"
@.str.1 = [17 x i8] c"ancil_test_sock1\00"
@PF_UNIX = global i32 0
@SOCK_DGRAM = global i32 0
@.str.2 = [7 x i8] c"socket\00"
@.str.3 = [5 x i8] c"bind\00"
@.str.4 = [35 x i8] c"Established socket pair: (%d, %d)\0A\00"
@.str.5 = [5 x i8] c"fork\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [2 x i32]
%3 = alloca %struct.sockaddr_un
%4 = alloca %struct.sockaddr_un
store i32 0, i32* %1
%5 = call i32 @memset(%struct.sockaddr_un* %3, i32 0, i32 16)
%6 = load i8*, i8** @AF_UNIX
%7 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %3, i32 0, i32 1
store i8* %6, i8** %7
%8 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %3, i32 0, i32 0
%9 = load i32*, i32** %8
%10 = getelementptr inbounds i32, i32* %9, i64 1
%11 = call i32 @strcpy(i32* %10, i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i64 0, i64 0))
%12 = call i32 @memset(%struct.sockaddr_un* %4, i32 0, i32 16)
%13 = load i8*, i8** @AF_UNIX
%14 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %4, i32 0, i32 1
store i8* %13, i8** %14
%15 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %4, i32 0, i32 0
%16 = load i32*, i32** %15
%17 = getelementptr inbounds i32, i32* %16, i64 1
%18 = call i32 @strcpy(i32* %17, i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0))
%19 = load i32, i32* @PF_UNIX
%20 = load i32, i32* @SOCK_DGRAM
%21 = call i32 @socket(i32 %19, i32 %20, i32 0)
%22 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
store i32 %21, i32* %22
%23 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%24 = load i32, i32* %23
%25 = icmp slt i32 %24, 0
br i1 %25, label %26, label %29
26: ; preds = %0
%27 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0))
%28 = call i32 @exit(i32 1)
unreachable
29: ; preds = %0
%30 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%31 = load i32, i32* %30
%32 = bitcast %struct.sockaddr_un* %3 to %struct.sockaddr*
%33 = call i64 @bind(i32 %31, %struct.sockaddr* %32, i32 16)
%34 = icmp slt i64 %33, 0
br i1 %34, label %35, label %38
35: ; preds = %29
%36 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i64 0, i64 0))
%37 = call i32 @exit(i32 1)
unreachable
38: ; preds = %29
%39 = load i32, i32* @PF_UNIX
%40 = load i32, i32* @SOCK_DGRAM
%41 = call i32 @socket(i32 %39, i32 %40, i32 0)
%42 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
store i32 %41, i32* %42
%43 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%44 = load i32, i32* %43
%45 = icmp slt i32 %44, 0
br i1 %45, label %46, label %49
46: ; preds = %38
%47 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0))
%48 = call i32 @exit(i32 1)
unreachable
49: ; preds = %38
%50 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%51 = load i32, i32* %50
%52 = bitcast %struct.sockaddr_un* %4 to %struct.sockaddr*
%53 = call i64 @bind(i32 %51, %struct.sockaddr* %52, i32 16)
%54 = icmp slt i64 %53, 0
br i1 %54, label %55, label %58
55: ; preds = %49
%56 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i64 0, i64 0))
%57 = call i32 @exit(i32 1)
unreachable
58: ; preds = %49
%59 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%60 = load i32, i32* %59
%61 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%62 = load i32, i32* %61
%63 = call i32 @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @.str.4, i64 0, i64 0), i32 %60, i32 %62)
%64 = call i32 (...) @fork()
switch i32 %64, label %76 [
i32 0, label %65
i32 -1, label %73
]
65: ; preds = %58
%66 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%67 = load i32, i32* %66
%68 = call i32 @close(i32 %67)
%69 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%70 = load i32, i32* %69
%71 = bitcast %struct.sockaddr_un* %3 to %struct.sockaddr*
%72 = call i32 @child_process(i32 %70, %struct.sockaddr* %71)
br label %85
73: ; preds = %58
%74 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i64 0, i64 0))
%75 = call i32 @exit(i32 1)
unreachable
76: ; preds = %58
%77 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%78 = load i32, i32* %77
%79 = call i32 @close(i32 %78)
%80 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%81 = load i32, i32* %80
%82 = bitcast %struct.sockaddr_un* %4 to %struct.sockaddr*
%83 = call i32 @parent_process(i32 %81, %struct.sockaddr* %82)
%84 = call i32 @wait(i32* null)
br label %85
85: ; preds = %76, %65
ret i32 0
}

LLVM IR (-O2):
%struct.sockaddr_un = type { i32*, i8* }
%struct.sockaddr = type { i32 }
@AF_UNIX = global i8* null
@.str = [17 x i8] c"ancil_test_sock0\00"
@.str.1 = [17 x i8] c"ancil_test_sock1\00"
@PF_UNIX = global i32 0
@SOCK_DGRAM = global i32 0
@.str.2 = [7 x i8] c"socket\00"
@.str.3 = [5 x i8] c"bind\00"
@.str.4 = [35 x i8] c"Established socket pair: (%d, %d)\0A\00"
@.str.5 = [5 x i8] c"fork\00"
define i32 @main() {
%1 = alloca %struct.sockaddr_un
%2 = alloca %struct.sockaddr_un
%3 = bitcast %struct.sockaddr_un* %1 to i8*
%4 = bitcast %struct.sockaddr_un* %2 to i8*
%5 = call i32 @memset(%struct.sockaddr_un* %1, i32 0, i32 16)
%6 = load i8*, i8** @AF_UNIX
%7 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %1, i64 0, i32 1
store i8* %6, i8** %7
%8 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %1, i64 0, i32 0
%9 = load i32*, i32** %8
%10 = getelementptr inbounds i32, i32* %9, i64 1
%11 = call i32 @strcpy(i32* %10, i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i64 0, i64 0))
%12 = call i32 @memset(%struct.sockaddr_un* %2, i32 0, i32 16)
%13 = load i8*, i8** @AF_UNIX
%14 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %2, i64 0, i32 1
store i8* %13, i8** %14
%15 = getelementptr inbounds %struct.sockaddr_un, %struct.sockaddr_un* %2, i64 0, i32 0
%16 = load i32*, i32** %15
%17 = getelementptr inbounds i32, i32* %16, i64 1
%18 = call i32 @strcpy(i32* %17, i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0))
%19 = load i32, i32* @PF_UNIX
%20 = load i32, i32* @SOCK_DGRAM
%21 = call i32 @socket(i32 %19, i32 %20, i32 0)
%22 = icmp slt i32 %21, 0
br i1 %22, label %23, label %26
23: ; preds = %0
%24 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0))
%25 = call i32 @exit(i32 1)
unreachable
26: ; preds = %0
%27 = bitcast %struct.sockaddr_un* %1 to %struct.sockaddr*
%28 = call i64 @bind(i32 %21, %struct.sockaddr* %27, i32 16)
%29 = icmp slt i64 %28, 0
br i1 %29, label %30, label %33
30: ; preds = %26
%31 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i64 0, i64 0))
%32 = call i32 @exit(i32 1)
unreachable
33: ; preds = %26
%34 = load i32, i32* @PF_UNIX
%35 = load i32, i32* @SOCK_DGRAM
%36 = call i32 @socket(i32 %34, i32 %35, i32 0)
%37 = icmp slt i32 %36, 0
br i1 %37, label %38, label %41
38: ; preds = %33
%39 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0))
%40 = call i32 @exit(i32 1)
unreachable
41: ; preds = %33
%42 = bitcast %struct.sockaddr_un* %2 to %struct.sockaddr*
%43 = call i64 @bind(i32 %36, %struct.sockaddr* %42, i32 16)
%44 = icmp slt i64 %43, 0
br i1 %44, label %45, label %48
45: ; preds = %41
%46 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i64 0, i64 0))
%47 = call i32 @exit(i32 1)
unreachable
48: ; preds = %41
%49 = call i32 @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @.str.4, i64 0, i64 0), i32 %21, i32 %36)
%50 = call i32 (...) @fork()
switch i32 %50, label %57 [
i32 0, label %51
i32 -1, label %54
]
51: ; preds = %48
%52 = call i32 @close(i32 %21)
%53 = call i32 @child_process(i32 %36, %struct.sockaddr* %27)
br label %61
54: ; preds = %48
%55 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i64 0, i64 0))
%56 = call i32 @exit(i32 1)
unreachable
57: ; preds = %48
%58 = call i32 @close(i32 %36)
%59 = call i32 @parent_process(i32 %21, %struct.sockaddr* %42)
%60 = call i32 @wait(i32* null)
br label %61
61: ; preds = %57, %51
ret i32 0
}