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.c122
1 files changed, 116 insertions, 6 deletions
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index f0cd3b9b16c..3a795aef536 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -405,6 +405,10 @@ buf_flush (unix_stream * s)
if (s->ndirty != 0)
return -1;
+#ifdef _WIN32
+ _commit (s->fd);
+#endif
+
return 0;
}
@@ -594,7 +598,6 @@ buf_init (unix_stream * s)
*********************************************************************/
-
char *
mem_alloc_r (stream * strm, int * len)
{
@@ -616,6 +619,26 @@ mem_alloc_r (stream * strm, int * len)
char *
+mem_alloc_r4 (stream * strm, int * len)
+{
+ unix_stream * s = (unix_stream *) strm;
+ gfc_offset n;
+ gfc_offset where = s->logical_offset;
+
+ if (where < s->buffer_offset || where > s->buffer_offset + s->active)
+ return NULL;
+
+ n = s->buffer_offset + s->active - where;
+ if (*len > n)
+ *len = n;
+
+ s->logical_offset = where + *len;
+
+ return s->buffer + (where - s->buffer_offset) * 4;
+}
+
+
+char *
mem_alloc_w (stream * strm, int * len)
{
unix_stream * s = (unix_stream *) strm;
@@ -636,7 +659,28 @@ mem_alloc_w (stream * strm, int * len)
}
-/* Stream read function for internal units. */
+gfc_char4_t *
+mem_alloc_w4 (stream * strm, int * len)
+{
+ unix_stream * s = (unix_stream *) strm;
+ gfc_offset m;
+ gfc_offset where = s->logical_offset;
+ gfc_char4_t *result = (gfc_char4_t *) s->buffer;
+
+ m = where + *len;
+
+ if (where < s->buffer_offset)
+ return NULL;
+
+ if (m > s->file_length)
+ return NULL;
+
+ s->logical_offset = m;
+ return &result[where - s->buffer_offset];
+}
+
+
+/* Stream read function for character(kine=1) internal units. */
static ssize_t
mem_read (stream * s, void * buf, ssize_t nbytes)
@@ -655,9 +699,26 @@ mem_read (stream * s, void * buf, ssize_t nbytes)
}
-/* Stream write function for internal units. This is not actually used
- at the moment, as all internal IO is formatted and the formatted IO
- routines use mem_alloc_w_at. */
+/* Stream read function for chracter(kind=4) internal units. */
+
+static ssize_t
+mem_read4 (stream * s, void * buf, ssize_t nbytes)
+{
+ void *p;
+ int nb = nbytes;
+
+ p = mem_alloc_r (s, &nb);
+ if (p)
+ {
+ memcpy (buf, p, nb);
+ return (ssize_t) nb;
+ }
+ else
+ return 0;
+}
+
+
+/* Stream write function for character(kind=1) internal units. */
static ssize_t
mem_write (stream * s, const void * buf, ssize_t nbytes)
@@ -676,6 +737,26 @@ mem_write (stream * s, const void * buf, ssize_t nbytes)
}
+/* Stream write function for character(kind=4) internal units. */
+
+static ssize_t
+mem_write4 (stream * s, const void * buf, ssize_t nwords)
+{
+ gfc_char4_t *p;
+ int nw = nwords;
+
+ p = mem_alloc_w4 (s, &nw);
+ if (p)
+ {
+ while (nw--)
+ *p++ = (gfc_char4_t) *((char *) buf);
+ return nwords;
+ }
+ else
+ return 0;
+}
+
+
static gfc_offset
mem_seek (stream * strm, gfc_offset offset, int whence)
{
@@ -759,7 +840,8 @@ empty_internal_buffer(stream *strm)
memset(s->buffer, ' ', s->file_length);
}
-/* open_internal()-- Returns a stream structure from an internal file */
+/* open_internal()-- Returns a stream structure from a character(kind=1)
+ internal file */
stream *
open_internal (char *base, int length, gfc_offset offset)
@@ -786,6 +868,34 @@ open_internal (char *base, int length, gfc_offset offset)
return (stream *) s;
}
+/* open_internal4()-- Returns a stream structure from a character(kind=4)
+ internal file */
+
+stream *
+open_internal4 (char *base, int length, gfc_offset offset)
+{
+ unix_stream *s;
+
+ s = get_mem (sizeof (unix_stream));
+ memset (s, '\0', sizeof (unix_stream));
+
+ s->buffer = base;
+ s->buffer_offset = offset;
+
+ s->logical_offset = 0;
+ s->active = s->file_length = length;
+
+ s->st.close = (void *) mem_close;
+ s->st.seek = (void *) mem_seek;
+ s->st.tell = (void *) mem_tell;
+ s->st.trunc = (void *) mem_truncate;
+ s->st.read = (void *) mem_read4;
+ s->st.write = (void *) mem_write4;
+ s->st.flush = (void *) mem_flush;
+
+ return (stream *) s;
+}
+
/* fd_to_stream()-- Given an open file descriptor, build a stream
* around it. */