[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