aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2004-02-18 08:36:27 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2004-02-18 08:36:27 +0000
commit94b8de97c4774b6c44e42845085d1517563a81de (patch)
tree27649f2406ed864798c973f4333fb7b40794a345
parent9c56033feb5c28ac49e8da1c28ce73b8761c2bef (diff)
downloadgcc-94b8de97c4774b6c44e42845085d1517563a81de.zip
gcc-94b8de97c4774b6c44e42845085d1517563a81de.tar.gz
gcc-94b8de97c4774b6c44e42845085d1517563a81de.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/config/io/basic_file_stdio.cc51
2 files changed, 38 insertions, 19 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c40c080..822c781 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 f83b7a2..53c1a26 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