NetCDF  4.7.4
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 
36 #include "ncdispatch.h"
37 #include "netcdf_mem.h"
38 #include "ncwinpath.h"
39 #include "fbits.h"
40 
41 #undef DEBUG
42 
43 extern int NC_initialized;
45 /* User-defined formats. */
46 NC_Dispatch *UDF0_dispatch_table = NULL;
47 char UDF0_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
48 NC_Dispatch *UDF1_dispatch_table = NULL;
49 char UDF1_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
50 
51 /**************************************************/
52 
53 
119 int
120 nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
121 {
122  /* Check inputs. */
123  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
124  return NC_EINVAL;
125  if (!dispatch_table)
126  return NC_EINVAL;
127  if (magic_number && strlen(magic_number) > NC_MAX_MAGIC_NUMBER_LEN)
128  return NC_EINVAL;
129 
130  /* Check the version of the dispatch table provided. */
131  if (dispatch_table->dispatch_version != NC_DISPATCH_VERSION)
132  return NC_EINVAL;
133 
134  /* Retain a pointer to the dispatch_table and a copy of the magic
135  * number, if one was provided. */
136  switch(mode_flag)
137  {
138  case NC_UDF0:
139  UDF0_dispatch_table = dispatch_table;
140  if (magic_number)
141  strncpy(UDF0_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
142  break;
143  case NC_UDF1:
144  UDF1_dispatch_table = dispatch_table;
145  if (magic_number)
146  strncpy(UDF1_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
147  break;
148  }
149 
150  return NC_NOERR;
151 }
152 
169 int
170 nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
171 {
172  /* Check inputs. */
173  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
174  return NC_EINVAL;
175 
176  switch(mode_flag)
177  {
178  case NC_UDF0:
179  if (dispatch_table)
180  *dispatch_table = UDF0_dispatch_table;
181  if (magic_number)
182  strncpy(magic_number, UDF0_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
183  break;
184  case NC_UDF1:
185  if (dispatch_table)
186  *dispatch_table = UDF1_dispatch_table;
187  if (magic_number)
188  strncpy(magic_number, UDF1_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
189  break;
190  }
191 
192  return NC_NOERR;
193 }
194 
388 int
389 nc_create(const char *path, int cmode, int *ncidp)
390 {
391  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
392 }
393 
460 int
461 nc__create(const char *path, int cmode, size_t initialsz,
462  size_t *chunksizehintp, int *ncidp)
463 {
464  return NC_create(path, cmode, initialsz, 0,
465  chunksizehintp, 0, NULL, ncidp);
466 }
467 
506 int
507 nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
508 {
509  if(mode & NC_MMAP) return NC_EINVAL;
510  mode |= NC_INMEMORY; /* Specifically, do not set NC_DISKLESS */
511  return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
512 }
513 
533 int
534 nc__create_mp(const char *path, int cmode, size_t initialsz,
535  int basepe, size_t *chunksizehintp, int *ncidp)
536 {
537  return NC_create(path, cmode, initialsz, basepe,
538  chunksizehintp, 0, NULL, ncidp);
539 }
540 
654 int
655 nc_open(const char *path, int omode, int *ncidp)
656 {
657  return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
658 }
659 
711 int
712 nc__open(const char *path, int omode,
713  size_t *chunksizehintp, int *ncidp)
714 {
715  /* this API is for non-parallel access.
716  * Note nc_open_par() also calls NC_open().
717  */
718  return NC_open(path, omode, 0, chunksizehintp, 0, NULL, ncidp);
719 }
720 
766 int
767 nc_open_mem(const char* path, int omode, size_t size, void* memory, int* ncidp)
768 {
769  NC_memio meminfo;
770 
771  /* Sanity checks */
772  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
773  return NC_EINVAL;
774  if(omode & (NC_WRITE|NC_MMAP))
775  return NC_EINVAL;
776  omode |= (NC_INMEMORY); /* Note: NC_INMEMORY and NC_DISKLESS are mutually exclusive*/
777  meminfo.size = size;
778  meminfo.memory = memory;
779  meminfo.flags = NC_MEMIO_LOCKED;
780  return NC_open(path, omode, 0, NULL, 0, &meminfo, ncidp);
781 }
782 
831 int
832 nc_open_memio(const char* path, int omode, NC_memio* params, int* ncidp)
833 {
834  /* Sanity checks */
835  if(path == NULL || params == NULL)
836  return NC_EINVAL;
837  if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
838  return NC_EINVAL;
839 
840  if(omode & NC_MMAP)
841  return NC_EINVAL;
842  omode |= (NC_INMEMORY);
843  return NC_open(path, omode, 0, NULL, 0, params, ncidp);
844 }
845 
864 int
865 nc__open_mp(const char *path, int omode, int basepe,
866  size_t *chunksizehintp, int *ncidp)
867 {
868  return NC_open(path, omode, basepe, chunksizehintp, 0, NULL, ncidp);
869 }
870 
888 int
889 nc_inq_path(int ncid, size_t *pathlen, char *path)
890 {
891  NC* ncp;
892  int stat = NC_NOERR;
893  if ((stat = NC_check_id(ncid, &ncp)))
894  return stat;
895  if(ncp->path == NULL) {
896  if(pathlen) *pathlen = 0;
897  if(path) path[0] = '\0';
898  } else {
899  if (pathlen) *pathlen = strlen(ncp->path);
900  if (path) strcpy(path, ncp->path);
901  }
902  return stat;
903 }
904 
953 int
954 nc_redef(int ncid)
955 {
956  NC* ncp;
957  int stat = NC_check_id(ncid, &ncp);
958  if(stat != NC_NOERR) return stat;
959  return ncp->dispatch->redef(ncid);
960 }
961 
1017 int
1018 nc_enddef(int ncid)
1019 {
1020  int status = NC_NOERR;
1021  NC *ncp;
1022  status = NC_check_id(ncid, &ncp);
1023  if(status != NC_NOERR) return status;
1024  return ncp->dispatch->_enddef(ncid,0,1,0,1);
1025 }
1026 
1108 int
1109 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1110  size_t r_align)
1111 {
1112  NC* ncp;
1113  int stat = NC_check_id(ncid, &ncp);
1114  if(stat != NC_NOERR) return stat;
1115  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1116 }
1117 
1185 int
1186 nc_sync(int ncid)
1187 {
1188  NC* ncp;
1189  int stat = NC_check_id(ncid, &ncp);
1190  if(stat != NC_NOERR) return stat;
1191  return ncp->dispatch->sync(ncid);
1192 }
1193 
1237 int
1238 nc_abort(int ncid)
1239 {
1240  NC* ncp;
1241  int stat = NC_check_id(ncid, &ncp);
1242  if(stat != NC_NOERR) return stat;
1243 
1244  stat = ncp->dispatch->abort(ncid);
1245  del_from_NCList(ncp);
1246  free_NC(ncp);
1247  return stat;
1248 }
1249 
1290 int
1291 nc_close(int ncid)
1292 {
1293  NC* ncp;
1294  int stat = NC_check_id(ncid, &ncp);
1295  if(stat != NC_NOERR) return stat;
1296 
1297  stat = ncp->dispatch->close(ncid,NULL);
1298  /* Remove from the nc list */
1299  if (!stat)
1300  {
1301  del_from_NCList(ncp);
1302  free_NC(ncp);
1303  }
1304  return stat;
1305 }
1306 
1349 int
1350 nc_close_memio(int ncid, NC_memio* memio)
1351 {
1352  NC* ncp;
1353  int stat = NC_check_id(ncid, &ncp);
1354  if(stat != NC_NOERR) return stat;
1355 
1356  stat = ncp->dispatch->close(ncid,memio);
1357  /* Remove from the nc list */
1358  if (!stat)
1359  {
1360  del_from_NCList(ncp);
1361  free_NC(ncp);
1362  }
1363  return stat;
1364 }
1365 
1464 int
1465 nc_set_fill(int ncid, int fillmode, int *old_modep)
1466 {
1467  NC* ncp;
1468  int stat = NC_check_id(ncid, &ncp);
1469  if(stat != NC_NOERR) return stat;
1470  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1471 }
1472 
1487 int
1488 nc_inq_base_pe(int ncid, int *pe)
1489 {
1490  NC* ncp;
1491  int stat = NC_check_id(ncid, &ncp);
1492  if(stat != NC_NOERR) return stat;
1493  if (pe) *pe = 0;
1494  return NC_NOERR;
1495 }
1496 
1511 int
1512 nc_set_base_pe(int ncid, int pe)
1513 {
1514  NC* ncp;
1515  int stat = NC_check_id(ncid, &ncp);
1516  if(stat != NC_NOERR) return stat;
1517  return NC_NOERR;
1518 }
1519 
1537 int
1538 nc_inq_format(int ncid, int *formatp)
1539 {
1540  NC* ncp;
1541  int stat = NC_check_id(ncid, &ncp);
1542  if(stat != NC_NOERR) return stat;
1543  return ncp->dispatch->inq_format(ncid,formatp);
1544 }
1545 
1572 int
1573 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1574 {
1575  NC* ncp;
1576  int stat = NC_check_id(ncid, &ncp);
1577  if(stat != NC_NOERR) return stat;
1578  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1579 }
1580 
1625 int
1626 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1627 {
1628  NC* ncp;
1629  int stat = NC_check_id(ncid, &ncp);
1630  if(stat != NC_NOERR) return stat;
1631  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1632 }
1633 
1644 int
1645 nc_inq_nvars(int ncid, int *nvarsp)
1646 {
1647  NC* ncp;
1648  int stat = NC_check_id(ncid, &ncp);
1649  if(stat != NC_NOERR) return stat;
1650  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1651 }
1652 
1718 int
1719 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1720 {
1721  NC* ncp;
1722  int stat;
1723 
1724  /* Do a quick triage on xtype */
1725  if(xtype <= NC_NAT) return NC_EBADTYPE;
1726  /* For compatibility, we need to allow inq about
1727  atomic types, even if ncid is ill-defined */
1728  if(xtype <= ATOMICTYPEMAX4) {
1729  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1730  if(size) *size = NC_atomictypelen(xtype);
1731  return NC_NOERR;
1732  }
1733  /* Apparently asking about a user defined type, so we need
1734  a valid ncid */
1735  stat = NC_check_id(ncid, &ncp);
1736  if(stat != NC_NOERR) /* bad ncid */
1737  return NC_EBADTYPE;
1738  /* have good ncid */
1739  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1740 }
1741 
1758 static int
1760 {
1761  int mode_format;
1762  int mmap = 0;
1763  int inmemory = 0;
1764  int diskless = 0;
1765 
1766  /* This is a clever check to see if more than one format bit is
1767  * set. */
1768  mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
1769  (mode & NC_CDF5);
1770  if (mode_format && (mode_format & (mode_format - 1)))
1771  return NC_EINVAL;
1772 
1773  mmap = ((mode & NC_MMAP) == NC_MMAP);
1774  inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
1775  diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
1776 
1777  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1778  if(diskless && inmemory) return NC_EDISKLESS;
1779  if(diskless && mmap) return NC_EDISKLESS;
1780  if(inmemory && mmap) return NC_EINMEMORY;
1781 
1782  /* mmap is not allowed for netcdf-4 */
1783  if(mmap && (mode & NC_NETCDF4)) return NC_EINVAL;
1784 
1785 #ifndef USE_NETCDF4
1786  /* If the user asks for a netCDF-4 file, and the library was built
1787  * without netCDF-4, then return an error.*/
1788  if (mode & NC_NETCDF4)
1789  return NC_ENOTBUILT;
1790 #endif /* USE_NETCDF4 undefined */
1791 
1792  /* Well I guess there is some sanity in the world after all. */
1793  return NC_NOERR;
1794 }
1795 
1823 int
1824 NC_create(const char *path0, int cmode, size_t initialsz,
1825  int basepe, size_t *chunksizehintp, int useparallel,
1826  void* parameters, int *ncidp)
1827 {
1828  int stat = NC_NOERR;
1829  NC* ncp = NULL;
1830  const NC_Dispatch* dispatcher = NULL;
1831  char* path = NULL;
1832  NCmodel model;
1833  char* newpath = NULL;
1834 
1835  TRACE(nc_create);
1836  if(path0 == NULL)
1837  return NC_EINVAL;
1838 
1839  /* Check mode flag for sanity. */
1840  if ((stat = check_create_mode(cmode)))
1841  return stat;
1842 
1843  /* Initialize the library. The available dispatch tables
1844  * will depend on how netCDF was built
1845  * (with/without netCDF-4, DAP, CDMREMOTE). */
1846  if(!NC_initialized)
1847  {
1848  if ((stat = nc_initialize()))
1849  return stat;
1850  }
1851 
1852  {
1853  /* Skip past any leading whitespace in path */
1854  const unsigned char* p;
1855  for(p=(const unsigned char*)path0;*p;p++) {if(*p > ' ') break;}
1856 #ifdef WINPATH
1857  /* Need to do path conversion */
1858  path = NCpathcvt(p);
1859 #else
1860  path = nulldup(p);
1861 #endif
1862  }
1863 
1864  memset(&model,0,sizeof(model));
1865  if((stat = NC_infermodel(path,&cmode,1,useparallel,NULL,&model,&newpath)))
1866  goto done;
1867  if(newpath) {
1868  nullfree(path);
1869  path = newpath;
1870  newpath = NULL;
1871  }
1872 
1873  assert(model.format != 0 && model.impl != 0);
1874 
1875  /* Now, check for NC_ENOTBUILT cases limited to create (so e.g. HDF4 is not listed) */
1876 #ifndef USE_HDF5
1877  if (model.impl == NC_FORMATX_NC4)
1878  {stat = NC_ENOTBUILT; goto done;}
1879 #endif
1880 #ifndef USE_PNETCDF
1881  if (model.impl == NC_FORMATX_PNETCDF)
1882  {stat = NC_ENOTBUILT; goto done;}
1883 #endif
1884 #ifndef ENABLE_CDF5
1885  if (model.impl == NC_FORMATX_NC3 && (cmode & NC_64BIT_DATA))
1886  {stat = NC_ENOTBUILT; goto done;}
1887 #endif
1888 
1889  /* Figure out what dispatcher to use */
1890  switch (model.impl) {
1891 #ifdef USE_HDF5
1892  case NC_FORMATX_NC4:
1893  dispatcher = HDF5_dispatch_table;
1894  break;
1895 #endif
1896 #ifdef USE_PNETCDF
1897  case NC_FORMATX_PNETCDF:
1898  dispatcher = NCP_dispatch_table;
1899  break;
1900 #endif
1901 #ifdef USE_NETCDF4
1902  case NC_FORMATX_UDF0:
1903  dispatcher = UDF0_dispatch_table;
1904  break;
1905  case NC_FORMATX_UDF1:
1906  dispatcher = UDF1_dispatch_table;
1907  break;
1908 #endif /* USE_NETCDF4 */
1909  case NC_FORMATX_NC3:
1910  dispatcher = NC3_dispatch_table;
1911  break;
1912  default:
1913  return NC_ENOTNC;
1914  }
1915 
1916  /* Create the NC* instance and insert its dispatcher and model */
1917  if((stat = new_NC(dispatcher,path,cmode,&ncp))) goto done;
1918 
1919  /* Add to list of known open files and define ext_ncid */
1920  add_to_NCList(ncp);
1921 
1922  /* Assume create will fill in remaining ncp fields */
1923  if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp,
1924  parameters, dispatcher, ncp->ext_ncid))) {
1925  del_from_NCList(ncp); /* oh well */
1926  free_NC(ncp);
1927  } else {
1928  if(ncidp)*ncidp = ncp->ext_ncid;
1929  }
1930 done:
1931  nullfree(path);
1932  return stat;
1933 }
1934 
1958 int
1959 NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
1960  int useparallel, void* parameters, int *ncidp)
1961 {
1962  int stat = NC_NOERR;
1963  NC* ncp = NULL;
1964  const NC_Dispatch* dispatcher = NULL;
1965  int inmemory = 0;
1966  int diskless = 0;
1967  int mmap = 0;
1968  char* path = NULL;
1969  NCmodel model;
1970  char* newpath = NULL;
1971 
1972  TRACE(nc_open);
1973  if(!NC_initialized) {
1974  stat = nc_initialize();
1975  if(stat) return stat;
1976  }
1977 
1978  /* Check inputs. */
1979  if (!path0)
1980  return NC_EINVAL;
1981 
1982  /* Capture the inmemory related flags */
1983  mmap = ((omode & NC_MMAP) == NC_MMAP);
1984  diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
1985  inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
1986 
1987  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1988  if(diskless && inmemory) {stat = NC_EDISKLESS; goto done;}
1989  if(diskless && mmap) {stat = NC_EDISKLESS; goto done;}
1990  if(inmemory && mmap) {stat = NC_EINMEMORY; goto done;}
1991 
1992  /* mmap is not allowed for netcdf-4 */
1993  if(mmap && (omode & NC_NETCDF4)) {stat = NC_EINVAL; goto done;}
1994 
1995  /* Attempt to do file path conversion: note that this will do
1996  nothing if path is a 'file:...' url, so it will need to be
1997  repeated in protocol code (e.g. libdap2, libdap4, etc).
1998  */
1999 
2000  {
2001  /* Skip past any leading whitespace in path */
2002  const unsigned char* p;
2003  for(p=(const unsigned char*)path0;*p;p++) {if(*p > ' ') break;}
2004 #ifdef WINPATH
2005  /* Need to do path conversion */
2006  path = NCpathcvt(p);
2007 #else
2008  path = nulldup(p);
2009 #endif
2010  }
2011 
2012  memset(&model,0,sizeof(model));
2013  /* Infer model implementation and format, possibly by reading the file */
2014  if((stat = NC_infermodel(path,&omode,0,useparallel,parameters,&model,&newpath)))
2015  goto done;
2016  if(newpath) {
2017  nullfree(path);
2018  path = newpath;
2019  }
2020 
2021  /* Still no implementation, give up */
2022  if(model.impl == 0) {
2023 #ifdef DEBUG
2024  fprintf(stderr,"implementation == 0\n");
2025 #endif
2026  {stat = NC_ENOTNC; goto done;}
2027  }
2028 
2029  /* Suppress unsupported formats */
2030  {
2031  int hdf5built = 0;
2032  int hdf4built = 0;
2033  int cdf5built = 0;
2034  int udf0built = 0;
2035  int udf1built = 0;
2036 #ifdef USE_NETCDF4
2037  hdf5built = 1;
2038 #ifdef USE_HDF4
2039  hdf4built = 1;
2040 #endif
2041 #endif
2042 #ifdef ENABLE_CDF5
2043  cdf5built = 1;
2044 #endif
2045  if(UDF0_dispatch_table != NULL)
2046  udf0built = 1;
2047  if(UDF1_dispatch_table != NULL)
2048  udf1built = 1;
2049 
2050  if(!hdf5built && model.impl == NC_FORMATX_NC4)
2051  {stat = NC_ENOTBUILT; goto done;}
2052  if(!hdf4built && model.impl == NC_FORMATX_NC_HDF4)
2053  {stat = NC_ENOTBUILT; goto done;}
2054  if(!cdf5built && model.impl == NC_FORMATX_NC3 && model.format == NC_FORMAT_CDF5)
2055  {stat = NC_ENOTBUILT; goto done;}
2056  if(!udf0built && model.impl == NC_FORMATX_UDF0)
2057  {stat = NC_ENOTBUILT; goto done;}
2058  if(!udf1built && model.impl == NC_FORMATX_UDF1)
2059  {stat = NC_ENOTBUILT; goto done;}
2060  }
2061  /* Figure out what dispatcher to use */
2062  if (!dispatcher) {
2063  switch (model.impl) {
2064 #ifdef ENABLE_DAP
2065  case NC_FORMATX_DAP2:
2066  dispatcher = NCD2_dispatch_table;
2067  break;
2068 #endif
2069 #ifdef ENABLE_DAP4
2070  case NC_FORMATX_DAP4:
2071  dispatcher = NCD4_dispatch_table;
2072  break;
2073 #endif
2074 #ifdef USE_PNETCDF
2075  case NC_FORMATX_PNETCDF:
2076  dispatcher = NCP_dispatch_table;
2077  break;
2078 #endif
2079 #ifdef USE_HDF5
2080  case NC_FORMATX_NC4:
2081  dispatcher = HDF5_dispatch_table;
2082  break;
2083 #endif
2084 #ifdef USE_HDF4
2085  case NC_FORMATX_NC_HDF4:
2086  dispatcher = HDF4_dispatch_table;
2087  break;
2088 #endif
2089 #ifdef USE_NETCDF4
2090  case NC_FORMATX_UDF0:
2091  dispatcher = UDF0_dispatch_table;
2092  break;
2093  case NC_FORMATX_UDF1:
2094  dispatcher = UDF1_dispatch_table;
2095  break;
2096 #endif /* USE_NETCDF4 */
2097  case NC_FORMATX_NC3:
2098  dispatcher = NC3_dispatch_table;
2099  break;
2100  default:
2101  nullfree(path);
2102  return NC_ENOTNC;
2103  }
2104  }
2105 
2106 
2107  /* If we can't figure out what dispatch table to use, give up. */
2108  if (!dispatcher) {stat = NC_ENOTNC; goto done;}
2109 
2110  /* Create the NC* instance and insert its dispatcher */
2111  if((stat = new_NC(dispatcher,path,omode,&ncp))) goto done;
2112 
2113  /* Add to list of known open files. This assigns an ext_ncid. */
2114  add_to_NCList(ncp);
2115 
2116  /* Assume open will fill in remaining ncp fields */
2117  stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2118  parameters, dispatcher, ncp->ext_ncid);
2119  if(stat == NC_NOERR) {
2120  if(ncidp) *ncidp = ncp->ext_ncid;
2121  } else {
2122  del_from_NCList(ncp);
2123  free_NC(ncp);
2124  }
2125 
2126 done:
2127  nullfree(path);
2128  return stat;
2129 }
2130 
2131 /*Provide an internal function for generating pseudo file descriptors
2132  for systems that are not file based (e.g. dap, memio).
2133 */
2134 
2136 static int pseudofd = 0;
2137 
2145 int
2146 nc__pseudofd(void)
2147 {
2148  if(pseudofd == 0) {
2149  int maxfd = 32767; /* default */
2150 #ifdef HAVE_GETRLIMIT
2151  struct rlimit rl;
2152  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2153  if(rl.rlim_max != RLIM_INFINITY)
2154  maxfd = (int)rl.rlim_max;
2155  if(rl.rlim_cur != RLIM_INFINITY)
2156  maxfd = (int)rl.rlim_cur;
2157  }
2158  pseudofd = maxfd+1;
2159 #endif
2160  }
2161  return pseudofd++;
2162 }
#define NC_MAX_MAGIC_NUMBER_LEN
Max len of user-defined format magic number.
Definition: netcdf.h:163
int nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
Add handling of user-defined format.
Definition: dfile.c:120
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:1350
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:212
Main header file for in-memory (diskless) functionality.
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:954
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:1109
#define NC_UDF1
User-defined format 1.
Definition: netcdf.h:136
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:161
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:832
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:1538
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1626
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:712
#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:1573
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:385
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:185
#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:469
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1291
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:470
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1238
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:371
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:767
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:239
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:339
#define NC_EINMEMORY
In-memory file error.
Definition: netcdf.h:477
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1465
#define NC_FORMATX_UDF0
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:217
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:275
#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:1719
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:215
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:210
#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:461
#define NC_FORMATX_NC_HDF4
netCDF-4 subset of HDF4
Definition: netcdf.h:213
int nc_open(const char *path, int omode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:655
#define NC_FORMATX_UDF1
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:218
#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:170
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:507
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:889
#define NC_NOERR
No Error.
Definition: netcdf.h:329
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition: dfile.c:1645
#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:1759
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:216
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:1018
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:214
#define NC_MMAP
Definition: netcdf.h:130
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
Definition: dfile.c:1186
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:389

Return to the Main Unidata NetCDF page.
Generated on Mon Nov 16 2020 01:48:49 for NetCDF. NetCDF is a Unidata library.