[GRASS-dev] Re: [GRASS GIS] #1006: r.terraflow fails to stat() stream file on Windows

GRASS GIS trac at osgeo.org
Thu Apr 29 07:30:36 EDT 2010


#1006: r.terraflow fails to stat() stream file on Windows
------------------------------+---------------------------------------------
  Reporter:  marisn           |       Owner:  grass-dev at lists.osgeo.org
      Type:  defect           |      Status:  new                      
  Priority:  critical         |   Milestone:  6.4.0                    
 Component:  Raster           |     Version:  svn-releasebranch64      
Resolution:                   |    Keywords:  wingrass, r.terraflow    
  Platform:  MSWindows Vista  |         Cpu:  x86-32                   
------------------------------+---------------------------------------------
Comment (by adanner):

 Replying to [comment:24 hamish]:
 > In comment:12, Hamish wrote:
 > > > ok, so str->stream_len() is not getting set correctly.
 > ...
 > > > stream_len() is defined in include/iostream/ami_stream.h (number of
 items in each stream)
 >
 >
 > In comment:22, Glynn wrote:
 > > A more portable way to determine the length of a file is to use
 fseek(SEEK_END), e.g.:
 > {{{
 >       long save = ftell(fp);
 >       fseek(fp, 0, SEEK_END);
 >       long size = ftell(fp);
 >       fseek(fp, save, SEEK_SET);
 >       return size;
 > }}}
 >
 >
 > ok, thanks. how's this:
 >
 > (patch vs. 6.5svn)
 > {{{
 > Index: include/iostream/ami_stream.h
 > ===================================================================
 > --- include/iostream/ami_stream.h       (revision 41749)
 > +++ include/iostream/ami_stream.h       (working copy)
 > @@ -351,21 +351,32 @@
 >  template<class T>
 >  off_t AMI_STREAM<T>::stream_len(void) {
 >
 > +  long posn_save, st_size;
 > +
 >    fflush(fp);
 >
 > -  struct stat buf;
 > -  if (stat(path, &buf) == -1) {
 > -    perror("AMI_STREAM::stream_len(): fstat failed ");
 > -       perror(path);
 > -    assert(0);
 > -    exit(1);
 > +  posn_save = ftell(fp);
 > +  if(posn_save == -1) {
 > +     perror("ERROR: AMI_STREAM::stream_len(): ftell(fp) failed ");
 > +     perror(path);
 > +     exit(1);
 >    }
 >
 > +  fseek(fp, 0, SEEK_END);
 > +  st_size = ftell(fp);
 > +  if(st_size == -1) {
 > +     perror("ERROR: AMI_STREAM::stream_len(): ftell[SEEK_END] failed
 ");
 > +     perror(path);
 > +     exit(1);
 > +  }
 > +
 > +  fseek(fp, posn_save, SEEK_SET);
 > +
 >    //DEBUG:
 >    fprintf(stderr, "%s: length = %lld   sizeof(T)=%d\n",
 > -         path, buf.st_size, sizeof(T));
 > +         path, st_size, sizeof(T));
 >
 > -  return (buf.st_size / sizeof(T));
 > +  return (st_size / sizeof(T));
 >  };
 >
 >
 > }}}
 >
 >
 > Hamish

 fseek and ftell only work for 32-bit file offsets on 32-bit system as the
 offset for fseek and the return value of ftell is a long type. At least in
 linux, the proper return type is an off_t which can be set to 32 or 64
 bits at compile time and fseeko and ftello use off_t types. A real fix
 should support 64 bit file offsets on 32 bit and 64-bit systems in Windows
 and Linux, but this gets a bit complicated. Is there a guaranteed portable
 64-bit type in Grass? A portable 64-bit G_fseek might avoid future
 problems of this type.

-- 
Ticket URL: <https://trac.osgeo.org/grass/ticket/1006#comment:25>
GRASS GIS <http://grass.osgeo.org>


More information about the grass-dev mailing list