#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 timeval {
  int tv_sec;
  int tv_usec;
};
typedef int off_t;
typedef int /*<<< orphan*/ buf;

/* Variables and functions */
scalar_t__ EINVAL;
scalar_t__ EWOULDBLOCK;
int /*<<< orphan*/ SEEK_CUR;
int /*<<< orphan*/ SEEK_SET;
scalar_t__ errno;
int filelength(int);
int lseek(int, int, int /*<<< orphan*/);
int read(int, char *, int);
int /*<<< orphan*/ select(int /*<<< orphan*/, int /*<<< orphan*/ *,
                          int /*<<< orphan*/ *, int /*<<< orphan*/ *,
                          struct timeval *);
int write(int, char *, int);
int sendfilesocket(int sock, int file, off_t *offset, off_t count) {
  char buf[1024 * 16];
  off_t len;
  int rd;
  int wr = 0;
  int total = 0;
  int i;
  len = filelength(file);
  if (offset != NULL)
    if (lseek(file, *offset, SEEK_SET) < 0)
      return (-1);
  if (count < 1 || count > len) {
    count = len;
    count -= lseek(file, 0, SEEK_CUR);
  }
  if (count < 0) {
    errno = EINVAL;
    return (-1);
  }
  while (total < count) {
    rd = read(file, buf, sizeof(buf));
    if (rd == -1)
      return (-1);
    if (rd == 0)
      break;
    for (i = wr = 0; i < rd; i += wr) {
      wr = write(sock, buf + i, rd - i);
      if (wr > 0)
        continue;
      if (wr == -1 && errno == EWOULDBLOCK) {
        wr = 0;
        ({
          int sleep_msecs = 1;
          struct timeval tv;
          tv.tv_sec = (sleep_msecs / 1000);
          tv.tv_usec = ((sleep_msecs % 1000) * 1000);
          select(0, NULL, NULL, NULL, &tv);
        });
        continue;
      }
      return (wr);
    }
    if (i != rd)
      return (-1);
    total += rd;
  }
  if (offset != NULL)
    (*offset) += total;
  return (total);
}


x86 assembly (clang, -O0):
<sendfilesocket>:
push   %rbp
mov    %rsp,%rbp
sub    $0x4050,%rsp
mov    %edi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
movl   $0x0,-0x402c(%rbp)
movl   $0x0,-0x4030(%rbp)
mov    -0xc(%rbp),%edi
call   1030 <filelength@plt>
mov    %eax,-0x4024(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     11c6 <sendfilesocket+0x76>
mov    -0xc(%rbp),%edi
mov    -0x18(%rbp),%rax
mov    (%rax),%esi
mov    0x2e2b(%rip),%rax
mov    (%rax),%edx
call   1050 <lseek@plt>
cmp    $0x0,%eax
jge    11c1 <sendfilesocket+0x71>
movl   $0xffffffff,-0x4(%rbp)
jmp    13f3 <sendfilesocket+0x2a3>
jmp    11c6 <sendfilesocket+0x76>
cmpl   $0x1,-0x1c(%rbp)
jl     11df <sendfilesocket+0x8f>
mov    -0x1c(%rbp),%eax
cmp    -0x4024(%rbp),%eax
jle    1205 <sendfilesocket+0xb5>
mov    -0x4024(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0xc(%rbp),%edi
mov    0x2df6(%rip),%rax
mov    (%rax),%edx
xor    %esi,%esi
call   1050 <lseek@plt>
mov    %eax,%ecx
mov    -0x1c(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jge    122f <sendfilesocket+0xdf>
mov    0x2daa(%rip),%rax
mov    (%rax),%rcx
mov    0x2db8(%rip),%rax
mov    %rcx,(%rax)
movl   $0xffffffff,-0x4(%rbp)
jmp    13f3 <sendfilesocket+0x2a3>
jmp    1234 <sendfilesocket+0xe4>
mov    -0x4030(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    13d1 <sendfilesocket+0x281>
mov    -0xc(%rbp),%edi
lea    -0x4020(%rbp),%rsi
mov    $0x4000,%edx
call   1060 <read@plt>
mov    %eax,-0x4028(%rbp)
cmpl   $0xffffffff,-0x4028(%rbp)
jne    1276 <sendfilesocket+0x126>
movl   $0xffffffff,-0x4(%rbp)
jmp    13f3 <sendfilesocket+0x2a3>
cmpl   $0x0,-0x4028(%rbp)
jne    1288 <sendfilesocket+0x138>
jmp    13d1 <sendfilesocket+0x281>
movl   $0x0,-0x402c(%rbp)
movl   $0x0,-0x4034(%rbp)
mov    -0x4034(%rbp),%eax
cmp    -0x4028(%rbp),%eax
jge    139c <sendfilesocket+0x24c>
mov    -0x8(%rbp),%edi
lea    -0x4020(%rbp),%rsi
movslq -0x4034(%rbp),%rax
add    %rax,%rsi
mov    -0x4028(%rbp),%edx
sub    -0x4034(%rbp),%edx
call   1040 <write@plt>
mov    %eax,-0x402c(%rbp)
cmpl   $0x0,-0x402c(%rbp)
jle    12eb <sendfilesocket+0x19b>
jmp    1385 <sendfilesocket+0x235>
cmpl   $0xffffffff,-0x402c(%rbp)
jne    1377 <sendfilesocket+0x227>
mov    0x2cd9(%rip),%rax
mov    (%rax),%rax
mov    0x2cbf(%rip),%rcx
cmp    (%rcx),%rax
jne    1377 <sendfilesocket+0x227>
movl   $0x0,-0x402c(%rbp)
movl   $0x1,-0x4038(%rbp)
mov    -0x4038(%rbp),%eax
mov    $0x3e8,%ecx
cltd
idiv   %ecx
mov    %eax,-0x4040(%rbp)
mov    -0x4038(%rbp),%eax
mov    $0x3e8,%ecx
cltd
idiv   %ecx
imul   $0x3e8,%edx,%eax
mov    %eax,-0x403c(%rbp)
xor    %edi,%edi
xor    %eax,%eax
mov    %eax,%ecx
lea    -0x4040(%rbp),%r8
mov    %rcx,%rsi
mov    %rcx,%rdx
call   1070 <select@plt>
mov    %eax,-0x4044(%rbp)
jmp    1385 <sendfilesocket+0x235>
mov    -0x402c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    13f3 <sendfilesocket+0x2a3>
mov    -0x402c(%rbp),%eax
add    -0x4034(%rbp),%eax
mov    %eax,-0x4034(%rbp)
jmp    129c <sendfilesocket+0x14c>
mov    -0x4034(%rbp),%eax
cmp    -0x4028(%rbp),%eax
je     13ba <sendfilesocket+0x26a>
movl   $0xffffffff,-0x4(%rbp)
jmp    13f3 <sendfilesocket+0x2a3>
mov    -0x4028(%rbp),%eax
add    -0x4030(%rbp),%eax
mov    %eax,-0x4030(%rbp)
jmp    1234 <sendfilesocket+0xe4>
cmpq   $0x0,-0x18(%rbp)
je     13ea <sendfilesocket+0x29a>
mov    -0x4030(%rbp),%ecx
mov    -0x18(%rbp),%rax
add    (%rax),%ecx
mov    %ecx,(%rax)
mov    -0x4030(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x4050,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sendfilesocket>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x4028,%rsp
mov    %ecx,%r15d
mov    %rdx,%rbp
mov    %esi,%r12d
mov    %edi,%ebx
mov    %esi,%edi
call   1030 <filelength@plt>
mov    %eax,%r14d
test   %rbp,%rbp
je     1197 <sendfilesocket+0x47>
mov    0x0(%rbp),%esi
mov    0x2e4b(%rip),%rax
mov    (%rax),%edx
mov    %r12d,%edi
call   1050 <lseek@plt>
test   %eax,%eax
js     12cd <sendfilesocket+0x17d>
mov    %rbp,0x10(%rsp)
test   %r15d,%r15d
jle    11a6 <sendfilesocket+0x56>
cmp    %r15d,%r14d
jge    11d3 <sendfilesocket+0x83>
mov    0x2e3b(%rip),%rax
mov    (%rax),%edx
mov    %r12d,%edi
xor    %esi,%esi
call   1050 <lseek@plt>
sub    %eax,%r14d
js     12b9 <sendfilesocket+0x169>
movl   $0x0,0xc(%rsp)
mov    %r14d,%r15d
je     12a4 <sendfilesocket+0x154>
movl   $0x0,0xc(%rsp)
lea    0x20(%rsp),%rsi
mov    %r12d,%r13d
mov    %r12d,%edi
mov    $0x4000,%edx
call   1060 <read@plt>
mov    %eax,%r12d
cmp    $0xffffffff,%eax
je     12f1 <sendfilesocket+0x1a1>
test   %r12d,%r12d
je     12a4 <sendfilesocket+0x154>
jle    12cd <sendfilesocket+0x17d>
xor    %ebp,%ebp
jmp    123c <sendfilesocket+0xec>
nop
movabs $0x3e800000000,%rax
mov    %rax,0x18(%rsp)
xor    %r14d,%r14d
xor    %edi,%edi
xor    %esi,%esi
xor    %edx,%edx
xor    %ecx,%ecx
lea    0x18(%rsp),%r8
call   1070 <select@plt>
add    %r14d,%ebp
cmp    %ebp,%r12d
jle    1280 <sendfilesocket+0x130>
movslq %ebp,%rax
lea    (%rsp,%rax,1),%rsi
add    $0x20,%rsi
mov    %r12d,%edx
sub    %eax,%edx
mov    %ebx,%edi
call   1040 <write@plt>
mov    %eax,%r14d
test   %eax,%eax
jg     1234 <sendfilesocket+0xe4>
cmp    $0xffffffff,%r14d
jne    12d3 <sendfilesocket+0x183>
mov    0x2d71(%rip),%rax
mov    (%rax),%rax
mov    0x2d57(%rip),%rcx
cmp    (%rcx),%rax
je     1210 <sendfilesocket+0xc0>
jmp    12cd <sendfilesocket+0x17d>
nopl   0x0(%rax,%rax,1)
mov    $0xffffffff,%r14d
jne    12d3 <sendfilesocket+0x183>
mov    0xc(%rsp),%eax
add    %r12d,%eax
mov    %eax,0xc(%rsp)
cmp    %r15d,%eax
mov    %r13d,%r12d
lea    0x20(%rsp),%rsi
jl     11e0 <sendfilesocket+0x90>
mov    0x10(%rsp),%rax
test   %rax,%rax
je     12e8 <sendfilesocket+0x198>
mov    0xc(%rsp),%ecx
add    %ecx,(%rax)
mov    %ecx,%r14d
jmp    12d3 <sendfilesocket+0x183>
mov    0x2d00(%rip),%rax
mov    (%rax),%rax
mov    0x2d0e(%rip),%rcx
mov    %rax,(%rcx)
mov    $0xffffffff,%r14d
mov    %r14d,%eax
add    $0x4028,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    0xc(%rsp),%eax
mov    %eax,%r14d
jmp    12d3 <sendfilesocket+0x183>
mov    %r12d,%r14d
jmp    12d3 <sendfilesocket+0x183>

LLVM IR (-O0):
%struct.timeval = type { i32, i32 }
@SEEK_SET = global i32 0
@SEEK_CUR = global i32 0
@EINVAL = global i64 0
@errno = global i64 0
@EWOULDBLOCK = global i64 0
define i32 @sendfilesocket(i32 %0, i32 %1, i32* %2, i32 %3) {
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32*
%9 = alloca i32
%10 = alloca [16384 x i8]
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca %struct.timeval
%18 = alloca i32
store i32 %0, i32* %6
store i32 %1, i32* %7
store i32* %2, i32** %8
store i32 %3, i32* %9
store i32 0, i32* %13
store i32 0, i32* %14
%19 = load i32, i32* %7
%20 = call i32 @filelength(i32 %19)
store i32 %20, i32* %11
%21 = load i32*, i32** %8
%22 = icmp ne i32* %21, null
br i1 %22, label %23, label %32
23: ; preds = %4
%24 = load i32, i32* %7
%25 = load i32*, i32** %8
%26 = load i32, i32* %25
%27 = load i32, i32* @SEEK_SET
%28 = call i32 @lseek(i32 %24, i32 %26, i32 %27)
%29 = icmp slt i32 %28, 0
br i1 %29, label %30, label %31
30: ; preds = %23
store i32 -1, i32* %5
br label %127
31: ; preds = %23
br label %32
32: ; preds = %31, %4
%33 = load i32, i32* %9
%34 = icmp slt i32 %33, 1
br i1 %34, label %39, label %35
35: ; preds = %32
%36 = load i32, i32* %9
%37 = load i32, i32* %11
%38 = icmp sgt i32 %36, %37
br i1 %38, label %39, label %46
39: ; preds = %35, %32
%40 = load i32, i32* %11
store i32 %40, i32* %9
%41 = load i32, i32* %7
%42 = load i32, i32* @SEEK_CUR
%43 = call i32 @lseek(i32 %41, i32 0, i32 %42)
%44 = load i32, i32* %9
%45 = sub nsw i32 %44, %43
store i32 %45, i32* %9
br label %46
46: ; preds = %39, %35
%47 = load i32, i32* %9
%48 = icmp slt i32 %47, 0
br i1 %48, label %49, label %51
49: ; preds = %46
%50 = load i64, i64* @EINVAL
store i64 %50, i64* @errno
store i32 -1, i32* %5
br label %127
51: ; preds = %46
br label %52
52: ; preds = %113, %51
%53 = load i32, i32* %14
%54 = load i32, i32* %9
%55 = icmp slt i32 %53, %54
br i1 %55, label %56, label %117
56: ; preds = %52
%57 = load i32, i32* %7
%58 = getelementptr inbounds [16384 x i8], [16384 x i8]* %10, i64 0, i64 0
%59 = call i32 @read(i32 %57, i8* %58, i32 16384)
store i32 %59, i32* %12
%60 = load i32, i32* %12
%61 = icmp eq i32 %60, -1
br i1 %61, label %62, label %63
62: ; preds = %56
store i32 -1, i32* %5
br label %127
63: ; preds = %56
%64 = load i32, i32* %12
%65 = icmp eq i32 %64, 0
br i1 %65, label %66, label %67
66: ; preds = %63
br label %117
67: ; preds = %63
store i32 0, i32* %13
store i32 0, i32* %15
br label %68
68: ; preds = %104, %67
%69 = load i32, i32* %15
%70 = load i32, i32* %12
%71 = icmp slt i32 %69, %70
br i1 %71, label %72, label %108
72: ; preds = %68
%73 = load i32, i32* %6
%74 = getelementptr inbounds [16384 x i8], [16384 x i8]* %10, i64 0, i64 0
%75 = load i32, i32* %15
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds i8, i8* %74, i64 %76
%78 = load i32, i32* %12
%79 = load i32, i32* %15
%80 = sub nsw i32 %78, %79
%81 = call i32 @write(i32 %73, i8* %77, i32 %80)
store i32 %81, i32* %13
%82 = load i32, i32* %13
%83 = icmp sgt i32 %82, 0
br i1 %83, label %84, label %85
84: ; preds = %72
br label %104
85: ; preds = %72
%86 = load i32, i32* %13
%87 = icmp eq i32 %86, -1
br i1 %87, label %88, label %102
88: ; preds = %85
%89 = load i64, i64* @errno
%90 = load i64, i64* @EWOULDBLOCK
%91 = icmp eq i64 %89, %90
br i1 %91, label %92, label %102
92: ; preds = %88
store i32 0, i32* %13
store i32 1, i32* %16
%93 = load i32, i32* %16
%94 = sdiv i32 %93, 1000
%95 = getelementptr inbounds %struct.timeval, %struct.timeval* %17, i32 0, i32 0
store i32 %94, i32* %95
%96 = load i32, i32* %16
%97 = srem i32 %96, 1000
%98 = mul nsw i32 %97, 1000
%99 = getelementptr inbounds %struct.timeval, %struct.timeval* %17, i32 0, i32 1
store i32 %98, i32* %99
%100 = call i32 @select(i32 0, i32* null, i32* null, i32* null, %struct.timeval* %17)
store i32 %100, i32* %18
%101 = load i32, i32* %18
br label %104
102: ; preds = %88, %85
%103 = load i32, i32* %13
store i32 %103, i32* %5
br label %127
104: ; preds = %92, %84
%105 = load i32, i32* %13
%106 = load i32, i32* %15
%107 = add nsw i32 %106, %105
store i32 %107, i32* %15
br label %68
108: ; preds = %68
%109 = load i32, i32* %15
%110 = load i32, i32* %12
%111 = icmp ne i32 %109, %110
br i1 %111, label %112, label %113
112: ; preds = %108
store i32 -1, i32* %5
br label %127
113: ; preds = %108
%114 = load i32, i32* %12
%115 = load i32, i32* %14
%116 = add nsw i32 %115, %114
store i32 %116, i32* %14
br label %52
117: ; preds = %66, %52
%118 = load i32*, i32** %8
%119 = icmp ne i32* %118, null
br i1 %119, label %120, label %125
120: ; preds = %117
%121 = load i32, i32* %14
%122 = load i32*, i32** %8
%123 = load i32, i32* %122
%124 = add nsw i32 %123, %121
store i32 %124, i32* %122
br label %125
125: ; preds = %120, %117
%126 = load i32, i32* %14
store i32 %126, i32* %5
br label %127
127: ; preds = %125, %112, %102, %62, %49, %30
%128 = load i32, i32* %5
ret i32 %128
}

LLVM IR (-O2):
%struct.timeval = type { i32, i32 }
@SEEK_SET = global i32 0
@SEEK_CUR = global i32 0
@EINVAL = global i64 0
@errno = global i64 0
@EWOULDBLOCK = global i64 0
define i32 @sendfilesocket(i32 %0, i32 %1, i32* %2, i32 %3) {
%5 = alloca [16384 x i8]
%6 = alloca %struct.timeval
%7 = getelementptr inbounds [16384 x i8], [16384 x i8]* %5, i64 0, i64 0
%8 = tail call i32 @filelength(i32 %1)
%9 = icmp eq i32* %2, null
br i1 %9, label %15, label %10
10: ; preds = %4
%11 = load i32, i32* %2
%12 = load i32, i32* @SEEK_SET
%13 = tail call i32 @lseek(i32 %1, i32 %11, i32 %12)
%14 = icmp slt i32 %13, 0
br i1 %14, label %67, label %15
15: ; preds = %10, %4
%16 = icmp slt i32 %3, 1
%17 = icmp slt i32 %8, %3
%18 = select i1 %16, i1 true, i1 %17
br i1 %18, label %19, label %26
19: ; preds = %15
%20 = load i32, i32* @SEEK_CUR
%21 = tail call i32 @lseek(i32 %1, i32 0, i32 %20)
%22 = sub nsw i32 %8, %21
%23 = icmp slt i32 %22, 0
br i1 %23, label %31, label %24
24: ; preds = %19
%25 = icmp eq i32 %22, 0
br i1 %25, label %62, label %26
26: ; preds = %15, %24
%27 = phi i32 [ %22, %24 ], [ %3, %15 ]
%28 = bitcast %struct.timeval* %6 to i8*
%29 = getelementptr inbounds %struct.timeval, %struct.timeval* %6, i64 0, i32 0
%30 = getelementptr inbounds %struct.timeval, %struct.timeval* %6, i64 0, i32 1
br label %35
31: ; preds = %19
%32 = load i64, i64* @EINVAL
store i64 %32, i64* @errno
br label %67
33: ; preds = %59
%34 = icmp slt i32 %61, %27
br i1 %34, label %35, label %62
35: ; preds = %26, %33
%36 = phi i32 [ 0, %26 ], [ %61, %33 ]
%37 = call i32 @read(i32 %1, i8* %7, i32 16384)
switch i32 %37, label %38 [
i32 -1, label %67
i32 0, label %62
]
38: ; preds = %35
%39 = icmp sgt i32 %37, 0
br i1 %39, label %40, label %67
40: ; preds = %38, %55
%41 = phi i32 [ %57, %55 ], [ 0, %38 ]
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds [16384 x i8], [16384 x i8]* %5, i64 0, i64 %42
%44 = sub nsw i32 %37, %41
%45 = call i32 @write(i32 %0, i8* %43, i32 %44)
%46 = icmp sgt i32 %45, 0
br i1 %46, label %55, label %47
47: ; preds = %40
%48 = icmp eq i32 %45, -1
br i1 %48, label %49, label %67
49: ; preds = %47
%50 = load i64, i64* @errno
%51 = load i64, i64* @EWOULDBLOCK
%52 = icmp eq i64 %50, %51
br i1 %52, label %53, label %67
53: ; preds = %49
store i32 0, i32* %29
store i32 1000, i32* %30
%54 = call i32 @select(i32 0, i32* null, i32* null, i32* null, %struct.timeval* %6)
br label %55
55: ; preds = %40, %53
%56 = phi i32 [ %45, %40 ], [ 0, %53 ]
%57 = add nsw i32 %56, %41
%58 = icmp sgt i32 %37, %57
br i1 %58, label %40, label %59
59: ; preds = %55
%60 = icmp eq i32 %37, %57
%61 = add nsw i32 %37, %36
br i1 %60, label %33, label %67
62: ; preds = %33, %35, %24
%63 = phi i32 [ 0, %24 ], [ %36, %35 ], [ %61, %33 ]
br i1 %9, label %67, label %64
64: ; preds = %62
%65 = load i32, i32* %2
%66 = add nsw i32 %65, %63
store i32 %66, i32* %2
br label %67
67: ; preds = %38, %59, %35, %47, %49, %62, %64, %10, %31
%68 = phi i32 [ -1, %31 ], [ -1, %10 ], [ %63, %64 ], [ %63, %62 ], [ %45, %47 ], [ -1, %49 ], [ -1, %38 ], [ -1, %59 ], [ %37, %35 ]
ret i32 %68
}