// File: /workspace/github_c_makefile_star2_O2/hasindu2008[P]f5p/socket.c
// Function: TCP_server_init
int TCP_server_init(int PORT) {
    //initialize variables
    int listenfd, ret;
    struct sockaddr_in server;

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(PORT);

    //open socket bind and listen
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    errorCheck(listenfd, "Cannot create socket");

    /****sophisticated way of binding*/

    //This lets a port be used as soon as the using program ends. Otherwise you will get "Cannot bind : Address is used"
    //for few minutes after the program that previously used the port exists
    int enable = 1;
    if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) <
        0 && verbose_socklibc>=1) {
        WARNING("%s", "setsockopt(SO_REUSEADDR) failed");
    }

    //try binding
    ret = -1;
    while (ret == -1) {
        ret = bind(listenfd, (struct sockaddr*)&server, sizeof(server));
        if (ret == -1) {
            
			if(verbose_socklibc>=1){
				WARNING(
                "%s",
                "Cannot bind to address as it is already used. Trying again.");
			}
            sleep(1);
        }
    }

    /*** end of the sophisticated way*/

    /*following (commented) is the simplest way of doing it. But You will get "Cannot bind : Address is used"
    for few minutes after the program that used the port exited */
    //ret=bind(listenfd,(struct sockaddr *)&server, sizeof(server));

    errorCheck(ret, "Cannot bind");
    if(verbose_socklibc>=4){
		INFO("Binding successfull to port %d.", PORT);
	}

    //now listen
    ret = listen(listenfd, 5);
    errorCheck(ret, "Cannot listen");
	if(verbose_socklibc>=4){
		INFO("Listening on port %d.", PORT);
	}

    return listenfd;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movw $0x2, 0x8(%rsp)
andl $0x0, 0xc(%rsp)
movl %edi, (%rsp)
movl %edi, %eax
rolw $0x8, %ax
movw %ax, 0xa(%rsp)
pushq $0x2
popq %rbx
pushq $0x1
popq %r14
movl %ebx, %edi
movl %r14d, %esi
xorl %edx, %edx
callq 0x1270
movl %eax, %ebp
leaq 0x1986(%rip), %rsi      # 0x30a1
movl %eax, %edi
callq 0x1879
leaq 0x4(%rsp), %rcx
movl $0x1, (%rcx)
pushq $0x4
popq %r8
movl %ebp, %edi
movl %r14d, %esi
movl %ebx, %edx
callq 0x1080
testl %eax, %eax
jns 0x174e
cmpl $0x0, 0x4a08(%rip)      # 0x6150
jg 0x1800
pushq $-0x1
popq %r13
leaq 0x8(%rsp), %r14
pushq $0x10
popq %r15
leaq 0x19a1(%rip), %r12      # 0x3103
pushq $0x1
popq %rbx
cmpl $-0x1, %r13d
jne 0x17b6
movl %ebp, %edi
movq %r14, %rsi
movl %r15d, %edx
callq 0x1190
movl %eax, %r13d
cmpl $-0x1, %eax
jne 0x1765
cmpl $0x0, 0x49c9(%rip)      # 0x6150
jg 0x1792
movl %ebx, %edi
callq 0x1250
jmp 0x1765
movq 0x485f(%rip), %rax      # 0x5ff8
movq (%rax), %rdi
leaq 0x1913(%rip), %rsi      # 0x30b6
leaq 0x1929(%rip), %rdx      # 0x30d3
movq %r12, %rcx
xorl %eax, %eax
callq 0x1130
jmp 0x1789
leaq 0x1982(%rip), %rsi      # 0x313f
movl %r13d, %edi
callq 0x1879
cmpl $0x4, 0x4984(%rip)      # 0x6150
jge 0x182b
pushq $0x5
popq %rsi
movl %ebp, %edi
callq 0x1170
leaq 0x1998(%rip), %rsi      # 0x3177
movl %eax, %edi
callq 0x1879
cmpl $0x4, 0x4963(%rip)      # 0x6150
jge 0x1852
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x47f1(%rip), %rax      # 0x5ff8
movq (%rax), %rdi
leaq 0x18a5(%rip), %rsi      # 0x30b6
leaq 0x18bb(%rip), %rdx      # 0x30d3
leaq 0x18c4(%rip), %rcx      # 0x30e3
xorl %eax, %eax
callq 0x1130
jmp 0x174e
movq 0x47c6(%rip), %rax      # 0x5ff8
movq (%rax), %rdi
leaq 0x190f(%rip), %rsi      # 0x314b
leaq 0x1890(%rip), %rdx      # 0x30d3
movl (%rsp), %ecx
xorl %eax, %eax
callq 0x1130
jmp 0x17ce
movq 0x479f(%rip), %rax      # 0x5ff8
movq (%rax), %rdi
leaq 0x1922(%rip), %rsi      # 0x3185
leaq 0x1869(%rip), %rdx      # 0x30d3
movl (%rsp), %ecx
xorl %eax, %eax
callq 0x1130
jmp 0x17ef