NetCDF  4.6.3
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
dfile.c
Go to the documentation of this file.
1 
13 #include "config.h"
14 #include <stdlib.h>
15 #ifdef HAVE_STRING_H
16 #include <string.h>
17 #endif
18 #ifdef HAVE_SYS_RESOURCE_H
19 #include <sys/resource.h>
20 #endif
21 #ifdef HAVE_SYS_TYPES_H
22 #include <sys/types.h>
23 #endif
24 #ifdef HAVE_SYS_STAT_H
25 #include <sys/stat.h>
26 #endif
27 
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h> /* lseek() */
30 #endif
31 
32 #ifdef HAVE_STDIO_H
33 #include <stdio.h>
34 #endif
35 extern int fileno(FILE*);
36 
37 #include "ncdispatch.h"
38 #include "netcdf_mem.h"
39 #include "ncwinpath.h"
40 #include "fbits.h"
41 
42 /* If Defined, then use only stdio for all magic number io;
43  otherwise use stdio or mpio as required.
44  */
45 #undef DEBUG
46 
51 struct MagicFile {
52  const char* path;
53  long long filelen;
54  int use_parallel;
55  int inmemory;
56  int diskless;
57  void* parameters; /* !NULL if inmemory && !diskless */
58  FILE* fp;
59 #ifdef USE_PARALLEL
60  MPI_File fh;
61 #endif
62 };
63 
64 static int openmagic(struct MagicFile* file);
65 static int readmagic(struct MagicFile* file, long pos, char* magic);
66 static int closemagic(struct MagicFile* file);
67 #ifdef DEBUG
68 static void printmagic(const char* tag, char* magic,struct MagicFile*);
69 #endif
70 
71 extern int NC_initialized;
75 static char HDF5_SIGNATURE[MAGIC_NUMBER_LEN] = "\211HDF\r\n\032\n";
76 
77 #ifdef USE_NETCDF4
78 /* User-defined formats. */
79 NC_Dispatch *UDF0_dispatch_table = NULL;
80 char UDF0_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
81 NC_Dispatch *UDF1_dispatch_table = NULL;
82 char UDF1_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
83 #endif /* USE_NETCDF4 */
84 
121 #ifdef USE_NETCDF4
122 
135 int
136 nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
137 {
138  /* Check inputs. */
139  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
140  return NC_EINVAL;
141  if (!dispatch_table)
142  return NC_EINVAL;
143  if (magic_number && strlen(magic_number) > NC_MAX_MAGIC_NUMBER_LEN)
144  return NC_EINVAL;
145 
146  /* Retain a pointer to the dispatch_table and a copy of the magic
147  * number, if one was provided. */
148  switch(mode_flag)
149  {
150  case NC_UDF0:
151  UDF0_dispatch_table = dispatch_table;
152  if (magic_number)
153  strncpy(UDF0_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
154  break;
155  case NC_UDF1:
156  UDF1_dispatch_table = dispatch_table;
157  if (magic_number)
158  strncpy(UDF1_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
159  break;
160  }
161 
162  return NC_NOERR;
163 }
164 
181 int
182 nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
183 {
184  /* Check inputs. */
185  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
186  return NC_EINVAL;
187 
188  switch(mode_flag)
189  {
190  case NC_UDF0:
191  if (dispatch_table)
192  *dispatch_table = UDF0_dispatch_table;
193  if (magic_number)
194  strncpy(magic_number, UDF0_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
195  break;
196  case NC_UDF1:
197  if (dispatch_table)
198  *dispatch_table = UDF1_dispatch_table;
199  if (magic_number)
200  strncpy(magic_number, UDF1_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
201  break;
202  }
203 
204  return NC_NOERR;
205 }
206 #endif /* USE_NETCDF4 */
207 
222 static int
223 NC_interpret_magic_number(char* magic, int* model, int* version)
224 {
225  int status = NC_NOERR;
226  /* Look at the magic number */
227  *model = 0;
228  *version = 0;
229 #ifdef USE_NETCDF4
230  if (strlen(UDF0_magic_number) && !strncmp(UDF0_magic_number, magic,
231  strlen(UDF0_magic_number)))
232  {
233  *model = NC_FORMATX_UDF0;
234  *version = 6; /* redundant */
235  goto done;
236  }
237  if (strlen(UDF1_magic_number) && !strncmp(UDF1_magic_number, magic,
238  strlen(UDF1_magic_number)))
239  {
240  *model = NC_FORMATX_UDF1;
241  *version = 7; /* redundant */
242  goto done;
243  }
244 #endif /* USE_NETCDF4 */
245 
246  /* Use the complete magic number string for HDF5 */
247  if(memcmp(magic,HDF5_SIGNATURE,sizeof(HDF5_SIGNATURE))==0) {
248  *model = NC_FORMATX_NC4;
249  *version = 5; /* redundant */
250  goto done;
251  }
252  if(magic[0] == '\016' && magic[1] == '\003'
253  && magic[2] == '\023' && magic[3] == '\001') {
254  *model = NC_FORMATX_NC_HDF4;
255  *version = 4; /* redundant */
256  goto done;
257  }
258  if(magic[0] == 'C' && magic[1] == 'D' && magic[2] == 'F') {
259  if(magic[3] == '\001') {
260  *version = 1; /* netcdf classic version 1 */
261  *model = NC_FORMATX_NC3;
262  goto done;
263  }
264  if(magic[3] == '\002') {
265  *version = 2; /* netcdf classic version 2 */
266  *model = NC_FORMATX_NC3;
267  goto done;
268  }
269  if(magic[3] == '\005') {
270  *version = 5; /* cdf5 file */
271  *model = NC_FORMATX_NC3;
272  goto done;
273  }
274  }
275  /* No match */
276  status = NC_ENOTNC;
277  goto done;
278 
279 done:
280  return status;
281 }
282 
298 static int
299 NC_check_file_type(const char *path, int flags, int use_parallel,
300  void *parameters, int* model, int* version)
301 {
302  char magic[MAGIC_NUMBER_LEN];
303  int status = NC_NOERR;
304  int diskless = ((flags & NC_DISKLESS) == NC_DISKLESS);
305  int inmemory = ((flags & NC_INMEMORY) == NC_INMEMORY);
306  int mmap = ((flags & NC_MMAP) == NC_MMAP);
307 
308  struct MagicFile file;
309 
310  *model = 0;
311  *version = 0;
312 
313  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
314  if(diskless && inmemory) {status = NC_EDISKLESS; goto done;}
315  if(diskless && mmap) {status = NC_EDISKLESS; goto done;}
316  if(inmemory && mmap) {status = NC_EINMEMORY; goto done;}
317 
318  /* mmap is not allowed for netcdf-4 */
319  if(mmap && (flags & NC_NETCDF4)) {status = NC_EINVAL; goto done;}
320 
321  memset((void*)&file,0,sizeof(file));
322  file.path = path; /* do not free */
323  file.parameters = parameters;
324  file.inmemory = inmemory;
325  file.diskless = diskless;
326  file.use_parallel = use_parallel;
327 
328  status = openmagic(&file);
329  if(status != NC_NOERR) {goto done;}
330  /* Verify we have a large enough file */
331  if(file.filelen < MAGIC_NUMBER_LEN)
332  {status = NC_ENOTNC; goto done;}
333  if((status = readmagic(&file,0L,magic)) != NC_NOERR) {
334  status = NC_ENOTNC;
335  *model = 0;
336  *version = 0;
337  goto done;
338  }
339  /* Look at the magic number */
340  if(NC_interpret_magic_number(magic,model,version) == NC_NOERR
341  && *model != 0) {
342  if (*model == NC_FORMATX_NC3 && use_parallel)
343  /* this is called from nc_open_par() and file is classic */
344  *model = NC_FORMATX_PNETCDF;
345  goto done; /* found something */
346  }
347 
348  /* Remaining case is to search forward at starting at 512
349  and doubling to see if we have HDF5 magic number */
350  {
351  long pos = 512L;
352  for(;;) {
353  if((pos+MAGIC_NUMBER_LEN) > file.filelen)
354  {status = NC_ENOTNC; goto done;}
355  if((status = readmagic(&file,pos,magic)) != NC_NOERR)
356  {status = NC_ENOTNC; goto done; }
357  NC_interpret_magic_number(magic,model,version);
358  if(*model == NC_FORMATX_NC4) break;
359  /* double and try again */
360  pos = 2*pos;
361  }
362  }
363 done:
364  closemagic(&file);
365  return status;
366 }
367 
561 int
562 nc_create(const char *path, int cmode, int *ncidp)
563 {
564  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
565 }
566 
633 int
634 nc__create(const char *path, int cmode, size_t initialsz,
635  size_t *chunksizehintp, int *ncidp)
636 {
637  return NC_create(path, cmode, initialsz, 0,
638  chunksizehintp, 0, NULL, ncidp);
639 }
640 
679 int
680 nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
681 {
682  if(mode & NC_MMAP) return NC_EINVAL;
683  mode |= NC_INMEMORY; /* Specifically, do not set NC_DISKLESS */
684  return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
685 }
686 
706 int
707 nc__create_mp(const char *path, int cmode, size_t initialsz,
708  int basepe, size_t *chunksizehintp, int *ncidp)
709 {
710  return NC_create(path, cmode, initialsz, basepe,
711  chunksizehintp, 0, NULL, ncidp);
712 }
713 
827 int
828 nc_open(const char *path, int omode, int *ncidp)
829 {
830  return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
831 }
832 
884 int
885 nc__open(const char *path, int omode,
886  size_t *chunksizehintp, int *ncidp)
887 {
888  /* this API is for non-parallel access.
889  * Note nc_open_par() also calls NC_open().
890  */
891  return NC_open(path, omode, 0, chunksizehintp, 0, NULL, ncidp);
892 }
893 
939 int
940 nc_open_mem(const char* path, int omode, size_t size, void* memory, int* ncidp)
941 {
942  NC_memio meminfo;
943 
944  /* Sanity checks */
945  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
946  return NC_EINVAL;
947  if(omode & (NC_WRITE|NC_MMAP))
948  return NC_EINVAL;
949  omode |= (NC_INMEMORY); /* Note: NC_INMEMORY and NC_DISKLESS are mutually exclusive*/
950  meminfo.size = size;
951  meminfo.memory = memory;
952  meminfo.flags = NC_MEMIO_LOCKED;
953  return NC_open(path, omode, 0, NULL, 0, &meminfo, ncidp);
954 }
955 
1004 int
1005 nc_open_memio(const char* path, int omode, NC_memio* params, int* ncidp)
1006 {
1007  /* Sanity checks */
1008  if(path == NULL || params == NULL)
1009  return NC_EINVAL;
1010  if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
1011  return NC_EINVAL;
1012 
1013  if(omode & NC_MMAP)
1014  return NC_EINVAL;
1015  omode |= (NC_INMEMORY);
1016  return NC_open(path, omode, 0, NULL, 0, params, ncidp);
1017 }
1018 
1037 int
1038 nc__open_mp(const char *path, int omode, int basepe,
1039  size_t *chunksizehintp, int *ncidp)
1040 {
1041  return NC_open(path, omode, basepe, chunksizehintp, 0, NULL, ncidp);
1042 }
1043 
1061 int
1062 nc_inq_path(int ncid, size_t *pathlen, char *path)
1063 {
1064  NC* ncp;
1065  int stat = NC_NOERR;
1066  if ((stat = NC_check_id(ncid, &ncp)))
1067  return stat;
1068  if(ncp->path == NULL) {
1069  if(pathlen) *pathlen = 0;
1070  if(path) path[0] = '\0';
1071  } else {
1072  if (pathlen) *pathlen = strlen(ncp->path);
1073  if (path) strcpy(path, ncp->path);
1074  }
1075  return stat;
1076 }
1077 
1126 int
1127 nc_redef(int ncid)
1128 {
1129  NC* ncp;
1130  int stat = NC_check_id(ncid, &ncp);
1131  if(stat != NC_NOERR) return stat;
1132  return ncp->dispatch->redef(ncid);
1133 }
1134 
1190 int
1191 nc_enddef(int ncid)
1192 {
1193  int status = NC_NOERR;
1194  NC *ncp;
1195  status = NC_check_id(ncid, &ncp);
1196  if(status != NC_NOERR) return status;
1197  return ncp->dispatch->_enddef(ncid,0,1,0,1);
1198 }
1199 
1281 int
1282 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1283  size_t r_align)
1284 {
1285  NC* ncp;
1286  int stat = NC_check_id(ncid, &ncp);
1287  if(stat != NC_NOERR) return stat;
1288  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1289 }
1290 
1358 int
1359 nc_sync(int ncid)
1360 {
1361  NC* ncp;
1362  int stat = NC_check_id(ncid, &ncp);
1363  if(stat != NC_NOERR) return stat;
1364  return ncp->dispatch->sync(ncid);
1365 }
1366 
1410 int
1411 nc_abort(int ncid)
1412 {
1413  NC* ncp;
1414  int stat = NC_check_id(ncid, &ncp);
1415  if(stat != NC_NOERR) return stat;
1416 
1417 #ifdef USE_REFCOUNT
1418  /* What to do if refcount > 0? */
1419  /* currently, forcibly abort */
1420  ncp->refcount = 0;
1421 #endif
1422 
1423  stat = ncp->dispatch->abort(ncid);
1424  del_from_NCList(ncp);
1425  free_NC(ncp);
1426  return stat;
1427 }
1428 
1469 int
1470 nc_close(int ncid)
1471 {
1472  NC* ncp;
1473  int stat = NC_check_id(ncid, &ncp);
1474  if(stat != NC_NOERR) return stat;
1475 
1476 #ifdef USE_REFCOUNT
1477  ncp->refcount--;
1478  if(ncp->refcount <= 0)
1479 #endif
1480  {
1481  stat = ncp->dispatch->close(ncid,NULL);
1482  /* Remove from the nc list */
1483  if (!stat)
1484  {
1485  del_from_NCList(ncp);
1486  free_NC(ncp);
1487  }
1488  }
1489  return stat;
1490 }
1491 
1534 int
1535 nc_close_memio(int ncid, NC_memio* memio)
1536 {
1537  NC* ncp;
1538  int stat = NC_check_id(ncid, &ncp);
1539  if(stat != NC_NOERR) return stat;
1540 
1541 #ifdef USE_REFCOUNT
1542  ncp->refcount--;
1543  if(ncp->refcount <= 0)
1544 #endif
1545  {
1546  stat = ncp->dispatch->close(ncid,memio);
1547  /* Remove from the nc list */
1548  if (!stat)
1549  {
1550  del_from_NCList(ncp);
1551  free_NC(ncp);
1552  }
1553  }
1554  return stat;
1555 }
1556 
1655 int
1656 nc_set_fill(int ncid, int fillmode, int *old_modep)
1657 {
1658  NC* ncp;
1659  int stat = NC_check_id(ncid, &ncp);
1660  if(stat != NC_NOERR) return stat;
1661  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1662 }
1663 
1678 int
1679 nc_inq_base_pe(int ncid, int *pe)
1680 {
1681  NC* ncp;
1682  int stat = NC_check_id(ncid, &ncp);
1683  if(stat != NC_NOERR) return stat;
1684  return ncp->dispatch->inq_base_pe(ncid,pe);
1685 }
1686 
1701 int
1702 nc_set_base_pe(int ncid, int pe)
1703 {
1704  NC* ncp;
1705  int stat = NC_check_id(ncid, &ncp);
1706  if(stat != NC_NOERR) return stat;
1707  return ncp->dispatch->set_base_pe(ncid,pe);
1708 }
1709 
1728 int
1729 nc_inq_format(int ncid, int *formatp)
1730 {
1731  NC* ncp;
1732  int stat = NC_check_id(ncid, &ncp);
1733  if(stat != NC_NOERR) return stat;
1734  return ncp->dispatch->inq_format(ncid,formatp);
1735 }
1736 
1763 int
1764 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1765 {
1766  NC* ncp;
1767  int stat = NC_check_id(ncid, &ncp);
1768  if(stat != NC_NOERR) return stat;
1769  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1770 }
1771 
1816 int
1817 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1818 {
1819  NC* ncp;
1820  int stat = NC_check_id(ncid, &ncp);
1821  if(stat != NC_NOERR) return stat;
1822  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1823 }
1824 
1835 int
1836 nc_inq_nvars(int ncid, int *nvarsp)
1837 {
1838  NC* ncp;
1839  int stat = NC_check_id(ncid, &ncp);
1840  if(stat != NC_NOERR) return stat;
1841  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1842 }
1843 
1909 int
1910 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1911 {
1912  NC* ncp;
1913  int stat;
1914 
1915  /* Do a quick triage on xtype */
1916  if(xtype <= NC_NAT) return NC_EBADTYPE;
1917  /* For compatibility, we need to allow inq about
1918  atomic types, even if ncid is ill-defined */
1919  if(xtype <= ATOMICTYPEMAX4) {
1920  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1921  if(size) *size = NC_atomictypelen(xtype);
1922  return NC_NOERR;
1923  }
1924  /* Apparently asking about a user defined type, so we need
1925  a valid ncid */
1926  stat = NC_check_id(ncid, &ncp);
1927  if(stat != NC_NOERR) /* bad ncid */
1928  return NC_EBADTYPE;
1929  /* have good ncid */
1930  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1931 }
1932 
1949 static int
1951 {
1952  int mode_format;
1953  int mmap = 0;
1954  int inmemory = 0;
1955  int diskless = 0;
1956 
1957  /* This is a clever check to see if more than one format bit is
1958  * set. */
1959  mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
1960  (mode & NC_CDF5);
1961  if (mode_format && (mode_format & (mode_format - 1)))
1962  return NC_EINVAL;
1963 
1964  mmap = ((mode & NC_MMAP) == NC_MMAP);
1965  inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
1966  diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
1967 
1968  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1969  if(diskless && inmemory) return NC_EDISKLESS;
1970  if(diskless && mmap) return NC_EDISKLESS;
1971  if(inmemory && mmap) return NC_EINMEMORY;
1972 
1973  /* mmap is not allowed for netcdf-4 */
1974  if(mmap && (mode & NC_NETCDF4)) return NC_EINVAL;
1975 
1976  /* Can't use both parallel and diskless|inmemory|mmap. */
1977  if (mode & NC_MPIIO && mode & (NC_DISKLESS|NC_INMEMORY|NC_MMAP))
1978  return NC_EINVAL;
1979 
1980 #ifndef USE_NETCDF4
1981  /* If the user asks for a netCDF-4 file, and the library was built
1982  * without netCDF-4, then return an error.*/
1983  if (mode & NC_NETCDF4)
1984  return NC_ENOTBUILT;
1985 #endif /* USE_NETCDF4 undefined */
1986 
1987  /* Well I guess there is some sanity in the world after all. */
1988  return NC_NOERR;
1989 }
1990 
2018 int
2019 NC_create(const char *path0, int cmode, size_t initialsz,
2020  int basepe, size_t *chunksizehintp, int useparallel,
2021  void* parameters, int *ncidp)
2022 {
2023  int stat = NC_NOERR;
2024  NC* ncp = NULL;
2025  NC_Dispatch* dispatcher = NULL;
2026  /* Need three pieces of information for now */
2027  int model = NC_FORMATX_UNDEFINED; /* one of the NC_FORMATX values */
2028  int isurl = 0; /* dap or cdmremote or neither */
2029  char* path = NULL;
2030 
2031  TRACE(nc_create);
2032  if(path0 == NULL)
2033  return NC_EINVAL;
2034 
2035  /* Check mode flag for sanity. */
2036  if ((stat = check_create_mode(cmode)))
2037  return stat;
2038 
2039  /* Initialize the library. The available dispatch tables
2040  * will depend on how netCDF was built
2041  * (with/without netCDF-4, DAP, CDMREMOTE). */
2042  if(!NC_initialized)
2043  {
2044  if ((stat = nc_initialize()))
2045  return stat;
2046  }
2047 
2048 #ifdef WINPATH
2049  /* Need to do path conversion */
2050  path = NCpathcvt(path0);
2051 #else
2052  path = nulldup(path0);
2053 #endif
2054 
2055 #ifdef USE_REFCOUNT
2056  /* If this path is already open, then fail */
2057  ncp = find_in_NCList_by_name(path);
2058  if(ncp != NULL) {
2059  nullfree(path);
2060  return NC_ENFILE;
2061  }
2062 #endif
2063 
2064  {
2065  char* newpath = NULL;
2066  model = NC_urlmodel(path,cmode,&newpath);
2067  isurl = (model != 0);
2068  if(isurl) {
2069  nullfree(path);
2070  path = newpath;
2071  }
2072  }
2073 
2074  /* determine the model */
2075 #ifdef USE_NETCDF4
2076  if (model == NC_FORMATX_UNDEFINED && (cmode & NC_NETCDF4))
2077  model = NC_FORMATX_NC4;
2078 #else
2079  if (model == NC_FORMATX_UNDEFINED && (cmode & NC_NETCDF4))
2080  return NC_ENOTBUILT;
2081 #endif
2082 #ifdef USE_PNETCDF
2083  if (model == NC_FORMATX_UNDEFINED && useparallel)
2084  /* PnetCDF is used for parallel io on CDF-1, CDF-2, and CDF-5 */
2085  model = NC_FORMATX_PNETCDF;
2086 #else
2087  if (model == NC_FORMATX_UNDEFINED && useparallel)
2088  return NC_ENOTBUILT;
2089 #endif
2090 
2091  /* Check default format (not formatx) */
2092  if (!fIsSet(cmode, NC_64BIT_OFFSET) && !fIsSet(cmode, NC_64BIT_DATA) &&
2093  !fIsSet(cmode, NC_CLASSIC_MODEL) && !fIsSet(cmode, NC_NETCDF4)) {
2094  /* if no file format flag is set in cmode, use default */
2095  int format = nc_get_default_format();
2096  switch (format) {
2097 #ifdef USE_NETCDF4
2098  case NC_FORMAT_NETCDF4:
2099  cmode |= NC_NETCDF4;
2100  if (model == NC_FORMATX_UNDEFINED) model = NC_FORMATX_NC4;
2101  break;
2103  cmode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
2104  if (model == NC_FORMATX_UNDEFINED) model = NC_FORMATX_NC4;
2105  break;
2106 #endif
2107  case NC_FORMAT_CDF5:
2108  cmode |= NC_64BIT_DATA;
2109  break;
2111  cmode |= NC_64BIT_OFFSET;
2112  break;
2113  case NC_FORMAT_CLASSIC: break;
2114  default: break;
2115  }
2116  }
2117 
2118  /* default model */
2119  if (model == NC_FORMATX_UNDEFINED) {
2120  if (useparallel)
2121  model = NC_FORMATX_PNETCDF;
2122  else
2123  model = NC_FORMATX_NC3;
2124  }
2125 
2126 #ifndef ENABLE_CDF5
2127  if (model == NC_FORMATX_NC3 && (cmode & NC_64BIT_DATA))
2128  return NC_ENOTBUILT;
2129 #endif
2130 
2131  /* Figure out what dispatcher to use */
2132  if (model == NC_FORMATX_NC4)
2133 #ifdef USE_HDF5
2134  dispatcher = HDF5_dispatch_table;
2135 #else
2136  return NC_ENOTBUILT;
2137 #endif
2138  else if (model == NC_FORMATX_PNETCDF)
2139 #ifdef USE_PNETCDF
2140  dispatcher = NCP_dispatch_table;
2141 #else
2142  return NC_ENOTBUILT;
2143 #endif
2144  else if (model == NC_FORMATX_NC3)
2145  dispatcher = NC3_dispatch_table;
2146  else {
2147  nullfree(path);
2148  return NC_ENOTNC;
2149  }
2150 
2151  /* Create the NC* instance and insert its dispatcher */
2152  stat = new_NC(dispatcher,path,cmode,model,&ncp);
2153  nullfree(path); path = NULL; /* no longer needed */
2154 
2155  if(stat) return stat;
2156 
2157  /* Add to list of known open files and define ext_ncid */
2158  add_to_NCList(ncp);
2159 
2160 #ifdef USE_REFCOUNT
2161  /* bump the refcount */
2162  ncp->refcount++;
2163 #endif
2164 
2165  /* Assume create will fill in remaining ncp fields */
2166  if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp,
2167  parameters, dispatcher, ncp))) {
2168  del_from_NCList(ncp); /* oh well */
2169  free_NC(ncp);
2170  } else {
2171  if(ncidp)*ncidp = ncp->ext_ncid;
2172  }
2173  return stat;
2174 }
2175 
2199 int
2200 NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
2201  int useparallel, void* parameters, int *ncidp)
2202 {
2203  int stat = NC_NOERR;
2204  NC* ncp = NULL;
2205  NC_Dispatch* dispatcher = NULL;
2206  int inmemory = 0;
2207  int diskless = 0;
2208  int mmap = 0;
2209  /* Need pieces of information for now to decide model*/
2210  int model = 0;
2211  int isurl = 0;
2212  int version = 0;
2213  char* path = NULL;
2214 
2215  TRACE(nc_open);
2216  if(!NC_initialized) {
2217  stat = nc_initialize();
2218  if(stat) return stat;
2219  }
2220 
2221  /* Fix the inmemory related flags */
2222  mmap = ((omode & NC_MMAP) == NC_MMAP);
2223  diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
2224  inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
2225 
2226  if(mmap && inmemory) /* cannot have both */
2227  return NC_EINMEMORY;
2228  if(mmap && diskless) /* cannot have both */
2229  return NC_EDISKLESS;
2230 
2231  /* Attempt to do file path conversion: note that this will do
2232  nothing if path is a 'file:...' url, so it will need to be
2233  repeated in protocol code: libdap2 and libdap4
2234  */
2235 
2236 #ifdef WINPATH
2237  path = NCpathcvt(path0);
2238 #else
2239  path = nulldup(path0);
2240 #endif
2241 
2242 #ifdef USE_REFCOUNT
2243  /* If this path is already open, then bump the refcount and return it */
2244  ncp = find_in_NCList_by_name(path);
2245  if(ncp != NULL) {
2246  nullfree(path);
2247  ncp->refcount++;
2248  if(ncidp) *ncidp = ncp->ext_ncid;
2249  return NC_NOERR;
2250  }
2251 #endif
2252 
2253  if(!inmemory) {
2254  char* newpath = NULL;
2255  model = NC_urlmodel(path,omode,&newpath);
2256  isurl = (model != 0);
2257  if(isurl) {
2258  nullfree(path);
2259  path = newpath;
2260  } else
2261  nullfree(newpath);
2262  }
2263 
2264 #ifdef USE_NETCDF4
2265  /* Check for use of user-defined format 0. */
2266  if (omode & NC_UDF0)
2267  {
2268  if (!UDF0_dispatch_table)
2269  return NC_EINVAL;
2270  model = NC_FORMATX_UDF0;
2271  dispatcher = UDF0_dispatch_table;
2272  }
2273 
2274  /* Check for use of user-defined format 1. */
2275  if (omode & NC_UDF1)
2276  {
2277  if (!UDF1_dispatch_table)
2278  return NC_EINVAL;
2279  model = NC_FORMATX_UDF1;
2280  dispatcher = UDF1_dispatch_table;
2281  }
2282 #endif /* USE_NETCDF4 */
2283 
2284  if(model == 0) {
2285  version = 0;
2286  /* Try to find dataset type */
2287  int flags = omode;
2288  stat = NC_check_file_type(path,flags,useparallel,parameters,&model,&version);
2289  if(stat == NC_NOERR) {
2290  if(model == 0) {
2291  nullfree(path);
2292  return NC_ENOTNC;
2293  }
2294  } else {
2295  /* presumably not a netcdf file */
2296  nullfree(path);
2297  return stat;
2298  }
2299  }
2300 
2301  if(model == 0) {
2302  fprintf(stderr,"Model == 0\n");
2303  return NC_ENOTNC;
2304  }
2305 
2306  /* Suppress unsupported formats */
2307  {
2308  int hdf5built = 0;
2309  int hdf4built = 0;
2310  int cdf5built = 0;
2311 #ifdef USE_NETCDF4
2312  hdf5built = 1;
2313  #ifdef USEHDF4
2314  hdf4built = 1;
2315  #endif
2316 #endif
2317 #ifdef ENABLE_CDF5
2318  cdf5built = 1;
2319 #endif
2320  if(!hdf5built && model == NC_FORMATX_NC4) {
2321  free(path);
2322  return NC_ENOTBUILT;
2323  }
2324  if(!hdf4built && model == NC_FORMATX_NC4 && version == 4) {
2325  free(path);
2326  return NC_ENOTBUILT;
2327  }
2328  if(!cdf5built && model == NC_FORMATX_NC3 && version == 5) {
2329  free(path);
2330  return NC_ENOTBUILT;
2331  }
2332  }
2333 
2334  /* Force flag consistency */
2335  if(model == NC_FORMATX_NC4 || model == NC_FORMATX_NC_HDF4 || model == NC_FORMATX_DAP4 ||
2336  model == NC_FORMATX_UDF0 || model == NC_FORMATX_UDF1)
2337  omode |= NC_NETCDF4;
2338  else if(model == NC_FORMATX_DAP2) {
2339  omode &= ~NC_NETCDF4;
2340  omode &= ~NC_64BIT_OFFSET;
2341  } else if(model == NC_FORMATX_NC3) {
2342  omode &= ~NC_NETCDF4; /* must be netcdf-3 (CDF-1, CDF-2, CDF-5) */
2343  if(version == 2) omode |= NC_64BIT_OFFSET;
2344  else if(version == 5) omode |= NC_64BIT_DATA;
2345  } else if(model == NC_FORMATX_PNETCDF) {
2346  omode &= ~NC_NETCDF4; /* must be netcdf-3 (CDF-1, CDF-2, CDF-5) */
2347  if(version == 2) omode |= NC_64BIT_OFFSET;
2348  else if(version == 5) omode |= NC_64BIT_DATA;
2349  }
2350 
2351  /* Figure out what dispatcher to use */
2352  if (!dispatcher) {
2353  switch (model) {
2354 #if defined(ENABLE_DAP)
2355  case NC_FORMATX_DAP2:
2356  dispatcher = NCD2_dispatch_table;
2357  break;
2358 #endif
2359 #if defined(ENABLE_DAP4)
2360  case NC_FORMATX_DAP4:
2361  dispatcher = NCD4_dispatch_table;
2362  break;
2363 #endif
2364 #if defined(USE_PNETCDF)
2365  case NC_FORMATX_PNETCDF:
2366  dispatcher = NCP_dispatch_table;
2367  break;
2368 #endif
2369 #if defined(USE_HDF5)
2370  case NC_FORMATX_NC4:
2371  dispatcher = HDF5_dispatch_table;
2372  break;
2373 #endif
2374 #if defined(USE_HDF4)
2375  case NC_FORMATX_NC_HDF4:
2376  dispatcher = HDF4_dispatch_table;
2377  break;
2378 #endif
2379 #ifdef USE_NETCDF4
2380  case NC_FORMATX_UDF0:
2381  dispatcher = UDF0_dispatch_table;
2382  break;
2383  case NC_FORMATX_UDF1:
2384  dispatcher = UDF1_dispatch_table;
2385  break;
2386 #endif /* USE_NETCDF4 */
2387  case NC_FORMATX_NC3:
2388  dispatcher = NC3_dispatch_table;
2389  break;
2390  default:
2391  nullfree(path);
2392  return NC_ENOTNC;
2393  }
2394  }
2395 
2396  /* If we can't figure out what dispatch table to use, give up. */
2397  if (!dispatcher) {
2398  nullfree(path);
2399  return NC_ENOTNC;
2400  }
2401 
2402  /* Create the NC* instance and insert its dispatcher */
2403  stat = new_NC(dispatcher,path,omode,model,&ncp);
2404  nullfree(path); path = NULL; /* no longer need path */
2405  if(stat) return stat;
2406 
2407  /* Add to list of known open files */
2408  add_to_NCList(ncp);
2409 
2410 #ifdef USE_REFCOUNT
2411  /* bump the refcount */
2412  ncp->refcount++;
2413 #endif
2414 
2415  /* Assume open will fill in remaining ncp fields */
2416  stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2417  parameters, dispatcher, ncp);
2418  if(stat == NC_NOERR) {
2419  if(ncidp) *ncidp = ncp->ext_ncid;
2420  } else {
2421  del_from_NCList(ncp);
2422  free_NC(ncp);
2423  }
2424  return stat;
2425 }
2426 
2427 /*Provide an internal function for generating pseudo file descriptors
2428  for systems that are not file based (e.g. dap, memio).
2429 */
2430 
2432 static int pseudofd = 0;
2433 
2441 int
2442 nc__pseudofd(void)
2443 {
2444  if(pseudofd == 0) {
2445  int maxfd = 32767; /* default */
2446 #ifdef HAVE_GETRLIMIT
2447  struct rlimit rl;
2448  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2449  if(rl.rlim_max != RLIM_INFINITY)
2450  maxfd = (int)rl.rlim_max;
2451  if(rl.rlim_cur != RLIM_INFINITY)
2452  maxfd = (int)rl.rlim_cur;
2453  }
2454  pseudofd = maxfd+1;
2455 #endif
2456  }
2457  return pseudofd++;
2458 }
2459 
2465 static int
2466 openmagic(struct MagicFile* file)
2467 {
2468  int status = NC_NOERR;
2469  assert((file->inmemory) ? file->parameters != NULL : 1);
2470  if(file->inmemory) {
2471  /* Get its length */
2472  NC_memio* meminfo = (NC_memio*)file->parameters;
2473  file->filelen = (long long)meminfo->size;
2474  goto done;
2475  }
2476 #ifdef USE_PARALLEL
2477  if (file->use_parallel) {
2478  int retval;
2479  MPI_Offset size;
2480  assert(file->parameters);
2481  if((retval = MPI_File_open(((NC_MPI_INFO*)file->parameters)->comm,
2482  (char*)file->path,MPI_MODE_RDONLY,
2483  ((NC_MPI_INFO*)file->parameters)->info,
2484  &file->fh)) != MPI_SUCCESS) {
2485 #ifdef MPI_ERR_NO_SUCH_FILE
2486  int errorclass;
2487  MPI_Error_class(retval, &errorclass);
2488  if (errorclass == MPI_ERR_NO_SUCH_FILE)
2489 #ifdef NC_ENOENT
2490  status = NC_ENOENT;
2491 #else
2492  status = errno;
2493 #endif
2494  else
2495 #endif
2496  status = NC_EPARINIT;
2497  goto done;
2498  }
2499  /* Get its length */
2500  if((retval=MPI_File_get_size(file->fh, &size)) != MPI_SUCCESS)
2501  {status = NC_EPARINIT; goto done;}
2502  file->filelen = (long long)size;
2503  goto done;
2504  }
2505 #endif /* USE_PARALLEL */
2506  {
2507  if(file->path == NULL || strlen(file->path)==0)
2508  {status = NC_EINVAL; goto done;}
2509 #ifdef _MSC_VER
2510  file->fp = fopen(file->path, "rb");
2511 #else
2512  file->fp = fopen(file->path, "r");
2513 #endif
2514  if(file->fp == NULL)
2515  {status = errno; goto done;}
2516  /* Get its length */
2517  {
2518  int fd = fileno(file->fp);
2519 #ifdef _MSC_VER
2520  __int64 len64 = _filelengthi64(fd);
2521  if(len64 < 0)
2522  {status = errno; goto done;}
2523  file->filelen = (long long)len64;
2524 #else
2525  off_t size;
2526  size = lseek(fd, 0, SEEK_END);
2527  if(size == -1)
2528  {status = errno; goto done;}
2529  file->filelen = (long long)size;
2530 #endif
2531  rewind(file->fp);
2532  }
2533  goto done;
2534  }
2535 
2536 done:
2537  return status;
2538 }
2539 
2540 static int
2541 readmagic(struct MagicFile* file, long pos, char* magic)
2542 {
2543  int status = NC_NOERR;
2544  memset(magic,0,MAGIC_NUMBER_LEN);
2545  if(file->inmemory) {
2546  char* mempos;
2547  NC_memio* meminfo = (NC_memio*)file->parameters;
2548  if((pos + MAGIC_NUMBER_LEN) > meminfo->size)
2549  {status = NC_EINMEMORY; goto done;}
2550  mempos = ((char*)meminfo->memory) + pos;
2551  memcpy((void*)magic,mempos,MAGIC_NUMBER_LEN);
2552 #ifdef DEBUG
2553  printmagic("XXX: readmagic",magic,file);
2554 #endif
2555  goto done;
2556  }
2557 #ifdef USE_PARALLEL
2558  if (file->use_parallel) {
2559  MPI_Status mstatus;
2560  int retval;
2561  if((retval = MPI_File_read_at_all(file->fh, pos, magic,
2562  MAGIC_NUMBER_LEN, MPI_CHAR, &mstatus)) != MPI_SUCCESS)
2563  {status = NC_EPARINIT; goto done;}
2564  goto done;
2565  }
2566 #endif /* USE_PARALLEL */
2567  {
2568  int count;
2569  int i = fseek(file->fp,pos,SEEK_SET);
2570  if(i < 0)
2571  {status = errno; goto done;}
2572  for(i=0;i<MAGIC_NUMBER_LEN;) {/* make sure to read proper # of bytes */
2573  count=fread(&magic[i],1,(size_t)(MAGIC_NUMBER_LEN-i),file->fp);
2574  if(count == 0 || ferror(file->fp))
2575  {status = errno; goto done;}
2576  i += count;
2577  }
2578  goto done;
2579  }
2580 done:
2581  if(file && file->fp) clearerr(file->fp);
2582  return status;
2583 }
2584 
2594 static int
2595 closemagic(struct MagicFile* file)
2596 {
2597  int status = NC_NOERR;
2598  if(file->inmemory) goto done; /* noop*/
2599 #ifdef USE_PARALLEL
2600  if (file->use_parallel) {
2601  int retval;
2602  if((retval = MPI_File_close(&file->fh)) != MPI_SUCCESS)
2603  {status = NC_EPARINIT; goto done;}
2604  goto done;
2605  }
2606 #endif
2607  {
2608  if(file->fp) fclose(file->fp);
2609  goto done;
2610  }
2611 done:
2612  return status;
2613 }
2614 
2615 #ifdef DEBUG
2616 static void
2617 printmagic(const char* tag, char* magic, struct MagicFile* f)
2618 {
2619  int i;
2620  fprintf(stderr,"%s: inmem=%d ispar=%d magic=",tag,f->inmemory,f->use_parallel);
2621  for(i=0;i<MAGIC_NUMBER_LEN;i++) {
2622  unsigned int c = (unsigned int)magic[i];
2623  c = c & 0x000000FF;
2624  if(c == '\n')
2625  fprintf(stderr," 0x%0x/'\\n'",c);
2626  else if(c == '\r')
2627  fprintf(stderr," 0x%0x/'\\r'",c);
2628  else if(c < ' ')
2629  fprintf(stderr," 0x%0x/'?'",c);
2630  else
2631  fprintf(stderr," 0x%0x/'%c'",c,c);
2632  }
2633  fprintf(stderr,"\n");
2634  fflush(stderr);
2635 }
2636 #endif
#define NC_MAX_MAGIC_NUMBER_LEN
Max len of user-defined format magic number.
Definition: netcdf.h:165
#define NC_ENFILE
Too many netcdfs open.
Definition: netcdf.h:331
int nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
Add handling of user-defined format.
Definition: dfile.c:136
int NC_initialized
True when dispatch table is initialized.
int nc_close_memio(int ncid, NC_memio *memio)
Do a normal close (see nc_close()) on an in-memory dataset, then return a copy of the final memory co...
Definition: dfile.c:1535
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:211
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition: netcdf.h:138
Main header file for in-memory (diskless) functionality.
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:1127
int nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align)
Leave define mode with performance tuning.
Definition: dfile.c:1282
#define NC_UDF1
User-defined format 1.
Definition: netcdf.h:136
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:161
#define NC_MPIIO
Turn on MPI I/O.
Definition: netcdf.h:155
int nc_open_memio(const char *path, int omode, NC_memio *params, int *ncidp)
Open a netCDF file with the contents taken from a block of memory.
Definition: dfile.c:1005
int nc_inq_format(int ncid, int *formatp)
Inquire about the binary format of a netCDF file as presented by the API.
Definition: dfile.c:1729
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1817
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:25
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
Definition: netcdf.h:139
int nc__open(const char *path, int omode, size_t *chunksizehintp, int *ncidp)
Open a netCDF file with extra performance parameters for the classic library.
Definition: dfile.c:885
#define NC_UDF0
User-defined format 0.
Definition: netcdf.h:135
int nc_inq_format_extended(int ncid, int *formatp, int *modep)
Obtain more detailed (vis-a-vis nc_inq_format) format information about an open dataset.
Definition: dfile.c:1764
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:379
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:187
#define NC_64BIT_DATA
CDF-5 format: classic model but 64 bit dimensions and sizes.
Definition: netcdf.h:132
#define NC_ENOTBUILT
Attempt to use feature that was not turned on when netCDF was built.
Definition: netcdf.h:463
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1470
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:464
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1411
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:365
int nc_open_mem(const char *path, int omode, size_t size, void *memory, int *ncidp)
Open a netCDF file with the contents taken from a block of memory.
Definition: dfile.c:940
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:237
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:333
#define NC_EINMEMORY
In-memory file error.
Definition: netcdf.h:471
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1656
#define NC_FORMATX_UDF0
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:216
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:273
#define NC_NAT
Not A Type.
Definition: netcdf.h:34
int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Inquire about a type.
Definition: dfile.c:1910
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:214
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:209
#define NC_EPARINIT
Error initializing for parallel access.
Definition: netcdf.h:450
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition: netcdf.h:151
int nc__create(const char *path, int cmode, size_t initialsz, size_t *chunksizehintp, int *ncidp)
Create a netCDF file with some extra parameters controlling classic file caching. ...
Definition: dfile.c:634
#define NC_FORMAT_NETCDF4_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:183
#define NC_FORMATX_NC_HDF4
netCDF-4 subset of HDF4
Definition: netcdf.h:212
int nc_open(const char *path, int omode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:828
#define NC_FORMATX_UDF1
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:217
#define NC_FORMAT_NETCDF4
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:182
#define NC_CDF5
Alias NC_CDF5 to NC_64BIT_DATA.
Definition: netcdf.h:133
#define NC_WRITE
Set read-write access for nc_open().
Definition: netcdf.h:124
int nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
Inquire about user-defined format.
Definition: dfile.c:182
int nc_create_mem(const char *path, int mode, size_t initialsize, int *ncidp)
Create a netCDF file with the contents stored in memory.
Definition: dfile.c:680
int nc_inq_path(int ncid, size_t *pathlen, char *path)
Get the file pathname (or the opendap URL) which was used to open/create the ncid's file...
Definition: dfile.c:1062
#define NC_NOERR
No Error.
Definition: netcdf.h:323
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition: dfile.c:1836
#define NC_DISKLESS
Use diskless file.
Definition: netcdf.h:129
static int check_create_mode(int mode)
Check the create mode parameter for sanity.
Definition: dfile.c:1950
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:215
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:1191
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:213
static int NC_interpret_magic_number(char *magic, int *model, int *version)
Interpret the magic number found in the header of a netCDF file.
Definition: dfile.c:223
#define NC_FORMAT_64BIT_OFFSET
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:180
#define NC_MMAP
Definition: netcdf.h:130
static int closemagic(struct MagicFile *file)
Close the file opened to check for magic number.
Definition: dfile.c:2595
#define NC_FORMATX_UNDEFINED
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:218
#define NC_FORMAT_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:174
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
Definition: dfile.c:1359
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:562

Return to the Main Unidata NetCDF page.
Generated on Sat Apr 6 2019 08:19:00 for NetCDF. NetCDF is a Unidata library.