diff options
author | Paolo Carlini <pcarlini@suse.de> | 2004-02-18 08:36:27 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2004-02-18 08:36:27 +0000 |
commit | 94b8de97c4774b6c44e42845085d1517563a81de (patch) | |
tree | 27649f2406ed864798c973f4333fb7b40794a345 /libstdc++-v3 | |
parent | 9c56033feb5c28ac49e8da1c28ce73b8761c2bef (diff) | |
download | gcc-94b8de97c4774b6c44e42845085d1517563a81de.tar.gz |
basic_file_stdio.cc (__gnu_internal::xwritev): Rewrite, avoiding recursion.
2004-02-18 Paolo Carlini <pcarlini@suse.de>
* config/io/basic_file_stdio.cc (__gnu_internal::xwritev):
Rewrite, avoiding recursion.
(__gnu_internal::xwrite): Minor tweaks.
From-SVN: r78015
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 6 | ||||
-rw-r--r-- | libstdc++-v3/config/io/basic_file_stdio.cc | 51 |
2 files changed, 38 insertions, 19 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c40c080d64f..822c78172ee 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2004-02-18 Paolo Carlini <pcarlini@suse.de> + + * config/io/basic_file_stdio.cc (__gnu_internal::xwritev): + Rewrite, avoiding recursion. + (__gnu_internal::xwrite): Minor tweaks. + 2004-02-17 Stefan Olsson <stefan@xapa.se> * include/ext/mt_allocator.h: Removed the last diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc index f83b7a25f88..53c1a26a472 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.cc +++ b/libstdc++-v3/config/io/basic_file_stdio.cc @@ -111,16 +111,22 @@ namespace __gnu_internal xwrite(int __fd, const char* __s, std::streamsize __n) { std::streamsize __nleft = __n; - while (__nleft > 0) + + for (;;) { const std::streamsize __ret = write(__fd, __s, __nleft); if (__ret == -1L && errno == EINTR) continue; - else if (__ret == -1L) + if (__ret == -1L) break; + __nleft -= __ret; + if (__nleft == 0) + break; + __s += __ret; } + return __n - __nleft; } @@ -130,33 +136,40 @@ namespace __gnu_internal xwritev(int __fd, const char* __s1, std::streamsize __n1, const char* __s2, std::streamsize __n2) { - std::streamsize __ret; + std::streamsize __nleft = __n1 + __n2; + std::streamsize __n1_left = __n1; struct iovec __iov[2]; - __iov[0].iov_base = const_cast<char*>(__s1); - __iov[0].iov_len = __n1; __iov[1].iov_base = const_cast<char*>(__s2); __iov[1].iov_len = __n2; - do - __ret = writev(__fd, __iov, 2); - while (__ret == -1L && errno == EINTR); - - if (__ret == -1L) - __ret = 0; - else if (__ret < __n1 + __n2) + for (;;) { - if (__ret >= __n1) + __iov[0].iov_base = const_cast<char*>(__s1); + __iov[0].iov_len = __n1_left; + + const std::streamsize __ret = writev(__fd, __iov, 2); + if (__ret == -1L && errno == EINTR) + continue; + if (__ret == -1L) + break; + + __nleft -= __ret; + if (__nleft == 0) + break; + + const std::streamsize __off = __ret - __n1_left; + if (__off >= 0) { - const std::streamsize __off = __ret - __n1; - __ret += xwrite(__fd, __s2 + __off, __n2 - __off); + __nleft -= xwrite(__fd, __s2 + __off, __n2 - __off); + break; } - else - __ret += xwritev(__fd, __s1 + __ret, __n1 - __ret, - __s2, __n2); + + __s1 += __ret; + __n1_left -= __ret; } - return __ret; + return __n1 + __n2 - __nleft; } #endif } // namespace __gnu_internal |