diff --git a/libports/lib/mk/libc.mk b/libports/lib/mk/libc.mk index 75a821464..82bc6cbf7 100644 --- a/libports/lib/mk/libc.mk +++ b/libports/lib/mk/libc.mk @@ -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 \ 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 \ - libc_mem_alloc.cc + libc_mem_alloc.cc writev.cc # # Files from string library that are not included in libc-raw_string because diff --git a/libports/src/lib/libc/dummies.cc b/libports/src/lib/libc/dummies.cc index 64619fbf9..4abc1fcf5 100644 --- a/libports/src/lib/libc/dummies.cc +++ b/libports/src/lib/libc/dummies.cc @@ -137,7 +137,6 @@ DUMMY(-1, utimes) DUMMY(-1, utrace) DUMMY(-1, vfork) DUMMY(-1, _wait4) -DUMMY(-1, _writev) void ksem_init(void) { diff --git a/libports/src/lib/libc/writev.cc b/libports/src/lib/libc/writev.cc new file mode 100644 index 000000000..cb4fefd25 --- /dev/null +++ b/libports/src/lib/libc/writev.cc @@ -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 +#include +#include +#include +#include + +#include + +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(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); +} +