[GRASS-user] i.rectify - ERROR: error while writing to temp file

Hi,

I'm trying to rectify some scanned maps, but I've this error:

ERROR: error while writing to tmp file

I've checked the write permission of .tmp directory and it's ok...

I've 15 GB of free space.

How can I solve this problem?

The .tmp directory where the .tmp files are saved, are the source
LOCATION (xy) or target LOCATION?

Alfredo

Alfredo:

I'm trying to rectify some scanned maps, but I've
this error:

ERROR: error while writing to tmp file

I've checked the write permission of .tmp directory and
it's ok...

I've 15 GB of free space.

How can I solve this problem?

The .tmp directory where the .tmp files are saved, are the
source LOCATION (xy) or target LOCATION?

No idea, but the help page says this:
---
If i.rectify starts normally but after some time the following text is seen:
GIS ERROR: error while writing to temp file
the user may try the flag -c (or the module needs more free space on the hard drive).
---

The -c flag: "Use curr. region settings in target location (def.=calculate smallest area)"

the code that triggers that is this, in i.rectify/write.c:
---
offset = ((off_t) row++ * target_window.cols + col) *
          G_raster_size(map_type);
lseek(temp_fd,offset,SEEK_SET);

if(write(temp_fd,cell_buf[n],G_raster_size(map_type)*matrix_cols)
                          != G_raster_size(map_type)*matrix_cols)
{
    unlink(temp_name);
    G_fatal_error("error while writing to temp file");
}
---

?does the (off_t) cast only affect nearest row++ and not the whole (row*col+col)? or does the whole thing get promoted once one part of the calc is cast to off_t? or is that ok?

how does the region in your target mapset look like? of your source image?

Hamish

Hamish wrote:

> I'm trying to rectify some scanned maps, but I've
> this error:
>
> ERROR: error while writing to tmp file
>
> I've checked the write permission of .tmp directory and
> it's ok...
>
> I've 15 GB of free space.
>
> How can I solve this problem?
>
> The .tmp directory where the .tmp files are saved, are the
> source LOCATION (xy) or target LOCATION?

No idea, but the help page says this:
---
If i.rectify starts normally but after some time the following text is seen:
GIS ERROR: error while writing to temp file
the user may try the flag -c (or the module needs more free space on the hard drive).
---

The -c flag: "Use curr. region settings in target location (def.=calculate smallest area)"

the code that triggers that is this, in i.rectify/write.c:
---
offset = ((off_t) row++ * target_window.cols + col) *
          G_raster_size(map_type);
lseek(temp_fd,offset,SEEK_SET);

if(write(temp_fd,cell_buf[n],G_raster_size(map_type)*matrix_cols)
                          != G_raster_size(map_type)*matrix_cols)
{
    unlink(temp_name);
    G_fatal_error("error while writing to temp file");
}
---

However: note that nothing prior to the above checks that the temp_fd
returned from creat() is valid. So, if creat() fails, the first
indication will be that write() fails (with EBADF).

I suggest adding an explicit check for the return value from creat(),
i.e.:

        temp_fd = creat(temp_name,0660);
+ if (temp_fd < 0)
+ G_fatal_error("unable to open temporary file");

This will make it possible to distinguish between an error when
opening the file (e.g. EPERM = "permission denied") and an error when
writing to the file (e.g. ENOSPC = "no space left on device").

?does the (off_t) cast only affect nearest row++ and not the whole
(row*col+col)? or does the whole thing get promoted once one part of
the calc is cast to off_t? or is that ok?

In C, types propagate upwards from the leaves. The result type of a
diadic operator (addition, multiplication) etc is equal to the
"largest" operand type, where long long > long > int, and double is
deemed larger than all integral types.

When dealing with off_t, the general rule is to cast one "limb" of any
multiplication to off_t (it's invariably multiplications where any
truncation will occur). The result of the multiplication will then be
off_t, as will the result of any enclosing expression involving that
value.

So, in the above code, the off_t propagates up to the result of the
first multiplication, and then to the addition, then to the second
multiplication, and then to the assignment.

OTOH, this won't work:

  offset = (off_t) ((row++ * target_window.cols + col) * G_raster_size(map_type));

as all of the calculations will be truncated to lesser types (int,
long, size_t), and by the time that the value is cast to off_t
(immediately before the assignment), it has already been truncated.

--
Glynn Clements <glynn@gclements.plus.com>

2008/6/13 Glynn Clements <glynn@gclements.plus.com>:

Hamish wrote:

> I'm trying to rectify some scanned maps, but I've
> this error:
>
> ERROR: error while writing to tmp file
>
> I've checked the write permission of .tmp directory and
> it's ok...
>
> I've 15 GB of free space.
>
> How can I solve this problem?
>
> The .tmp directory where the .tmp files are saved, are the
> source LOCATION (xy) or target LOCATION?

No idea, but the help page says this:
---
If i.rectify starts normally but after some time the following text is seen:
GIS ERROR: error while writing to temp file
the user may try the flag -c (or the module needs more free space on the hard drive).
---

The -c flag: "Use curr. region settings in target location (def.=calculate smallest area)"

the code that triggers that is this, in i.rectify/write.c:
---
offset = ((off_t) row++ * target_window.cols + col) *
          G_raster_size(map_type);
lseek(temp_fd,offset,SEEK_SET);

if(write(temp_fd,cell_buf[n],G_raster_size(map_type)*matrix_cols)
                          != G_raster_size(map_type)*matrix_cols)
{
    unlink(temp_name);
    G_fatal_error("error while writing to temp file");
}
---

However: note that nothing prior to the above checks that the temp_fd
returned from creat() is valid. So, if creat() fails, the first
indication will be that write() fails (with EBADF).

I suggest adding an explicit check for the return value from creat(),
i.e.:

       temp_fd = creat(temp_name,0660);
+ if (temp_fd < 0)
+ G_fatal_error("unable to open temporary file");

This will make it possible to distinguish between an error when
opening the file (e.g. EPERM = "permission denied") and an error when
writing to the file (e.g. ENOSPC = "no space left on device").

?does the (off_t) cast only affect nearest row++ and not the whole
(row*col+col)? or does the whole thing get promoted once one part of
the calc is cast to off_t? or is that ok?

In C, types propagate upwards from the leaves. The result type of a
diadic operator (addition, multiplication) etc is equal to the
"largest" operand type, where long long > long > int, and double is
deemed larger than all integral types.

When dealing with off_t, the general rule is to cast one "limb" of any
multiplication to off_t (it's invariably multiplications where any
truncation will occur). The result of the multiplication will then be
off_t, as will the result of any enclosing expression involving that
value.

So, in the above code, the off_t propagates up to the result of the
first multiplication, and then to the addition, then to the second
multiplication, and then to the assignment.

OTOH, this won't work:

       offset = (off_t) ((row++ * target_window.cols + col) * G_raster_size(map_type));

as all of the calculations will be truncated to lesser types (int,
long, size_t), and by the time that the value is cast to off_t
(immediately before the assignment), it has already been truncated.

--
Glynn Clements <glynn@gclements.plus.com>

I've solved....

The region that I've setting is too large :slight_smile:

Now, it's work well...

Alfredo