GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
raster/close.c
Go to the documentation of this file.
1/*!
2 * \file lib/raster/close.c
3 *
4 * \brief Raster Library - Close raster file
5 *
6 * (C) 1999-2009 by the GRASS Development Team
7 *
8 * This program is free software under the GNU General Public
9 * License (>=v2). Read the file COPYING that comes with GRASS
10 * for details.
11 *
12 * \author USACERL and many others
13 */
14
15#ifdef _WIN32
16#include <windows.h>
17#endif
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23#include <fcntl.h>
24#include <signal.h>
25#include <errno.h>
26
27#include <grass/gis.h>
28#include <grass/raster.h>
29#include <grass/glocale.h>
30
31#include "R.h"
32
33#define FORMAT_FILE "f_format"
34#define QUANT_FILE "f_quant"
35#define NULL_FILE "null"
36/* cmpressed null file */
37#define NULLC_FILE "nullcmpr"
38
39static int close_old(int);
40static int close_new(int, int);
41
42static void sync_and_close(int fd, char *element, char *name)
43{
44 /* from man 2 write:
45 * A successful return from write() does not make any guarantee
46 * that data has been committed to disk. On some filesystems,
47 * including NFS, it does not even guarantee that space has
48 * successfully been reserved for the data. In this case, some
49 * errors might be delayed until a future write(2), fsync(2), or
50 * even close(2). The only way to be sure is to call fsync(2)
51 * after you are done writing all your data.
52 */
53
54#ifndef _WIN32
55 if (fsync(fd)) {
56 G_warning(_("Unable to flush file %s for raster map %s: %s"), element,
58 }
59 /* for MS Windows, try fdopen(int, char *) + fflush(FILE *) + fclose(FILE *)
60 * flcose() closes the underlying file descriptor, thus no need to
61 * call close(fd) afterwards */
62#endif
63 if (close(fd)) {
64 G_warning(_("Unable to close file %s for raster map %s: %s"), element,
66 }
67}
68
69static void write_fp_format(int fd);
70
71/*!
72 * \brief Close a raster map
73 *
74 * The raster map opened on file descriptor <i>fd</i> is
75 * closed. Memory allocated for raster processing is freed. If open
76 * for writing, skeletal support files for the new raster map are
77 * created as well.
78 *
79 * <b>Note:</b> If a module wants to explicitly write support files
80 * (e.g., a specific color table) for a raster map it creates, it must
81 * do so after the raster map is closed. Otherwise the close will
82 * overwrite the support files. See \ref
83 * Raster_Map_Layer_Support_Routines for routines which write raster
84 * support files.
85 *
86 * If the map is a new floating point, move the <tt>.tmp</tt> file
87 * into the <tt>fcell</tt> element, create an empty file in the
88 * <tt>cell</tt> directory; write the floating-point range file; write
89 * a default quantization file quantization file is set here to round
90 * fp numbers (this is a default for now). create an empty category
91 * file, with max cat = max value (for backwards compatibility). Move
92 * the <tt>.tmp</tt> NULL-value bitmap file to the <tt>cell_misc</tt>
93 * directory.
94 *
95 * \param fd file descriptor
96 *
97 * \return void
98 */
99void Rast_close(int fd)
100{
101 struct fileinfo *fcb = &R__.fileinfo[fd];
102
103 if (fd < 0 || fd >= R__.fileinfo_count || fcb->open_mode <= 0)
104 G_fatal_error(_("Invalid descriptor: %d"), fd);
105
106 if (fcb->open_mode == OPEN_OLD)
107 close_old(fd);
108 else
109 close_new(fd, 1);
110}
111
112/*!
113 * \brief Unopen a raster map
114 *
115 * The raster map opened on file descriptor <i>fd</i> is
116 * closed. Memory allocated for raster processing is freed. If open
117 * for writing, the raster map is not created and the temporary file
118 * created when the raster map was opened is removed (see \ref
119 * Creating_and_Opening_New_Raster_Files). This routine is useful when
120 * errors are detected and it is desired to not create the new raster
121 * map. While it is true that the raster map will not be created if
122 * the module exits without closing the file, the temporary file will
123 * not be removed at module exit. GRASS database management will
124 * eventually remove the temporary file, but the file can be quite
125 * large and will take up disk space until GRASS does remove it. Use
126 * this routine as a courtesy to the user.
127 *
128 * \param fd file descriptor
129 *
130 * \return void
131 */
132void Rast_unopen(int fd)
133{
134 struct fileinfo *fcb = &R__.fileinfo[fd];
135
136 if (fd < 0 || fd >= R__.fileinfo_count || fcb->open_mode <= 0)
137 G_fatal_error(_("Invalid descriptor: %d"), fd);
138
139 if (fcb->open_mode == OPEN_OLD)
140 close_old(fd);
141 else
142 close_new(fd, 0);
143}
144
145/*!
146 * \brief Unopen all raster maps
147 *
148 * Unopen all raster maps opened for write. Memory allocated for
149 * raster processing is freed, and the temporary file created when the
150 * raster map was opened is removed (see \ref
151 * Creating_and_Opening_New_Raster_Files). This routine is useful when
152 * errors are detected and it is desired to remove temporary files.
153 *
154 * \return void
155 */
157{
158 int i;
159
160 for (i = 0; i < R__.fileinfo_count; i++) {
161 struct fileinfo *fcb = &R__.fileinfo[i];
162
163 if (fcb->open_mode == OPEN_NEW_COMPRESSED ||
164 fcb->open_mode == OPEN_NEW_UNCOMPRESSED)
165 close_new(i, 0);
166 }
167}
168
169static int close_old(int fd)
170{
171 struct fileinfo *fcb = &R__.fileinfo[fd];
172
173 /* if R__.auto_mask was only allocated for reading map rows to create
174 non-existent null rows, and not for actual mask, free R__.mask_row
175 if(R__.auto_mask <=0)
176 G_free (R__.mask_buf);
177 This is obsolete since now the mask_bus is always allocated
178 */
179
180 if (fcb->gdal)
182 if (fcb->vrt)
183 Rast_close_vrt(fcb->vrt);
184
185 if (fcb->null_bits)
186 G_free(fcb->null_bits);
187 if (fcb->null_row_ptr)
188 G_free(fcb->null_row_ptr);
189 if (fcb->null_fd >= 0)
190 close(fcb->null_fd);
191 fcb->null_fd = -1;
192
193 if (fcb->cellhd.compressed)
194 G_free(fcb->row_ptr);
195 G_free(fcb->col_map);
196 G_free(fcb->mapset);
197 G_free(fcb->data);
198 G_free(fcb->name);
199 if (fcb->reclass_flag)
200 Rast_free_reclass(&fcb->reclass);
201 fcb->open_mode = -1;
202
203 if (fcb->map_type != CELL_TYPE) {
204 Rast_quant_free(&fcb->quant);
205 }
206 if (fcb->data_fd >= 0)
207 close(fcb->data_fd);
208
209 return 1;
210}
211
212static void write_support_files(int fd)
213{
214 struct fileinfo *fcb = &R__.fileinfo[fd];
215 struct Categories cats;
216 struct History hist;
218 char path[GPATH_MAX];
219
220 /* remove color table */
222
223 /* create a history file */
224 Rast_short_history(fcb->name, "raster", &hist);
225 Rast_write_history(fcb->name, &hist);
226
227 /* write the range */
228 if (fcb->map_type == CELL_TYPE) {
229 Rast_write_range(fcb->name, &fcb->range);
231 }
232 /*NOTE: int range for floating point maps is not written out */
233 else { /* if(fcb->map_type != CELL_TYPE) */
234
235 Rast_write_fp_range(fcb->name, &fcb->fp_range);
237 /* this range will be used to add default rule to quant structure */
238 }
239
240 if (fcb->map_type != CELL_TYPE)
241 fcb->cellhd.format = -1;
242 else /* CELL map */
243 fcb->cellhd.format = fcb->nbytes - 1;
244
245 /* write header file */
246 Rast_put_cellhd(fcb->name, &fcb->cellhd);
247
248 /* if map is floating point write the quant rules, otherwise remove f_quant
249 */
250 if (fcb->map_type != CELL_TYPE) {
251 /* DEFAULT RANGE QUANT
252 Rast_get_fp_range_min_max(&fcb->fp_range, &dcell_min, &dcell_max);
253 if(!Rast_is_d_null_value(&dcell_min) &&
254 !Rast_is_d_null_value(&dcell_max))
255 {
256 Rast_get_range_min_max(&fcb->range, &cell_min, &cell_max);
257 Rast_quant_add_rule(&fcb->quant, dcell_min, dcell_max,
258 cell_min, cell_max);
259 }
260 */
261 Rast_quant_round(&fcb->quant);
262 Rast_write_quant(fcb->name, fcb->mapset, &fcb->quant);
263 }
264 else {
265 /* remove cell_misc/name/f_quant */
266 G_file_name_misc(path, "cell_misc", QUANT_FILE, fcb->name, fcb->mapset);
267 remove(path);
268 }
269
270 /* create empty cats file */
273 cell_max = 0;
274 Rast_init_cats((char *)NULL, &cats);
275 Rast_write_cats(fcb->name, &cats);
276 Rast_free_cats(&cats);
277
278 /* write the histogram */
279 /* only works for integer maps */
280 if ((fcb->map_type == CELL_TYPE) && (fcb->want_histogram)) {
282 Rast_free_cell_stats(&fcb->statf);
283 }
284 else {
286 }
287}
288
289static int close_new_gdal(int fd, int ok)
290{
291 struct fileinfo *fcb = &R__.fileinfo[fd];
292 char path[GPATH_MAX];
293 int stat = 1;
294
295 if (ok) {
296 int cell_fd;
297
298 G_debug(1, "close %s GDAL", fcb->name);
299
300 if (fcb->cur_row < fcb->cellhd.rows) {
301 int row;
302
303 Rast_zero_output_buf(fcb->data, fcb->map_type);
304 for (row = fcb->cur_row; row < fcb->cellhd.rows; row++)
305 Rast_put_row(fd, fcb->data, fcb->map_type);
306 G_free(fcb->data);
307 fcb->data = NULL;
308 }
309
310 /* create path : full null file name */
311 G__make_mapset_element_misc("cell_misc", fcb->name);
312 G_file_name_misc(path, "cell_misc", NULL_FILE, fcb->name, G_mapset());
313 remove(path);
314 G_file_name_misc(path, "cell_misc", NULLC_FILE, fcb->name, G_mapset());
315 remove(path);
316
317 /* write 0-length cell file */
319 G_file_name(path, "cell", fcb->name, fcb->mapset);
320 cell_fd = creat(path, 0666);
321 close(cell_fd);
322
323 if (fcb->map_type != CELL_TYPE) { /* floating point map */
324 write_fp_format(fd);
325
326 /* write 0-length fcell file */
328 G_file_name(path, "fcell", fcb->name, fcb->mapset);
329 cell_fd = creat(path, 0666);
330 close(cell_fd);
331 }
332 else {
333 /* remove fcell/name file */
334 G_file_name(path, "fcell", fcb->name, fcb->mapset);
335 remove(path);
336 /* remove cell_misc/name/f_format */
337 G_file_name_misc(path, "cell_misc", FORMAT_FILE, fcb->name,
338 fcb->mapset);
339 remove(path);
340 }
341
342 if (Rast_close_gdal_write_link(fcb->gdal) < 0)
343 stat = -1;
344 }
345 else {
346 remove(fcb->gdal->filename);
348 }
349
350 fcb->open_mode = -1;
351
352 if (fcb->data != NULL)
353 G_free(fcb->data);
354
355 if (ok)
356 write_support_files(fd);
357
358 G_free(fcb->name);
359 G_free(fcb->mapset);
360
361 if (fcb->map_type != CELL_TYPE)
362 Rast_quant_free(&fcb->quant);
363
364 return stat;
365}
366
367static int close_new(int fd, int ok)
368{
369 struct fileinfo *fcb = &R__.fileinfo[fd];
370 int stat;
371 char path[GPATH_MAX];
372 int row;
373 const char *CELL_DIR;
374
375 if (fcb->gdal)
376 return close_new_gdal(fd, ok);
377
378 if (ok) {
379 switch (fcb->open_mode) {
381 G_debug(1, "close %s compressed", fcb->name);
382 break;
384 G_debug(1, "close %s uncompressed", fcb->name);
385 break;
386 }
387
388 if (fcb->cur_row < fcb->cellhd.rows) {
389 Rast_zero_output_buf(fcb->data, fcb->map_type);
390 for (row = fcb->cur_row; row < fcb->cellhd.rows; row++)
391 Rast_put_row(fd, fcb->data, fcb->map_type);
392 G_free(fcb->data);
393 fcb->data = NULL;
394 }
395
396 if (fcb->null_row_ptr) { /* compressed nulls */
397 fcb->null_row_ptr[fcb->cellhd.rows] =
398 lseek(fcb->null_fd, 0L, SEEK_CUR);
399 if (fcb->null_row_ptr[fcb->cellhd.rows] == -1) {
400 int err = errno;
401 G_fatal_error(_("File read/write operation failed: %s (%d)"),
402 strerror(err), err);
403 }
404 Rast__write_null_row_ptrs(fd, fcb->null_fd);
405 }
406
407 if (fcb->null_fd >= 0) {
408 sync_and_close(fcb->null_fd,
409 (fcb->null_row_ptr ? NULLC_FILE : NULL_FILE),
410 fcb->name);
411 }
412 fcb->null_fd = -1;
413
414 /* create path : full null file name */
415 G__make_mapset_element_misc("cell_misc", fcb->name);
416 G_file_name_misc(path, "cell_misc", NULL_FILE, fcb->name, G_mapset());
417 remove(path);
418 G_file_name_misc(path, "cell_misc", NULLC_FILE, fcb->name, G_mapset());
419 remove(path);
420
421 G_file_name_misc(path, "cell_misc",
422 fcb->null_row_ptr ? NULLC_FILE : NULL_FILE, fcb->name,
423 G_mapset());
424
425 if (fcb->null_cur_row > 0) {
426 /* if temporary NULL file exists, write it into cell_misc/name/null
427 */
428 if (rename(fcb->null_temp_name, path)) {
429 G_warning(_("Unable to rename null file '%s' to '%s': %s"),
430 fcb->null_temp_name, path, strerror(errno));
431 stat = -1;
432 }
433 /* if rename() was successful what is left to remove() ? */
434 else {
435 remove(fcb->null_temp_name);
436 }
437 }
438 else {
439 remove(fcb->null_temp_name);
440 remove(path); /* again ? */
441 } /* null_cur_row > 0 */
442
443 if (fcb->open_mode == OPEN_NEW_COMPRESSED) { /* auto compression */
444 fcb->row_ptr[fcb->cellhd.rows] = lseek(fcb->data_fd, 0L, SEEK_CUR);
445 if (fcb->row_ptr[fcb->cellhd.rows] == -1) {
446 int err = errno;
447 G_fatal_error(_("File read/write operation failed: %s (%d)"),
448 strerror(err), err);
449 }
451 }
452
453 if (fcb->map_type != CELL_TYPE) { /* floating point map */
454 int cell_fd;
455
456 write_fp_format(fd);
457
458 /* now write 0-length cell file */
460 cell_fd =
461 creat(G_file_name(path, "cell", fcb->name, fcb->mapset), 0666);
462 close(cell_fd);
463 CELL_DIR = "fcell";
464 }
465 else {
466 /* remove fcell/name file */
467 G_file_name(path, "fcell", fcb->name, fcb->mapset);
468 remove(path);
469 /* remove cell_misc/name/f_format */
470 G_file_name_misc(path, "cell_misc", FORMAT_FILE, fcb->name,
471 fcb->mapset);
472 remove(path);
473 CELL_DIR = "cell";
474 }
475 } /* ok */
476 /* NOW CLOSE THE FILE DESCRIPTOR */
477
478 sync_and_close(fcb->data_fd,
479 (fcb->map_type == CELL_TYPE ? "cell" : "fcell"), fcb->name);
480 fcb->open_mode = -1;
481
482 if (fcb->null_fd >= 0) {
483 sync_and_close(fcb->null_fd,
484 (fcb->null_row_ptr ? NULLC_FILE : NULL_FILE), fcb->name);
485 }
486 fcb->null_fd = -1;
487
488 if (fcb->data != NULL)
489 G_free(fcb->data);
490
491 if (fcb->null_temp_name != NULL) {
492 G_free(fcb->null_temp_name);
493 fcb->null_temp_name = NULL;
494 }
495
496 /* if the cell file was written to a temporary file
497 * move this temporary file into the cell file
498 * if the move fails, tell the user, but go ahead and create
499 * the support files
500 */
501 stat = 1;
502 if (ok && (fcb->temp_name != NULL)) {
503 G_file_name(path, CELL_DIR, fcb->name, fcb->mapset);
504 remove(path);
505 if (rename(fcb->temp_name, path)) {
506 G_warning(_("Unable to rename cell file '%s' to '%s': %s"),
507 fcb->temp_name, path, strerror(errno));
508 stat = -1;
509 }
510 /* if rename() was successful what is left to remove() ? */
511 else {
512 remove(fcb->temp_name);
513 }
514 }
515
516 if (fcb->temp_name != NULL) {
517 G_free(fcb->temp_name);
518 }
519
520 if (ok)
521 write_support_files(fd);
522
523 G_free(fcb->name);
524 G_free(fcb->mapset);
525
526 G_free(fcb->null_bits);
527
528 if (fcb->null_row_ptr)
529 G_free(fcb->null_row_ptr);
530
531 if (fcb->map_type != CELL_TYPE)
532 Rast_quant_free(&fcb->quant);
533
534 return stat;
535}
536
538{
539 struct fileinfo *fcb = &R__.fileinfo[fd];
540 char path[GPATH_MAX];
541
542 if (fcb->null_row_ptr) { /* compressed nulls */
543 fcb->null_row_ptr[fcb->cellhd.rows] = lseek(fcb->null_fd, 0L, SEEK_CUR);
544 if (fcb->null_row_ptr[fcb->cellhd.rows] == -1) {
545 int err = errno;
546 G_fatal_error(_("File read/write operation failed: %s (%d)"),
547 strerror(err), err);
548 }
549 Rast__write_null_row_ptrs(fd, fcb->null_fd);
550 G_free(fcb->null_row_ptr);
551 }
552
553 if (fcb->null_fd >= 0)
554 close(fcb->null_fd);
555 fcb->null_fd = -1;
556
557 /* create path : full null file name */
558 G__make_mapset_element_misc("cell_misc", fcb->name);
559 G_file_name_misc(path, "cell_misc", NULL_FILE, fcb->name, G_mapset());
560 remove(path);
561 G_file_name_misc(path, "cell_misc", NULLC_FILE, fcb->name, G_mapset());
562 remove(path);
563
564 G_file_name_misc(path, "cell_misc",
565 fcb->null_row_ptr ? NULLC_FILE : NULL_FILE, fcb->name,
566 G_mapset());
567
568 if (rename(fcb->null_temp_name, path))
569 G_warning(_("Unable to rename null file '%s' to '%s': %s"),
570 fcb->null_temp_name, path, strerror(errno));
571 remove(fcb->null_temp_name);
572
573 G_free(fcb->null_temp_name);
574
575 G_free(fcb->name);
576 G_free(fcb->mapset);
577
578 G_free(fcb->null_bits);
579
580 fcb->open_mode = -1;
581}
582
583/* returns 0 on success, 1 on failure */
584static void write_fp_format(int fd)
585{
586 struct fileinfo *fcb = &R__.fileinfo[fd];
587 struct Key_Value *format_kv;
588 char path[GPATH_MAX];
589
590 if (fcb->map_type == CELL_TYPE) {
591 G_warning(_("unable to write f_format file for CELL maps"));
592 return;
593 }
595 if (fcb->map_type == FCELL_TYPE)
596 G_set_key_value("type", "float", format_kv);
597 else
598 G_set_key_value("type", "double", format_kv);
599
600 G_set_key_value("byte_order", "xdr", format_kv);
601
602 if (fcb->open_mode == OPEN_NEW_COMPRESSED)
603 G_set_key_value("lzw_compression_bits", "-1", format_kv);
604
605 G__make_mapset_element_misc("cell_misc", fcb->name);
606 G_file_name_misc(path, "cell_misc", FORMAT_FILE, fcb->name, fcb->mapset);
608
610}
#define OPEN_NEW_COMPRESSED
Definition R.h:102
#define OPEN_NEW_UNCOMPRESSED
Definition R.h:103
#define OPEN_OLD
Definition R.h:101
#define NULL
Definition ccmath.h:32
AMI_err name(char **stream_name)
Definition ami_stream.h:426
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
int G__make_mapset_element_misc(const char *, const char *)
Create misc element in the current mapset.
Definition mapset_msc.c:261
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
char * G_file_name_misc(char *, const char *, const char *, const char *, const char *)
Builds full path names to GIS misc data files.
Definition file_name.c:101
int G_make_mapset_object_group(const char *)
Create directory for group of elements of a given type.
Definition mapset_msc.c:75
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition file_name.c:61
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
Definition key_value1.c:104
void G_set_key_value(const char *, const char *, struct Key_Value *)
Set value for given key.
Definition key_value1.c:39
struct Key_Value * G_create_key_value(void)
Allocate and initialize Key_Value structure.
Definition key_value1.c:23
void G_write_key_value_file(const char *, const struct Key_Value *)
Write key/value pairs to file.
Definition key_value3.c:28
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:33
void Rast_put_cellhd(const char *, struct Cell_head *)
Writes the raster file header.
Definition put_cellhd.c:28
void Rast_free_cats(struct Categories *)
Free category structure memory.
void Rast_construct_default_range(struct Range *)
Construct default range.
void Rast_write_histogram_cs(const char *, struct Cell_stats *)
Writes the histogram based on cell statistics to file.
Definition histogram.c:108
void Rast_quant_round(struct Quant *)
Sets the quant rules to perform simple rounding on floats.
Definition quant.c:230
void Rast_close_gdal_link(struct GDAL_link *)
Close existing GDAL link.
Definition gdal.c:380
void Rast_quant_free(struct Quant *)
Resets and frees allocated memory.
Definition quant.c:55
void Rast_write_cats(const char *, struct Categories *)
Write raster category file.
void Rast_free_reclass(struct Reclass *)
Free Reclass structure.
Definition reclass.c:199
void Rast_free_cell_stats(struct Cell_stats *)
Free cell stats structure.
Definition cell_stats.c:382
int Rast__write_row_ptrs(int)
void Rast_remove_histogram(const char *)
Removes the histogram.
Definition histogram.c:329
void Rast_write_history(const char *, struct History *)
Write raster history file.
void Rast_init_cats(const char *, struct Categories *)
Initialize category structure.
int Rast_close_gdal_write_link(struct GDAL_link *)
Close existing GDAL link and write out data.
Definition gdal.c:395
int Rast__write_null_row_ptrs(int, int)
void Rast_write_range(const char *, const struct Range *)
Write raster range file.
void Rast__remove_fp_range(const char *)
Remove floating-point range.
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
void Rast_close_vrt(struct R_vrt *)
Definition vrt.c:150
void Rast_put_row(int, const void *, RASTER_MAP_TYPE)
Writes the next row for cell/fcell/dcell file.
void Rast_short_history(const char *, const char *, struct History *)
Initialize history structure.
#define Rast_is_c_null_value(cellVal)
int Rast_remove_colors(const char *, const char *)
Remove color table of raster map.
void Rast_write_quant(const char *, const char *, const struct Quant *)
Writes the quant rule table for the raster map.
Definition quant_rw.c:150
void Rast_zero_output_buf(void *, RASTER_MAP_TYPE)
Definition zero_cell.c:38
void Rast_write_fp_range(const char *, const struct FPRange *)
Write raster range file (floating-point)
Header file for msvc/fcntl.c.
#define creat
Definition fcntl.h:34
#define GPATH_MAX
Definition gis.h:199
int CELL
Definition gis.h:634
#define _(str)
Definition glocale.h:10
const char * name
Definition named_colr.c:6
#define NULL_FILE
void Rast__close_null(int fd)
void Rast_close(int fd)
Close a raster map.
void Rast__unopen_all(void)
Unopen all raster maps.
#define NULLC_FILE
void Rast_unopen(int fd)
Unopen a raster map.
#define QUANT_FILE
#define FORMAT_FILE
#define FCELL_TYPE
Definition raster.h:12
#define CELL_TYPE
Definition raster.h:11
Raster history info (metadata)
Definition raster.h:172
Definition R.h:82
struct fileinfo * fileinfo
Definition R.h:96
int fileinfo_count
Definition R.h:95
Definition R.h:48
Definition path.h:15
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
#define close
Definition unistd.h:8