re PR libfortran/30162 (Document when sequential I/O with named pipes works)

2007-01-05  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/30162
	* io/unix.c (fd_flush): Don't seek if file is not seekable, defined as
	s->file_length == -1.
	(fd_alloc_w_at): Do not adjust file_length if file is not seekable.
	(fd_seek): If not seekable, just return success.
	(fd_truncate): If not seekable, no need to truncate.  Return failure if
	seek fails and the stream is not a pipe.
	(fd_to_stream): Make test for non-seekable file more robust.

From-SVN: r120512
This commit is contained in:
Jerry DeLisle 2007-01-06 00:14:38 +00:00
parent 59c0753dd3
commit 779f397598
2 changed files with 39 additions and 11 deletions

View File

@ -1,3 +1,14 @@
2007-01-05 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/30162
* io/unix.c (fd_flush): Don't seek if file is not seekable, defined as
s->file_length == -1.
(fd_alloc_w_at): Do not adjust file_length if file is not seekable.
(fd_seek): If not seekable, just return success.
(fd_truncate): If not seekable, no need to truncate. Return failure if
seek fails and the stream is not a pipe.
(fd_to_stream): Make test for non-seekable file more robust.
2007-01-01 Steven G. Kargl <kargls@comcast.net>
* ChangeLog: Copied to ...

View File

@ -349,9 +349,9 @@ fd_flush (unix_stream * s)
size_t writelen;
if (s->ndirty == 0)
return SUCCESS;;
if (s->physical_offset != s->dirty_offset &&
return SUCCESS;
if (s->file_length != -1 && s->physical_offset != s->dirty_offset &&
lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
return FAILURE;
@ -536,8 +536,10 @@ fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
s->logical_offset = where + *len;
if (where + *len > s->file_length)
s->file_length = where + *len;
/* Don't increment file_length if the file is non-seekable. */
if (s->file_length != -1 && s->logical_offset > s->file_length)
s->file_length = s->logical_offset;
n = s->logical_offset - s->buffer_offset;
if (n > s->active)
@ -562,6 +564,10 @@ fd_sfree (unix_stream * s)
static try
fd_seek (unix_stream * s, gfc_offset offset)
{
if (s->file_length == -1)
return SUCCESS;
if (s->physical_offset == offset) /* Are we lucky and avoid syscall? */
{
s->logical_offset = offset;
@ -582,13 +588,19 @@ fd_seek (unix_stream * s, gfc_offset offset)
static try
fd_truncate (unix_stream * s)
{
/* Non-seekable files, like terminals and fifo's fail the lseek so just
return success, there is nothing to truncate. If its not a pipe there
is a real problem. */
if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
return FAILURE;
{
if (errno == ESPIPE)
return SUCCESS;
else
return FAILURE;
}
/* non-seekable files, like terminals and fifo's fail the lseek.
Using ftruncate on a seekable special file (like /dev/null)
is undefined, so we treat it as if the ftruncate succeeded.
*/
/* Using ftruncate on a seekable special file (like /dev/null)
is undefined, so we treat it as if the ftruncate succeeded. */
#ifdef HAVE_FTRUNCATE
if (s->special_file || ftruncate (s->fd, s->logical_offset))
#else
@ -1009,7 +1021,12 @@ fd_to_stream (int fd, int prot)
/* Get the current length of the file. */
fstat (fd, &statbuf);
s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
if (lseek (fd, 0, SEEK_CUR) == (off_t) -1)
s->file_length = -1;
else
s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
s->special_file = !S_ISREG (statbuf.st_mode);
fd_open (s);