2011-10-31 Janne Blomqvist <jb@gcc.gnu.org>
* io/unix.h (struct stream): Add size function pointer.
(ssize): New inline function.
(file_length): Remove prototype.
* io/unix.c (raw_size): New function.
(raw_init): Initialize st.size pointer.
(buf_size): New function.
(buf_init): Initialize st.size pointer.
(open_internal): Likewise.
(open_internal4): Likewise.
(file_length): Remove function.
* io/file_pos.c (st_rewind): Use ssize instead of file_length.
* io/open.c (test_endfile): Likewise.
* io/transfer.c (data_transfer_init): Likewise.
(next_record_r): Likewise.
(next_record_w): Likewise.
* io/unit.c (update_position): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180702
138bc75d-0d04-0410-961f-
82ee72b054a4
2011-10-31 Janne Blomqvist <jb@gcc.gnu.org>
+ * io/unix.h (struct stream): Add size function pointer.
+ (ssize): New inline function.
+ (file_length): Remove prototype.
+ * io/unix.c (raw_size): New function.
+ (raw_init): Initialize st.size pointer.
+ (buf_size): New function.
+ (buf_init): Initialize st.size pointer.
+ (open_internal): Likewise.
+ (open_internal4): Likewise.
+ (file_length): Remove function.
+ * io/file_pos.c (st_rewind): Use ssize instead of file_length.
+ * io/open.c (test_endfile): Likewise.
+ * io/transfer.c (data_transfer_init): Likewise.
+ (next_record_r): Likewise.
+ (next_record_w): Likewise.
+ * io/unit.c (update_position): Likewise.
+
+2011-10-31 Janne Blomqvist <jb@gcc.gnu.org>
+
* io/file_pos.c (st_rewind): Handle regular and special files
identically.
* io/intrinsics.c (fseek_sub): Don't check whether we think the
generate_error (&fpp->common, LIBERROR_OS, NULL);
/* Set this for compatibilty with g77 for /dev/null. */
- if (file_length (u->s) == 0)
+ if (ssize (u->s) == 0)
u->endfile = AT_ENDFILE;
else
{
static void
test_endfile (gfc_unit * u)
{
- if (u->endfile == NO_ENDFILE && file_length (u->s) == stell (u->s))
+ if (u->endfile == NO_ENDFILE && ssize (u->s) == stell (u->s))
u->endfile = AT_ENDFILE;
}
a partial record needs to exist. */
if (dtp->u.p.mode == READING && (dtp->rec - 1)
- * dtp->u.p.current_unit->recl >= file_length (dtp->u.p.current_unit->s))
+ * dtp->u.p.current_unit->recl >= ssize (dtp->u.p.current_unit->s))
{
generate_error (&dtp->common, LIBERROR_BAD_OPTION,
"Non-existing record number");
{
bytes_left = (int) dtp->u.p.current_unit->bytes_left;
bytes_left = min_off (bytes_left,
- file_length (dtp->u.p.current_unit->s)
+ ssize (dtp->u.p.current_unit->s)
- stell (dtp->u.p.current_unit->s));
if (sseek (dtp->u.p.current_unit->s,
bytes_left, SEEK_CUR) < 0)
{
dtp->u.p.current_unit->strm_pos += len;
if (dtp->u.p.current_unit->strm_pos
- < file_length (dtp->u.p.current_unit->s))
+ < ssize (dtp->u.p.current_unit->s))
unit_truncate (dtp->u.p.current_unit,
dtp->u.p.current_unit->strm_pos - 1,
&dtp->common);
return;
else if (cur == 0)
u->flags.position = POSITION_REWIND;
- else if (file_length (u->s) == cur)
+ else if (ssize (u->s) == cur)
u->flags.position = POSITION_APPEND;
else
u->flags.position = POSITION_ASIS;
return lseek (s->fd, 0, SEEK_CUR);
}
+static gfc_offset
+raw_size (unix_stream * s)
+{
+ struct stat statbuf;
+ int ret = fstat (s->fd, &statbuf);
+ if (ret == -1)
+ return ret;
+ return statbuf.st_size;
+}
+
static int
raw_truncate (unix_stream * s, gfc_offset length)
{
s->st.write = (void *) raw_write;
s->st.seek = (void *) raw_seek;
s->st.tell = (void *) raw_tell;
+ s->st.size = (void *) raw_size;
s->st.trunc = (void *) raw_truncate;
s->st.close = (void *) raw_close;
s->st.flush = (void *) raw_flush;
return buf_seek (s, 0, SEEK_CUR);
}
+static gfc_offset
+buf_size (unix_stream * s)
+{
+ return s->file_length;
+}
+
static int
buf_truncate (unix_stream * s, gfc_offset length)
{
s->st.write = (void *) buf_write;
s->st.seek = (void *) buf_seek;
s->st.tell = (void *) buf_tell;
+ s->st.size = (void *) buf_size;
s->st.trunc = (void *) buf_truncate;
s->st.close = (void *) buf_close;
s->st.flush = (void *) buf_flush;
s->st.close = (void *) mem_close;
s->st.seek = (void *) mem_seek;
s->st.tell = (void *) mem_tell;
+ /* buf_size is not a typo, we just reuse an identical
+ implementation. */
+ s->st.size = (void *) buf_size;
s->st.trunc = (void *) mem_truncate;
s->st.read = (void *) mem_read;
s->st.write = (void *) mem_write;
s->st.close = (void *) mem_close;
s->st.seek = (void *) mem_seek;
s->st.tell = (void *) mem_tell;
+ /* buf_size is not a typo, we just reuse an identical
+ implementation. */
+ s->st.size = (void *) buf_size;
s->st.trunc = (void *) mem_truncate;
s->st.read = (void *) mem_read4;
s->st.write = (void *) mem_write4;
}
-/* file_length()-- Return the file length in bytes, -1 if unknown */
-
-gfc_offset
-file_length (stream * s)
-{
- gfc_offset curr, end;
- curr = stell (s);
- if (curr == -1)
- return curr;
- end = sseek (s, 0, SEEK_END);
- sseek (s, curr, SEEK_SET);
- return end;
-}
-
-
int
stream_isatty (stream *s)
{
ssize_t (*write) (struct stream *, const void *, ssize_t);
gfc_offset (*seek) (struct stream *, gfc_offset, int);
gfc_offset (*tell) (struct stream *);
+ gfc_offset (*size) (struct stream *);
/* Avoid keyword truncate due to AIX namespace collision. */
int (*trunc) (struct stream *, gfc_offset);
int (*flush) (struct stream *);
return s->tell (s);
}
+static inline gfc_offset
+ssize (stream * s)
+{
+ return s->size (s);
+}
+
static inline int
struncate (stream * s, gfc_offset length)
{
extern const char *inquire_readwrite (const char *, int);
internal_proto(inquire_readwrite);
-extern gfc_offset file_length (stream *);
-internal_proto(file_length);
-
extern void flush_if_preconnected (stream *);
internal_proto(flush_if_preconnected);