aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/io/unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgfortran/io/unix.c')
-rw-r--r--libgfortran/io/unix.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 8b9d7a7..08fe4fe 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -212,6 +212,8 @@ typedef struct
/* Cached stat(2) values. */
dev_t st_dev;
ino_t st_ino;
+
+ bool unbuffered; /* Buffer should be flushed after each I/O statement. */
}
unix_stream;
@@ -442,7 +444,7 @@ raw_init (unix_stream * s)
Buffered I/O functions. These functions have the same semantics as the
raw I/O functions above, except that they are buffered in order to
improve performance. The buffer must be flushed when switching from
-reading to writing and vice versa. Only supported for regular files.
+reading to writing and vice versa.
*********************************************************************/
static int
@@ -968,11 +970,26 @@ open_internal4 (char *base, int length, gfc_offset offset)
}
+/* "Unbuffered" really means I/O statement buffering. For formatted
+ I/O, the fbuf manages this, and then uses raw I/O. For unformatted
+ I/O, buffered I/O is used, and the buffer is flushed at the end of
+ each I/O statement, where this function is called. */
+
+int
+flush_if_unbuffered (stream* s)
+{
+ unix_stream* us = (unix_stream*) s;
+ if (us->unbuffered)
+ return sflush (s);
+ return 0;
+}
+
+
/* fd_to_stream()-- Given an open file descriptor, build a stream
* around it. */
static stream *
-fd_to_stream (int fd)
+fd_to_stream (int fd, bool unformatted)
{
struct stat statbuf;
unix_stream *s;
@@ -998,7 +1015,15 @@ fd_to_stream (int fd)
|| s->fd == STDERR_FILENO)))
buf_init (s);
else
- raw_init (s);
+ {
+ if (unformatted)
+ {
+ s->unbuffered = true;
+ buf_init (s);
+ }
+ else
+ raw_init (s);
+ }
return (stream *) s;
}
@@ -1364,7 +1389,7 @@ open_external (st_parameter_open *opp, unit_flags *flags)
return NULL;
fd = fix_fd (fd);
- return fd_to_stream (fd);
+ return fd_to_stream (fd, flags->form == FORM_UNFORMATTED);
}
@@ -1374,7 +1399,7 @@ open_external (st_parameter_open *opp, unit_flags *flags)
stream *
input_stream (void)
{
- return fd_to_stream (STDIN_FILENO);
+ return fd_to_stream (STDIN_FILENO, false);
}
@@ -1390,7 +1415,7 @@ output_stream (void)
setmode (STDOUT_FILENO, O_BINARY);
#endif
- s = fd_to_stream (STDOUT_FILENO);
+ s = fd_to_stream (STDOUT_FILENO, false);
return s;
}
@@ -1407,7 +1432,7 @@ error_stream (void)
setmode (STDERR_FILENO, O_BINARY);
#endif
- s = fd_to_stream (STDERR_FILENO);
+ s = fd_to_stream (STDERR_FILENO, false);
return s;
}