public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [patch, libgfortran] PR30162 Named pipe formatted I/O
@ 2007-01-05  7:11 Thomas Koenig
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Koenig @ 2007-01-05  7:11 UTC (permalink / raw)
  To: fortran; +Cc: gcc-patches

:REVIEWMAIL:

Hi Jerry,

the patch is OK.

Thanks for taking this on!

	Thomas

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [patch, libgfortran] PR30162 Named pipe formatted I/O
@ 2007-01-05  4:59 Jerry DeLisle
  0 siblings, 0 replies; 2+ messages in thread
From: Jerry DeLisle @ 2007-01-05  4:59 UTC (permalink / raw)
  To: Fortran List; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 970 bytes --]

:ADDPATCH fortran:

This is a first installment of fixes for this bug.  The attached patch allows 
formatted I/O to named pipes by avoiding attempts to seek when the file is 
unseekable.  It is fairly self explanatory.

Regression tested on x86-64-Linux-gnu.  I am not clear on how to test this 
within the test suite machinery.  I have attached two test cases.  Run one in 
the background, then run the other.  You must first create the FIFO with 'mkfifo np'

OK for trunk and then 4.2

Regards,

Jerry

2007-01-04  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.

[-- Attachment #2: pr30162-b.diff --]
[-- Type: text/x-patch, Size: 3318 bytes --]

Index: io/unix.c
===================================================================
*** io/unix.c	(revision 120378)
--- io/unix.c	(working copy)
*************** fd_flush (unix_stream * s)
*** 349,357 ****
    size_t writelen;
  
    if (s->ndirty == 0)
!     return SUCCESS;;
! 
!   if (s->physical_offset != s->dirty_offset &&
        lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
      return FAILURE;
  
--- 349,357 ----
    size_t writelen;
  
    if (s->ndirty == 0)
!     return SUCCESS;
!   
!   if (s->file_length != -1 && s->physical_offset != s->dirty_offset &&
        lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
      return FAILURE;
  
*************** fd_alloc_w_at (unix_stream * s, int *len
*** 536,543 ****
  
    s->logical_offset = where + *len;
  
!   if (where + *len > s->file_length)
!     s->file_length = where + *len;
  
    n = s->logical_offset - s->buffer_offset;
    if (n > s->active)
--- 536,545 ----
  
    s->logical_offset = 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)
*************** fd_sfree (unix_stream * s)
*** 562,567 ****
--- 564,573 ----
  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;
*************** fd_seek (unix_stream * s, gfc_offset off
*** 582,594 ****
  static try
  fd_truncate (unix_stream * s)
  {
    if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
!     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.
!   */
  #ifdef HAVE_FTRUNCATE
    if (s->special_file || ftruncate (s->fd, s->logical_offset))
  #else
--- 588,606 ----
  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)
!     {
!       if (errno ==  ESPIPE)
! 	return SUCCESS;
!       else
! 	return FAILURE;
!     }
  
!   /* 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
*************** fd_to_stream (int fd, int prot)
*** 1009,1015 ****
    /* Get the current length of the file. */
  
    fstat (fd, &statbuf);
!   s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
    s->special_file = !S_ISREG (statbuf.st_mode);
  
    fd_open (s);
--- 1021,1032 ----
    /* Get the current length of the file. */
  
    fstat (fd, &statbuf);
! 
!   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);

[-- Attachment #3: read.f --]
[-- Type: text/x-fortran, Size: 205 bytes --]

      integer status
      integer i
      integer val
      open(unit=21,file='np',action='read',form='formatted');
      do i = 1,250000
         read(21,*)val
         print*,val
      end do
      end

[-- Attachment #4: write.f --]
[-- Type: text/x-fortran, Size: 179 bytes --]

      integer status
      integer i
      open(unit=20,file='np',action='write',
     &     form='formatted');
      do i = 1,250000
         write(20,*)i
      end do
      end

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-01-05  7:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-05  7:11 [patch, libgfortran] PR30162 Named pipe formatted I/O Thomas Koenig
  -- strict thread matches above, loose matches on Subject: below --
2007-01-05  4:59 Jerry DeLisle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).