about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-07-13 16:43:24 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2018-10-02 10:01:56 -0300
commit0b727ed4d605d9318cb0d323c88abb0d5a441a9b (patch)
tree456efbab739f291b486ee8d937703cb0d4db5cef /sysdeps
parentd0e91e8c4ef77997c940538eaa752799c9dda2d3 (diff)
downloadglibc-0b727ed4d605d9318cb0d323c88abb0d5a441a9b.tar.gz
glibc-0b727ed4d605d9318cb0d323c88abb0d5a441a9b.tar.xz
glibc-0b727ed4d605d9318cb0d323c88abb0d5a441a9b.zip
libio: Flush stream at freopen (BZ#21037)
As POSIX states [1] a freopen call should first flush the stream as if by a
call fflush.  C99 (n1256) and C11 (n1570) only states the function should
first close any file associated with the specific stream.  Although current
implementation only follow C specification, current BSD and other libc
implementation (musl) are in sync with POSIX and fflush the stream.

This patch change freopen{64} to fflush the stream before actually reopening
it (or returning if the stream does not support reopen).  It also changes the
Linux implementation to avoid a dynamic allocation on 'fd_to_filename'.

Checked on x86_64-linux-gnu.

	[BZ #21037]
	* libio/Makefile (tests): Add tst-memstream4 and tst-wmemstream4.
	* libio/freopen.c (freopen): Sync stream before reopen and adjust to
	new fd_to_filename interface.
	* libio/freopen64.c (freopen64): Likewise.
	* libio/tst-memstream.h: New file.
	* libio/tst-memstream4.c: Likewise.
	* libio/tst-wmemstream4.c: Likewise.
	* sysdeps/generic/fd_to_filename.h (fd_to_filename): Change signature.
	* sysdeps/unix/sysv/linux/fd_to_filename.h (fd_to_filename): Likewise
	and remove internal dynamic allocation.

[1] http://pubs.opengroup.org/onlinepubs/9699919799/
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/fd_to_filename.h4
-rw-r--r--sysdeps/unix/sysv/linux/fd_to_filename.h34
2 files changed, 15 insertions, 23 deletions
diff --git a/sysdeps/generic/fd_to_filename.h b/sysdeps/generic/fd_to_filename.h
index bacfe5bf52..d41b345a9d 100644
--- a/sysdeps/generic/fd_to_filename.h
+++ b/sysdeps/generic/fd_to_filename.h
@@ -16,10 +16,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define FD_TO_FILENAME_SIZE 0
+
 /* In general there is no generic way to query filename for an open
    file descriptor.  */
 static inline const char *
-fd_to_filename (int fd)
+fd_to_filename (int fd, char *buf)
 {
   return NULL;
 }
diff --git a/sysdeps/unix/sysv/linux/fd_to_filename.h b/sysdeps/unix/sysv/linux/fd_to_filename.h
index 297716b0ae..62bc9916b0 100644
--- a/sysdeps/unix/sysv/linux/fd_to_filename.h
+++ b/sysdeps/unix/sysv/linux/fd_to_filename.h
@@ -16,30 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stdlib.h>
-#include <string.h>
 #include <sys/stat.h>
-#include <_itoa.h>
+
+#define FD_TO_FILENAME_SIZE ((sizeof ("/proc/self/fd/") - 1) \
+			     + (sizeof ("4294967295") - 1) + 1)
 
 static inline const char *
-fd_to_filename (int fd)
+fd_to_filename (unsigned int fd, char *buf)
 {
-  char *ret = malloc (30);
-
-  if (ret != NULL)
-    {
-      struct stat64 st;
-
-      *_fitoa_word (fd, __stpcpy (ret, "/proc/self/fd/"), 10, 0) = '\0';
-
-      /* We must make sure the file exists.  */
-      if (__lxstat64 (_STAT_VER, ret, &st) < 0)
-	{
-	  /* /proc is not mounted or something else happened.  Don't
-	     return the file name.  */
-	  free (ret);
-	  ret = NULL;
-	}
-    }
-  return ret;
+  *_fitoa_word (fd, __stpcpy (buf, "/proc/self/fd/"), 10, 0) = '\0';
+
+  /* We must make sure the file exists.  */
+  struct stat64 st;
+  if (__lxstat64 (_STAT_VER, buf, &st) < 0)
+    /* /proc is not mounted or something else happened.  */
+    return NULL;
+  return buf;
 }