public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Keith Packard <keithp@keithp.com>
To: libstdc++@gcc.gnu.org
Cc: gcc@gcc.gnu.org, Keith Packard <keithp@keithp.com>
Subject: [PATCH 1/2] libstdc++: Add --enable-pure-stdio-libstdcxx option
Date: Mon,  7 Dec 2020 10:39:26 -0800	[thread overview]
Message-ID: <20201207183927.3275768-2-keithp@keithp.com> (raw)
In-Reply-To: <20201207183927.3275768-1-keithp@keithp.com>

This option directs the library to only use simple stdio APIs instead
of using fileno to get the file descriptor for use with POSIX APIs.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 libstdc++-v3/ChangeLog                     | 13 ++++++
 libstdc++-v3/acinclude.m4                  | 13 ++++++
 libstdc++-v3/config/io/basic_file_stdio.cc | 46 +++++++++++++++++++---
 libstdc++-v3/configure.ac                  |  1 +
 4 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index d3ee18ed7d1..7f6b0697534 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1147,6 +1147,19 @@
 	* include/bits/uniform_int_dist.h (uniform_int_distribution::_S_nd):
 	Use qualified-id to refer to static member functions.
 
+2020-11-04  Keith Packard  <keithp@keithp.com>
+
+	* acinclude.m4: Add GLIBCXX_ENABLE_PURE_STDIO for
+	--enable-libstdcxx-pure-stdio
+	* configure.ac: Use GLIBCXX_ENABLE_PURE_STDIO for
+	--enable-libstdcxx-pure-stdio
+	* configure: regenerate
+	* config.h.in: regenerate
+	* config/io/basic_file_stdio.cc: Add support for
+	_GLIBCXX_USE_PURE_STDIO. This makes libstdc++ use only defined
+	stdio entry points for all I/O operations, without direct calls to
+	underlying POSIX functions.
+
 2020-11-03  Jonathan Wakely  <jwakely@redhat.com>
 
 	* include/std/syncstream: Include <bits/std_mutex.h>
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index fcd9ea3d23a..863695e68e7 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2889,6 +2889,19 @@ AC_DEFUN([GLIBCXX_ENABLE_CSTDIO], [
 ])
 
 
+dnl
+dnl Check whether to use 'pure' stdio (no POSIX calls at all)
+dnl
+dnl Default is 'no'
+AC_DEFUN([GLIBCXX_ENABLE_PURE_STDIO], [
+  GLIBCXX_ENABLE(libstdcxx-pure-stdio,$1,,[use only stdio APIs])
+  if test $enable_libstdcxx_pure_stdio = yes; then
+    AC_DEFINE(_GLIBCXX_USE_PURE_STDIO, 1,
+              [Define to restrict code to stdio APIs.])
+  fi
+])
+
+
 dnl
 dnl Check for "unusual" flags to pass to the compiler while building.
 dnl
diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc
index ba830fb9e97..d31da8497f4 100644
--- a/libstdc++-v3/config/io/basic_file_stdio.cc
+++ b/libstdc++-v3/config/io/basic_file_stdio.cc
@@ -111,13 +111,21 @@ namespace
 
   // Wrapper handling partial write.
   static std::streamsize
+#ifdef _GLIBCXX_USE_PURE_STDIO
+  xwrite(FILE *__file, const char* __s, std::streamsize __n)
+#else
   xwrite(int __fd, const char* __s, std::streamsize __n)
+#endif
   {
     std::streamsize __nleft = __n;
 
     for (;;)
       {
+#ifdef _GLIBCXX_USE_PURE_STDIO
+	const std::streamsize __ret = fwrite(__file, 1, __nleft, __file);
+#else
 	const std::streamsize __ret = write(__fd, __s, __nleft);
+#endif
 	if (__ret == -1L && errno == EINTR)
 	  continue;
 	if (__ret == -1L)
@@ -133,7 +141,7 @@ namespace
     return __n - __nleft;
   }
 
-#ifdef _GLIBCXX_HAVE_WRITEV
+#if defined(_GLIBCXX_HAVE_WRITEV) && !defined(_GLIBCXX_USE_PURE_STDIO)
   // Wrapper handling partial writev.
   static std::streamsize
   xwritev(int __fd, const char* __s1, std::streamsize __n1,
@@ -286,9 +294,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __basic_file<char>::is_open() const throw ()
   { return _M_cfile != 0; }
 
+#ifndef _GLIBCCXX_USE_PURE_STDIO
   int
   __basic_file<char>::fd() throw ()
   { return fileno(_M_cfile); }
+#endif
 
   __c_file*
   __basic_file<char>::file() throw ()
@@ -315,28 +325,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
     streamsize __ret;
     do
+#ifdef _GLIBCXX_USE_PURE_STDIO
+      __ret = fread(__s, 1, __n, this->file());
+#else
       __ret = read(this->fd(), __s, __n);
+#endif
     while (__ret == -1L && errno == EINTR);
     return __ret;
   }
 
   streamsize
   __basic_file<char>::xsputn(const char* __s, streamsize __n)
-  { return xwrite(this->fd(), __s, __n); }
+  {
+#ifdef _GLIBCXX_USE_PURE_STDIO
+    return xwrite(this->file(), __s, __n);
+#else
+    return xwrite(this->fd(), __s, __n);
+#endif
+  }
 
   streamsize
   __basic_file<char>::xsputn_2(const char* __s1, streamsize __n1,
 			       const char* __s2, streamsize __n2)
   {
     streamsize __ret = 0;
-#ifdef _GLIBCXX_HAVE_WRITEV
+#if defined(_GLIBCXX_HAVE_WRITEV) && !defined(_GLIBCXX_USE_PURE_STDIO)
     __ret = xwritev(this->fd(), __s1, __n1, __s2, __n2);
 #else
     if (__n1)
+#ifdef _GLIBCXX_USE_PURE_STDIO
+      __ret = xwrite(this->file(), __s1, __n1);
+#else
       __ret = xwrite(this->fd(), __s1, __n1);
+#endif
 
     if (__ret == __n1)
+#ifdef _GLIBCXX_USE_PURE_STDIO
+      __ret += xwrite(this->file(), __s2, __n2);
+#else
       __ret += xwrite(this->fd(), __s2, __n2);
+#endif
 #endif
     return __ret;
   }
@@ -350,7 +378,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     if (__off > numeric_limits<off_t>::max()
 	|| __off < numeric_limits<off_t>::min())
       return -1L;
+#ifdef _GLIBCXX_USE_PURE_STDIO
+    return fseek(this->file(), __off, __way);
+#else
     return lseek(this->fd(), __off, __way);
+#endif
 #endif
   }
 
@@ -361,7 +393,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   streamsize
   __basic_file<char>::showmanyc()
   {
-#ifndef _GLIBCXX_NO_IOCTL
+#if !defined(_GLIBCXX_NO_IOCTL) && !defined(_GLIBCXX_USE_PURE_STDIO)
 #ifdef FIONREAD
     // Pipes and sockets.
     int __num = 0;
@@ -371,7 +403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 #endif
 
-#ifdef _GLIBCXX_HAVE_POLL
+#if defined(_GLIBCXX_HAVE_POLL) && !defined(_GLIBCXX_USE_PURE_STDIO)
     // Cheap test.
     struct pollfd __pfd[1];
     __pfd[0].fd = this->fd();
@@ -395,8 +427,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct stat __buffer;
     const int __err = fstat(this->fd(), &__buffer);
     if (!__err && _GLIBCXX_ISREG(__buffer.st_mode))
+#ifdef _GLIBCXX_USE_PURE_STDIO
+      return __buffer.st_size - fseek(this->file(), 0, ios_base::cur);
+#else
       return __buffer.st_size - lseek(this->fd(), 0, ios_base::cur);
 #endif
+#endif
 #endif
     return 0;
   }
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index cbfdf4c6bad..733154d070b 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -179,6 +179,7 @@ GLIBCXX_ENABLE_EXTERN_TEMPLATE([yes])
 GLIBCXX_ENABLE_PYTHON
 GLIBCXX_ENABLE_WERROR([no])
 GLIBCXX_ENABLE_VTABLE_VERIFY([no])
+GLIBCXX_ENABLE_PURE_STDIO
 
 # Checks for operating systems support that doesn't require linking.
 GLIBCXX_CHECK_STDIO_PROTO
-- 
2.29.2


  reply	other threads:[~2020-12-07 18:39 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-07 18:39 [PATCH 0/2] Support libc with stdio-only I/O in libstdc++ Keith Packard
2020-12-07 18:39 ` Keith Packard [this message]
2020-12-07 18:55   ` [PATCH 1/2] libstdc++: Add --enable-pure-stdio-libstdcxx option Jonathan Wakely
2020-12-07 20:36     ` Keith Packard
2020-12-09 10:17       ` Jonathan Wakely
2020-12-09 16:32         ` Keith Packard
2020-12-09 16:52           ` Jonathan Wakely
2020-12-10  2:46         ` [PATCH 0/2] Support libc with stdio-only I/O in libstdc++ Keith Packard
2020-12-10  2:46           ` [PATCH 1/2] libstdc++: Add --enable-stdio=stdio_pure option [v2] Keith Packard
2020-12-10 20:23             ` Jonathan Wakely
2020-12-10 20:56               ` Keith Packard
2020-12-15 18:43                 ` Jonathan Wakely
2020-12-10  2:46           ` [PATCH 2/2] Regenerate libstdc++-v3 autoconf files Keith Packard
2020-12-07 18:39 ` Keith Packard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201207183927.3275768-2-keithp@keithp.com \
    --to=keithp@keithp.com \
    --cc=gcc@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).