// File: qian-jiahong[P]uvncrep017-ws/repeater.cpp
// Function: writeExact(int, char*, int, int)
int writeExact(int sock, char *buf, int len, int timeOutSecs)
{
    int n;
    int timeOutCtr;

    debug(LEVEL_3, "writeExact(): start\n");
    timeOutCtr=0;
    while ((len > 0) && (timeOutCtr < timeOutSecs)) {
        n = send(sock, buf, len, MSG_DONTWAIT);

        if (n > 0) {
            buf += n;
            len -= n;
        }
        else if (n == 0) {
            debug(LEVEL_3, "writeExact(): send returned 0\n");
            return -1;
        }
        else {
            //send() returned -1 to indicate some error
            //Because we use non-blocking in send(), we have to 
            //handle EAGAIN by incrementing timeout counter
            if (errno == EAGAIN) {
                debug(LEVEL_3, "writeExact(): EAGAIN detected\n");
                sleep(1);
                timeOutCtr++;
            }
            else {
                debug(LEVEL_3, "writeExact(): send() returned error, errno = %d (%s)\n", errno, strerror(errno));
                return -1;
            }
        }
    }

    if (timeOutCtr <  timeOutSecs) {
        debug(LEVEL_3, "writeExact(): returning normally\n");
        return 1;
    }
    else {
        debug(LEVEL_3, "writeExact(): timeout error\n");
        return -2;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl $0x3, %edi
leaq 0x74bd(%rip), %rsi      # 0xa0ce
movb $0x0, %al
callq 0x2480
movl $0x0, -0x20(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x14(%rbp)
movb %al, -0x21(%rbp)
jle 0x2c36
movl -0x20(%rbp), %eax
cmpl -0x18(%rbp), %eax
setl %al
movb %al, -0x21(%rbp)
movb -0x21(%rbp), %al
testb $0x1, %al
jne 0x2c42
jmp 0x2d19
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
movslq -0x14(%rbp), %rdx
movl $0x40, %ecx
callq 0x2110
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jle 0x2c81
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x10(%rbp)
movl -0x1c(%rbp), %ecx
movl -0x14(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x14(%rbp)
jmp 0x2d14
cmpl $0x0, -0x1c(%rbp)
jne 0x2ca6
movl $0x3, %edi
leaq 0x7450(%rip), %rsi      # 0xa0e3
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2d57
callq 0x2030
cmpl $0xb, (%rax)
jne 0x2cd8
movl $0x3, %edi
leaq 0x7446(%rip), %rsi      # 0xa102
movb $0x0, %al
callq 0x2480
movl $0x1, %edi
callq 0x2170
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x2d10
callq 0x2030
movl (%rax), %eax
movl %eax, -0x28(%rbp)
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movl -0x28(%rbp), %edx
movq %rax, %rcx
movl $0x3, %edi
leaq 0x7421(%rip), %rsi      # 0xa121
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2d57
jmp 0x2d12
jmp 0x2d14
jmp 0x2c1f
movl -0x20(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x2d3d
movl $0x3, %edi
leaq 0x742a(%rip), %rsi      # 0xa157
movb $0x0, %al
callq 0x2480
movl $0x1, -0x4(%rbp)
jmp 0x2d57
movl $0x3, %edi
leaq 0x7430(%rip), %rsi      # 0xa179
movb $0x0, %al
callq 0x2480
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq