akaros/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/writev.c
<<
>>
Prefs
   1/* Copyright (C) 1991,1992,1996,1997,2002,2009 Free Software Foundation, Inc.
   2   This file is part of the GNU C Library.
   3
   4   The GNU C Library is free software; you can redistribute it and/or
   5   modify it under the terms of the GNU Lesser General Public
   6   License as published by the Free Software Foundation; either
   7   version 2.1 of the License, or (at your option) any later version.
   8
   9   The GNU C Library is distributed in the hope that it will be useful,
  10   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12   Lesser General Public License for more details.
  13
  14   You should have received a copy of the GNU Lesser General Public
  15   License along with the GNU C Library; if not, write to the Free
  16   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  17   02111-1307 USA.  */
  18
  19#include <stdlib.h>
  20#include <unistd.h>
  21#include <string.h>
  22#include <limits.h>
  23#include <stdbool.h>
  24#include <sys/param.h>
  25#include <sys/uio.h>
  26#include <errno.h>
  27
  28
  29/* Helper function to assemble and write everything in one shot. */
  30static ssize_t
  31write_all(int fd, char *buf, const struct iovec *vec, int n, ssize_t bytes)
  32{
  33  char* bufp = buf;
  34  for (int i = 0; i < n; i++)
  35    bufp = __mempcpy(bufp, vec[i].iov_base, vec[i].iov_len);
  36  return __write(fd, buf, bytes);
  37}
  38
  39/* Write data pointed by the buffers described by VECTOR, which
  40   is a vector of COUNT 'struct iovec's, to file descriptor FD.
  41   The data is written in the order specified.
  42   Operates just like 'write' (see <unistd.h>) except that the data
  43   are taken from VECTOR instead of a contiguous buffer.  */
  44ssize_t
  45__libc_writev (int fd, const struct iovec *vector, int count)
  46{
  47  ssize_t bytes = 0;
  48  for (int i = 0; i < count; ++i)
  49    bytes += vector[i].iov_len;
  50  
  51  if (bytes < 0)
  52  {
  53    __set_errno(EINVAL);
  54    return -1;
  55  }
  56
  57  /* Allocate a stack or heap buffer, then have write_all finish up. */
  58  if (__builtin_expect(__libc_use_alloca(bytes), 1))
  59  {
  60    char* buf = __alloca(bytes);
  61    return write_all(fd, buf, vector, count, bytes);
  62  }
  63  else
  64  {
  65    char* buf = malloc(bytes);
  66    if (buf == NULL)
  67    {
  68      __set_errno(ENOMEM);
  69      return -1;
  70    }
  71    ssize_t res = write_all(fd, buf, vector, count, bytes);
  72    free(buf);
  73    return res;
  74  }
  75}
  76#ifndef __libc_writev
  77strong_alias (__libc_writev, __writev)
  78weak_alias (__libc_writev, writev)
  79#endif
  80