package piaf

  1. Overview
  2. Docs
An HTTP library with HTTP/2 support written entirely in OCaml

Install

Dune Dependency

Authors

Maintainers

Sources

piaf-0.2.0.tbz
sha256=07fa9009a52faeaae6d86116e75007f5279b185c7bc7c95aab9455f2107370fb
sha512=dfde4bd0a5c8a3b795a8e3d6f6e1f9f1864a9eb0a1b96763c17515d771566af7623ca64db671a8dce2c7838dad08d8465db98f5e4f8dcf5e1a386ef5b29da56c

doc/src/piaf.sendfile/sendfile.ml.html

Source file sendfile.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
exception Darwin_specific_unix_error of (Unix.error * int)

let () =
  Callback.register_exception
    "sendfile_exn_unix_error"
    (Darwin_specific_unix_error (Unix.E2BIG, 0));
  Printexc.register_printer (function
    | Darwin_specific_unix_error (unix_error, len) ->
      let msg =
        (* Copied from
           https://github.com/ocaml/ocaml/blob/trunk/otherlibs/unix/unix_unix.ml *)
        match unix_error with
        | E2BIG -> "E2BIG"
        | EACCES -> "EACCES"
        | EAGAIN -> "EAGAIN"
        | EBADF -> "EBADF"
        | EBUSY -> "EBUSY"
        | ECHILD -> "ECHILD"
        | EDEADLK -> "EDEADLK"
        | EDOM -> "EDOM"
        | EEXIST -> "EEXIST"
        | EFAULT -> "EFAULT"
        | EFBIG -> "EFBIG"
        | EINTR -> "EINTR"
        | EINVAL -> "EINVAL"
        | EIO -> "EIO"
        | EISDIR -> "EISDIR"
        | EMFILE -> "EMFILE"
        | EMLINK -> "EMLINK"
        | ENAMETOOLONG -> "ENAMETOOLONG"
        | ENFILE -> "ENFILE"
        | ENODEV -> "ENODEV"
        | ENOENT -> "ENOENT"
        | ENOEXEC -> "ENOEXEC"
        | ENOLCK -> "ENOLCK"
        | ENOMEM -> "ENOMEM"
        | ENOSPC -> "ENOSPC"
        | ENOSYS -> "ENOSYS"
        | ENOTDIR -> "ENOTDIR"
        | ENOTEMPTY -> "ENOTEMPTY"
        | ENOTTY -> "ENOTTY"
        | ENXIO -> "ENXIO"
        | EPERM -> "EPERM"
        | EPIPE -> "EPIPE"
        | ERANGE -> "ERANGE"
        | EROFS -> "EROFS"
        | ESPIPE -> "ESPIPE"
        | ESRCH -> "ESRCH"
        | EXDEV -> "EXDEV"
        | EWOULDBLOCK -> "EWOULDBLOCK"
        | EINPROGRESS -> "EINPROGRESS"
        | EALREADY -> "EALREADY"
        | ENOTSOCK -> "ENOTSOCK"
        | EDESTADDRREQ -> "EDESTADDRREQ"
        | EMSGSIZE -> "EMSGSIZE"
        | EPROTOTYPE -> "EPROTOTYPE"
        | ENOPROTOOPT -> "ENOPROTOOPT"
        | EPROTONOSUPPORT -> "EPROTONOSUPPORT"
        | ESOCKTNOSUPPORT -> "ESOCKTNOSUPPORT"
        | EOPNOTSUPP -> "EOPNOTSUPP"
        | EPFNOSUPPORT -> "EPFNOSUPPORT"
        | EAFNOSUPPORT -> "EAFNOSUPPORT"
        | EADDRINUSE -> "EADDRINUSE"
        | EADDRNOTAVAIL -> "EADDRNOTAVAIL"
        | ENETDOWN -> "ENETDOWN"
        | ENETUNREACH -> "ENETUNREACH"
        | ENETRESET -> "ENETRESET"
        | ECONNABORTED -> "ECONNABORTED"
        | ECONNRESET -> "ECONNRESET"
        | ENOBUFS -> "ENOBUFS"
        | EISCONN -> "EISCONN"
        | ENOTCONN -> "ENOTCONN"
        | ESHUTDOWN -> "ESHUTDOWN"
        | ETOOMANYREFS -> "ETOOMANYREFS"
        | ETIMEDOUT -> "ETIMEDOUT"
        | ECONNREFUSED -> "ECONNREFUSED"
        | EHOSTDOWN -> "EHOSTDOWN"
        | EHOSTUNREACH -> "EHOSTUNREACH"
        | ELOOP -> "ELOOP"
        | EOVERFLOW -> "EOVERFLOW"
        | EUNKNOWNERR x -> Printf.sprintf "EUNKNOWNERR %d" x
      in

      Some
        (Format.asprintf "Sendfile(Unix_error): %s; remaining len: %d" msg len)
    | _ -> None)

external sendfile :
   src:Unix.file_descr
  -> dst:Unix.file_descr
  -> off:int
  -> len:int
  -> int
  = "ocaml_sendfile_sendfile_stub"

let sendfile_once_exn ?(off = 0) ~len ~src dst =
  try sendfile ~src ~dst ~off ~len with
  | Darwin_specific_unix_error (unix_err, _) ->
    raise (Unix.Unix_error (unix_err, "sendfile", ""))

let sendfile_once ?(off = 0) ~len ~src dst =
  try Ok (sendfile_once_exn ~src ~off ~len dst) with
  | Unix.Unix_error (unix_err, _, _msg) -> Error unix_err

let sendfile_exn ?(off = 0) ?len ~src dst =
  let rec sendfile_exn ~off ~len ~src dst =
    match sendfile ~src ~off ~len ~dst with
    | c when c = len -> len
    | c -> sendfile_exn ~src ~off:(off + c) ~len:(len - c) dst
    | exception Unix.Unix_error ((EINTR | EAGAIN), _, _) ->
      sendfile_exn ~src ~off ~len dst
    | exception Darwin_specific_unix_error ((EINTR | EAGAIN), sent) ->
      (* Darwin systems signal the number of bytes partially sent on EINTR /
         EAGAIN. *)
      sendfile_exn ~src ~off:(off + sent) ~len:(len - sent) dst
    | exception Darwin_specific_unix_error (unix_err, _) ->
      raise (Unix.Unix_error (unix_err, "sendfile", ""))
  in
  let len =
    match len with Some len -> len | None -> (Unix.fstat src).st_size - off
  in
  let _sent = sendfile_exn ~off ~len ~src dst in
  (* If we're here, we sent the whole file correctly, so we return the total
     length sent. *)
  len

let sendfile ?off ?len ~src dst =
  try Ok (sendfile_exn ~src ?off ?len dst) with
  | Unix.Unix_error (unix_err, _, _msg) -> Error unix_err
OCaml

Innovation. Community. Security.