Add writev() to libc
This function is needed by perror(3). Closes #239.
This commit is contained in:
parent
f325f314b5
commit
896d12d0b8
|
@ -14,7 +14,7 @@ SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc readlink.cc munmap.cc \
|
||||||
issetugid.cc errno.cc gai_strerror.cc clock_gettime.cc \
|
issetugid.cc errno.cc gai_strerror.cc clock_gettime.cc \
|
||||||
gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \
|
gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \
|
||||||
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
|
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
|
||||||
libc_mem_alloc.cc
|
libc_mem_alloc.cc writev.cc
|
||||||
|
|
||||||
#
|
#
|
||||||
# Files from string library that are not included in libc-raw_string because
|
# Files from string library that are not included in libc-raw_string because
|
||||||
|
|
|
@ -137,7 +137,6 @@ DUMMY(-1, utimes)
|
||||||
DUMMY(-1, utrace)
|
DUMMY(-1, utrace)
|
||||||
DUMMY(-1, vfork)
|
DUMMY(-1, vfork)
|
||||||
DUMMY(-1, _wait4)
|
DUMMY(-1, _wait4)
|
||||||
DUMMY(-1, _writev)
|
|
||||||
|
|
||||||
void ksem_init(void)
|
void ksem_init(void)
|
||||||
{
|
{
|
||||||
|
|
75
libports/src/lib/libc/writev.cc
Normal file
75
libports/src/lib/libc/writev.cc
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* \brief Plugin implementation
|
||||||
|
* \author Josef Soentgen
|
||||||
|
* \date 2012-04-10
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2012 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
enum { MAX_BUFFER_LEN = 2048 };
|
||||||
|
|
||||||
|
extern "C" int _writev(int d, const struct iovec *iov, int iovcnt)
|
||||||
|
{
|
||||||
|
char buffer[MAX_BUFFER_LEN];
|
||||||
|
char *v, *b;
|
||||||
|
ssize_t written;
|
||||||
|
size_t v_len, _len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (iovcnt < 1 || iovcnt > IOV_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < iovcnt; i++)
|
||||||
|
v_len += iov->iov_len;
|
||||||
|
|
||||||
|
if (v_len > SSIZE_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b = buffer;
|
||||||
|
while (iovcnt) {
|
||||||
|
v = static_cast<char *>(iov->iov_base);
|
||||||
|
v_len = iov->iov_len;
|
||||||
|
|
||||||
|
while (v_len > 0) {
|
||||||
|
if (v_len < sizeof(buffer))
|
||||||
|
_len = v_len;
|
||||||
|
else
|
||||||
|
_len = sizeof(buffer);
|
||||||
|
|
||||||
|
// TODO error check
|
||||||
|
memmove(b, v, _len);
|
||||||
|
i = write(d, b, _len);
|
||||||
|
v += _len;
|
||||||
|
v_len -= _len;
|
||||||
|
|
||||||
|
written += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
iov++;
|
||||||
|
iovcnt--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" ssize_t writev(int d, const struct iovec *iov, int iovcnt)
|
||||||
|
{
|
||||||
|
return _writev(d, iov, iovcnt);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user