text: #ifndef UNIX_UTILS_H
  #define UNIX_UTILS_H
  
  #define _GNU_SOURCE
  
  #include <sys/uio.h>
  #include <errno.h>
  #include "ocaml_utils.h"
  #include "core_params.h"
  
  /* Utility definitions */
  
  static inline char * get_bstr(value v_bstr, value v_pos)
  {
    return (char *) Caml_ba_data_val(v_bstr) + Long_val(v_pos);
  }
  
  static inline struct iovec * copy_iovecs(size_t *total_len, value v_iovecs, int n)
  {
    struct iovec *iovecs = caml_stat_alloc(sizeof(struct iovec) * n);
    for (--n; n >= 0; --n) {
      struct iovec *iovec = &iovecs[n];
      value v_iovec = Field(v_iovecs, n);
      value v_iov_base = Field(v_iovec, 0);
      value v_iov_pos = Field(v_iovec, 1);
      size_t iov_len = Long_val(Field(v_iovec, 2));
      iovec->iov_len = iov_len;
      *total_len += iov_len;
      iovec->iov_base = get_bstr(v_iov_base, v_iov_pos);
    }
    return iovecs;
  }
  
  static inline ssize_t jane_writev(int fd, struct iovec *iov, int iovcnt)
  {
    ssize_t ret = writev(fd, iov, iovcnt);
    if (ret == -1 && errno == EINVAL && iovcnt == 0) {
      /* On OSX [count = 0] is an error, but it's not on Linux. For
         simplicity we always ignore [EINVAL] when [iovcnt] is 0. */
      ret = 0;
    }
    return ret;
  }
  
  #endif /* UNIX_UTILS_H */
  