NetCDF  4.4.1
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
dfile.c
Go to the documentation of this file.
1 
12 #include "config.h"
13 #include <stdlib.h>
14 #ifdef HAVE_SYS_RESOURCE_H
15 #include <sys/resource.h>
16 #endif
17 #ifdef HAVE_SYS_TYPES_H
18 #include <sys/types.h>
19 #endif
20 #ifdef HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
23 #ifdef HAVE_FCNTL_H
24 #include <fcntl.h>
25 #endif
26 #include "ncdispatch.h"
27 
28 extern int NC_initialized;
29 extern int NC_finalized;
30 
31 
84 static int
85 NC_interpret_magic_number(char* magic, int* model, int* version, int use_parallel)
86 {
87  int status = NC_NOERR;
88  /* Look at the magic number */
89  /* Ignore the first byte for HDF */
90 #ifdef USE_NETCDF4
91  if(magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') {
92  *model = NC_FORMATX_NC4;
93  *version = 5;
94 #ifdef USE_HDF4
95  } else if(magic[0] == '\016' && magic[1] == '\003'
96  && magic[2] == '\023' && magic[3] == '\001') {
97  *model = NC_FORMATX_NC4;
98  *version = 4;
99 #endif
100  } else
101 #endif
102  if(magic[0] == 'C' && magic[1] == 'D' && magic[2] == 'F') {
103  if(magic[3] == '\001') {
104  *version = 1; /* netcdf classic version 1 */
105  *model = NC_FORMATX_NC3;
106  } else if(magic[3] == '\002') {
107  *version = 2; /* netcdf classic version 2 */
108  *model = NC_FORMATX_NC3;
109  } else if(magic[3] == '\005') {
110  *version = 5; /* cdf5 (including pnetcdf) file */
111  *model = NC_FORMATX_NC3;
112  } else
113  {status = NC_ENOTNC; goto done;}
114  } else
115  {status = NC_ENOTNC; goto done;}
116 done:
117  return status;
118 }
119 
125 static int NC_check_file_type(const char *path, int flags, void *parameters,
126  int* model, int* version)
127 {
128  char magic[MAGIC_NUMBER_LEN];
129  int status = NC_NOERR;
130  int diskless = ((flags & NC_DISKLESS) == NC_DISKLESS);
131  int use_parallel = ((flags & NC_MPIIO) == NC_MPIIO);
132  int inmemory = (diskless && ((flags & NC_INMEMORY) == NC_INMEMORY));
133 
134  *model = 0;
135 
136  if(inmemory) {
137  NC_MEM_INFO* meminfo = (NC_MEM_INFO*)parameters;
138  if(meminfo == NULL || meminfo->size < MAGIC_NUMBER_LEN)
139  {status = NC_EDISKLESS; goto done;}
140  memcpy(magic,meminfo->memory,MAGIC_NUMBER_LEN);
141  } else {/* presumably a real file */
142  /* Get the 4-byte magic from the beginning of the file. Don't use posix
143  * for parallel, use the MPI functions instead. */
144 #ifdef USE_PARALLEL
145  if (use_parallel) {
146  MPI_File fh;
147  MPI_Status mstatus;
148  int retval;
149  MPI_Comm comm = MPI_COMM_WORLD;
150  MPI_Info info = MPI_INFO_NULL;
151 
152  if(parameters != NULL) {
153  comm = ((NC_MPI_INFO*)parameters)->comm;
154  info = ((NC_MPI_INFO*)parameters)->info;
155  }
156  if((retval = MPI_File_open(comm,(char*)path,MPI_MODE_RDONLY,info,
157  &fh)) != MPI_SUCCESS)
158  {status = NC_EPARINIT; goto done;}
159  if((retval = MPI_File_read(fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR,
160  &mstatus)) != MPI_SUCCESS)
161  {status = NC_EPARINIT; goto done;}
162  if((retval = MPI_File_close(&fh)) != MPI_SUCCESS)
163  {status = NC_EPARINIT; goto done;}
164  } else
165 #endif /* USE_PARALLEL */
166  {
167  FILE *fp;
168  size_t i;
169 #ifdef HAVE_SYS_STAT_H
170  struct stat st;
171 #endif
172  if(path == NULL || strlen(path)==0)
173  {status = NC_EINVAL; goto done;}
174 
175  if (!(fp = fopen(path, "r")))
176  {status = errno; goto done;}
177 
178 #ifdef HAVE_SYS_STAT_H
179  /* The file must be at least MAGIC_NUMBER_LEN in size,
180  or otherwise the following fread will exhibit unexpected
181  behavior. */
182 
183  /* Windows and fstat have some issues, this will work around that. */
184 #ifdef HAVE_FILE_LENGTH_I64
185  __int64 file_len = 0;
186  if((file_len = _filelengthi64(fileno(fp))) < 0) {
187  fclose(fp);
188  status = errno;
189  goto done;
190  }
191 
192  if(file_len < MAGIC_NUMBER_LEN) {
193  fclose(fp);
194  status = NC_ENOTNC;
195  goto done;
196  }
197 #else
198 
199  if(!(fstat(fileno(fp),&st) == 0)) {
200  fclose(fp);
201  status = errno;
202  goto done;
203  }
204 
205  if(st.st_size < MAGIC_NUMBER_LEN) {
206  fclose(fp);
207  status = NC_ENOTNC;
208  goto done;
209  }
210 #endif //HAVE_FILE_LENGTH_I64
211 
212 #endif
213 
214  i = fread(magic, MAGIC_NUMBER_LEN, 1, fp);
215  fclose(fp);
216  if(i == 0)
217  {status = NC_ENOTNC; goto done;}
218  if(i != 1)
219  {status = errno; goto done;}
220  }
221  } /* !inmemory */
222 
223  /* Look at the magic number */
224  status = NC_interpret_magic_number(magic,model,version,use_parallel);
225 
226 done:
227  return status;
228 }
229 
437 int
438 nc_create(const char *path, int cmode, int *ncidp)
439 {
440  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
441 }
442 
507 int
508 nc__create(const char *path, int cmode, size_t initialsz,
509  size_t *chunksizehintp, int *ncidp)
510 {
511  return NC_create(path, cmode, initialsz, 0,
512  chunksizehintp, 0, NULL, ncidp);
513 
514 }
523 int
524 nc__create_mp(const char *path, int cmode, size_t initialsz,
525  int basepe, size_t *chunksizehintp, int *ncidp)
526 {
527  return NC_create(path, cmode, initialsz, basepe,
528  chunksizehintp, 0, NULL, ncidp);
529 }
530 
645 int
646 nc_open(const char *path, int mode, int *ncidp)
647 {
648  return NC_open(path, mode, 0, NULL, 0, NULL, ncidp);
649 }
650 
702 int
703 nc__open(const char *path, int mode,
704  size_t *chunksizehintp, int *ncidp)
705 {
706  /* this API is for non-parallel access: TODO check for illegal cmode
707  * flags, such as NC_PNETCDF, NC_MPIIO, or NC_MPIPOSIX, before entering
708  * NC_open()? Note nc_open_par() also calls NC_open().
709  */
710  return NC_open(path, mode, 0, chunksizehintp, 0,
711  NULL, ncidp);
712 }
713 
759 int
760 nc_open_mem(const char* path, int mode, size_t size, void* memory, int* ncidp)
761 {
762 #ifdef USE_DISKLESS
763  NC_MEM_INFO meminfo;
764 
765  /* Sanity checks */
766  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
767  return NC_EINVAL;
768  if(mode & (NC_WRITE|NC_MPIIO|NC_MPIPOSIX|NC_MMAP))
769  return NC_EINVAL;
770  mode |= (NC_INMEMORY|NC_DISKLESS);
771  meminfo.size = size;
772  meminfo.memory = memory;
773  return NC_open(path, mode, 0, NULL, 0, &meminfo, ncidp);
774 #else
775  return NC_EDISKLESS;
776 #endif
777 }
778 
787 int
788 nc__open_mp(const char *path, int mode, int basepe,
789  size_t *chunksizehintp, int *ncidp)
790 {
791  return NC_open(path, mode, basepe, chunksizehintp,
792  0, NULL, ncidp);
793 }
794 
812 int
813 nc_inq_path(int ncid, size_t *pathlen, char *path)
814 {
815  NC* ncp;
816  int stat = NC_NOERR;
817  if ((stat = NC_check_id(ncid, &ncp)))
818  return stat;
819  if(ncp->path == NULL) {
820  if(pathlen) *pathlen = 0;
821  if(path) path[0] = '\0';
822  } else {
823  if (pathlen) *pathlen = strlen(ncp->path);
824  if (path) strcpy(path, ncp->path);
825  }
826  return stat;
827 }
828 
877 int
878 nc_redef(int ncid)
879 {
880  NC* ncp;
881  int stat = NC_check_id(ncid, &ncp);
882  if(stat != NC_NOERR) return stat;
883  return ncp->dispatch->redef(ncid);
884 }
885 
941 int
942 nc_enddef(int ncid)
943 {
944  int status = NC_NOERR;
945  NC *ncp;
946  status = NC_check_id(ncid, &ncp);
947  if(status != NC_NOERR) return status;
948  return ncp->dispatch->_enddef(ncid,0,1,0,1);
949 }
950 
1032 int
1033 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1034  size_t r_align)
1035 {
1036  NC* ncp;
1037  int stat = NC_check_id(ncid, &ncp);
1038  if(stat != NC_NOERR) return stat;
1039  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1040 }
1041 
1109 int
1110 nc_sync(int ncid)
1111 {
1112  NC* ncp;
1113  int stat = NC_check_id(ncid, &ncp);
1114  if(stat != NC_NOERR) return stat;
1115  return ncp->dispatch->sync(ncid);
1116 }
1117 
1161 int
1162 nc_abort(int ncid)
1163 {
1164  NC* ncp;
1165  int stat = NC_check_id(ncid, &ncp);
1166  if(stat != NC_NOERR) return stat;
1167 
1168 #ifdef USE_REFCOUNT
1169  /* What to do if refcount > 0? */
1170  /* currently, forcibly abort */
1171  ncp->refcount = 0;
1172 #endif
1173 
1174  stat = ncp->dispatch->abort(ncid);
1175  del_from_NCList(ncp);
1176  free_NC(ncp);
1177  return stat;
1178 }
1179 
1220 int
1221 nc_close(int ncid)
1222 {
1223  NC* ncp;
1224  int stat = NC_check_id(ncid, &ncp);
1225  if(stat != NC_NOERR) return stat;
1226 
1227 #ifdef USE_REFCOUNT
1228  ncp->refcount--;
1229  if(ncp->refcount <= 0)
1230 #endif
1231  {
1232 
1233  stat = ncp->dispatch->close(ncid);
1234  /* Remove from the nc list */
1235  del_from_NCList(ncp);
1236  free_NC(ncp);
1237  }
1238  return stat;
1239 }
1240 
1339 int
1340 nc_set_fill(int ncid, int fillmode, int *old_modep)
1341 {
1342  NC* ncp;
1343  int stat = NC_check_id(ncid, &ncp);
1344  if(stat != NC_NOERR) return stat;
1345  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1346 }
1347 
1359 int
1360 nc_inq_base_pe(int ncid, int *pe)
1361 {
1362  NC* ncp;
1363  int stat = NC_check_id(ncid, &ncp);
1364  if(stat != NC_NOERR) return stat;
1365  return ncp->dispatch->inq_base_pe(ncid,pe);
1366 }
1367 
1379 int
1380 nc_set_base_pe(int ncid, int pe)
1381 {
1382  NC* ncp;
1383  int stat = NC_check_id(ncid, &ncp);
1384  if(stat != NC_NOERR) return stat;
1385  return ncp->dispatch->set_base_pe(ncid,pe);
1386 }
1387 
1406 int
1407 nc_inq_format(int ncid, int *formatp)
1408 {
1409  NC* ncp;
1410  int stat = NC_check_id(ncid, &ncp);
1411  if(stat != NC_NOERR) return stat;
1412  return ncp->dispatch->inq_format(ncid,formatp);
1413 }
1414 
1441 int
1442 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1443 {
1444  NC* ncp;
1445  int stat = NC_check_id(ncid, &ncp);
1446  if(stat != NC_NOERR) return stat;
1447  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1448 }
1449 
1494 int
1495 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1496 {
1497  NC* ncp;
1498  int stat = NC_check_id(ncid, &ncp);
1499  if(stat != NC_NOERR) return stat;
1500  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1501 }
1502 
1503 int
1504 nc_inq_nvars(int ncid, int *nvarsp)
1505 {
1506  NC* ncp;
1507  int stat = NC_check_id(ncid, &ncp);
1508  if(stat != NC_NOERR) return stat;
1509  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1510 }
1511 
1577 int
1578 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1579 {
1580  NC* ncp;
1581  int stat;
1582 
1583  /* Do a quick triage on xtype */
1584  if(xtype <= NC_NAT) return NC_EBADTYPE;
1585  /* See if the ncid is valid */
1586  stat = NC_check_id(ncid, &ncp);
1587  if(stat != NC_NOERR) { /* bad ncid; do what we can */
1588  /* For compatibility, we need to allow inq about
1589  atomic types, even if ncid is ill-defined */
1590  if(xtype <= ATOMICTYPEMAX5) {
1591  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1592  if(size) *size = NC_atomictypelen(xtype);
1593  return NC_NOERR;
1594  } else
1595  return NC_EBADTYPE;
1596  } else { /* have good ncid */
1597  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1598  }
1599 #if 0
1600  int maxtype;
1601  int format;
1602  nc_inq_format(ncid, &format);
1603  switch (format) {
1604  case NC_FORMAT_NETCDF4_CLASSIC: /*fall thru*/
1605  case NC_FORMAT_64BIT_OFFSET: /*fall thru*/
1606  case NC_FORMAT_CLASSIC: maxtype = ATOMICTYPEMAX3; break;
1607  case NC_FORMAT_NETCDF4: maxtype = ATOMICTYPEMAX4; break;
1608  case NC_FORMAT_CDF5: maxtype = ATOMICTYPEMAX5; break;
1609  default: return NC_EINVAL;
1610  }
1611 #endif
1612 }
1613 
1648 int
1649 NC_create(const char *path, int cmode, size_t initialsz,
1650  int basepe, size_t *chunksizehintp, int useparallel,
1651  void* parameters, int *ncidp)
1652 {
1653  int stat = NC_NOERR;
1654  NC* ncp = NULL;
1655  NC_Dispatch* dispatcher = NULL;
1656  /* Need three pieces of information for now */
1657  int model = NC_FORMATX_UNDEFINED; /* one of the NC_FORMATX values */
1658  int isurl = 0; /* dap or cdmremote or neither */
1659  int xcmode = 0; /* for implied cmode flags */
1660 
1661  TRACE(nc_create);
1662  /* Initialize the dispatch table. The function pointers in the
1663  * dispatch table will depend on how netCDF was built
1664  * (with/without netCDF-4, DAP, CDMREMOTE). */
1665  if(!NC_initialized)
1666  {
1667  if ((stat = nc_initialize()))
1668  return stat;
1669  }
1670 
1671 #ifdef USE_REFCOUNT
1672  /* If this path is already open, then fail */
1673  ncp = find_in_NCList_by_name(path);
1674  if(ncp != NULL)
1675  return NC_ENFILE;
1676 #endif
1677 
1678  if((isurl = NC_testurl(path)))
1679  model = NC_urlmodel(path);
1680 
1681  /* Look to the incoming cmode for hints */
1682  if(model == NC_FORMATX_UNDEFINED) {
1683 #ifdef USE_NETCDF4
1684  if((cmode & NC_NETCDF4) == NC_NETCDF4)
1685  model = NC_FORMATX_NC4;
1686  else
1687 #endif
1688 #ifdef USE_PNETCDF
1689  /* pnetcdf is used for parallel io on CDF-1, CDF-2, and CDF-5 */
1690  if((cmode & NC_MPIIO) == NC_MPIIO)
1691  model = NC_FORMATX_PNETCDF;
1692  else
1693 #endif
1694  {}
1695  }
1696  if(model == NC_FORMATX_UNDEFINED) {
1697  /* Check default format (not formatx) */
1698  int format = nc_get_default_format();
1699  switch (format) {
1700 #ifdef USE_NETCDF4
1701  case NC_FORMAT_NETCDF4:
1702  xcmode |= NC_NETCDF4;
1703  model = NC_FORMATX_NC4;
1704  break;
1706  xcmode |= NC_CLASSIC_MODEL;
1707  model = NC_FORMATX_NC4;
1708  break;
1709 #endif
1710  case NC_FORMAT_CDF5:
1711  xcmode |= NC_64BIT_DATA;
1712  model = NC_FORMATX_NC3;
1713  break;
1715  xcmode |= NC_64BIT_OFFSET;
1716  model = NC_FORMATX_NC3;
1717  break;
1718  case NC_FORMAT_CLASSIC:
1719  model = NC_FORMATX_NC3;
1720  break;
1721  default:
1722  model = NC_FORMATX_NC3;
1723  break;
1724  }
1725  }
1726 
1727  /* Add inferred flags */
1728  cmode |= xcmode;
1729 
1730  /* Clean up illegal combinations */
1732  cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/
1733 
1734  if((cmode & NC_MPIIO) && (cmode & NC_MPIPOSIX))
1735  return NC_EINVAL;
1736 
1737 #ifdef OBSOLETE
1738  dispatcher = NC_get_dispatch_override();
1739 #endif
1740  if (dispatcher == NULL)
1741  {
1742 
1743  /* Figure out what dispatcher to use */
1744 #ifdef USE_NETCDF4
1745  if(model == (NC_FORMATX_NC4))
1746  dispatcher = NC4_dispatch_table;
1747  else
1748 #endif /*USE_NETCDF4*/
1749 #ifdef USE_PNETCDF
1750  if(model == (NC_FORMATX_PNETCDF))
1751  dispatcher = NCP_dispatch_table;
1752  else
1753 #endif
1754  if(model == (NC_FORMATX_NC3))
1755  dispatcher = NC3_dispatch_table;
1756  else
1757  return NC_ENOTNC;
1758  }
1759 
1760  /* Create the NC* instance and insert its dispatcher */
1761  stat = new_NC(dispatcher,path,cmode,&ncp);
1762  if(stat) return stat;
1763 
1764  /* Add to list of known open files and define ext_ncid */
1765  add_to_NCList(ncp);
1766 
1767 #ifdef USE_REFCOUNT
1768  /* bump the refcount */
1769  ncp->refcount++;
1770 #endif
1771 
1772  /* Assume create will fill in remaining ncp fields */
1773  if ((stat = dispatcher->create(path, cmode, initialsz, basepe, chunksizehintp,
1774  useparallel, parameters, dispatcher, ncp))) {
1775  del_from_NCList(ncp); /* oh well */
1776  free_NC(ncp);
1777  } else {
1778  if(ncidp)*ncidp = ncp->ext_ncid;
1779  }
1780  return stat;
1781 }
1782 
1798 int
1799 NC_open(const char *path, int cmode,
1800  int basepe, size_t *chunksizehintp,
1801  int useparallel, void* parameters,
1802  int *ncidp)
1803 {
1804  int stat = NC_NOERR;
1805  NC* ncp = NULL;
1806  NC_Dispatch* dispatcher = NULL;
1807  int inmemory = ((cmode & NC_INMEMORY) == NC_INMEMORY);
1808  /* Need pieces of information for now to decide model*/
1809  int model = 0;
1810  int isurl = 0;
1811  int version = 0;
1812  int flags = 0;
1813 
1814  TRACE(nc_open);
1815  if(!NC_initialized) {
1816  stat = nc_initialize();
1817  if(stat) return stat;
1818  }
1819 
1820 #ifdef USE_REFCOUNT
1821  /* If this path is already open, then bump the refcount and return it */
1822  ncp = find_in_NCList_by_name(path);
1823  if(ncp != NULL) {
1824  ncp->refcount++;
1825  if(ncidp) *ncidp = ncp->ext_ncid;
1826  return NC_NOERR;
1827  }
1828 #endif
1829 
1830  if(!inmemory) {
1831  isurl = NC_testurl(path);
1832  if(isurl)
1833  model = NC_urlmodel(path);
1834  }
1835  if(model == 0) {
1836  version = 0;
1837  /* Try to find dataset type */
1838  if(useparallel) flags |= NC_MPIIO;
1839  if(inmemory) flags |= NC_INMEMORY;
1840  stat = NC_check_file_type(path,flags,parameters,&model,&version);
1841  if(stat == NC_NOERR) {
1842  if(model == 0)
1843  return NC_ENOTNC;
1844  } else /* presumably not a netcdf file */
1845  return stat;
1846  }
1847 
1848  if(model == 0) {
1849  fprintf(stderr,"Model == 0\n");
1850  return NC_ENOTNC;
1851  }
1852 
1853  /* Force flag consistentcy */
1854  if(model == NC_FORMATX_NC4)
1855  cmode |= NC_NETCDF4;
1856  else if(model == NC_FORMATX_NC3) {
1857  cmode &= ~NC_NETCDF4; /* must be netcdf-3 (CDF-1, CDF-2, CDF-5) */
1858  /* User may want to open file using the pnetcdf library */
1859  if(cmode & NC_PNETCDF) {
1860  /* dispatch is determined by cmode, rather than file format */
1861  model = NC_FORMATX_PNETCDF;
1862  }
1863  /* For opening an existing file, flags NC_64BIT_OFFSET and NC_64BIT_DATA
1864  * will be ignored, as the file is already in either CDF-1, 2, or 5
1865  * format. However, below we add the file format info to cmode so the
1866  * internal netcdf file open subroutine knows what file format to open.
1867  * The mode will be saved in ncp->mode, to be used by
1868  * nc_inq_format_extended() to report the file format.
1869  * See NC3_inq_format_extended() in libsrc/nc3internal.c for example.
1870  */
1871  if(version == 2) cmode |= NC_64BIT_OFFSET;
1872  else if(version == 5) {
1873  cmode |= NC_64BIT_DATA;
1874  cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/
1875  }
1876  } else if(model == NC_FORMATX_PNETCDF) {
1877  cmode &= ~(NC_NETCDF4|NC_64BIT_OFFSET);
1878  cmode |= NC_64BIT_DATA;
1879  }
1880 
1881  if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX))
1882  return NC_EINVAL;
1883 
1884  /* override any other table choice */
1885 #ifdef OBSOLETE
1886  dispatcher = NC_get_dispatch_override();
1887 #endif
1888  if(dispatcher != NULL) goto havetable;
1889 
1890  /* Figure out what dispatcher to use */
1891 #if defined(USE_CDMREMOTE)
1892  if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR))
1893  dispatcher = NCCR_dispatch_table;
1894  else
1895 #endif
1896 #if defined(USE_DAP)
1897  if(model == (NC_FORMATX_DAP2))
1898  dispatcher = NCD2_dispatch_table;
1899  else
1900 #endif
1901 #if defined(USE_PNETCDF)
1902  if(model == (NC_FORMATX_PNETCDF))
1903  dispatcher = NCP_dispatch_table;
1904  else
1905 #endif
1906 #if defined(USE_NETCDF4)
1907  if(model == (NC_FORMATX_NC4))
1908  dispatcher = NC4_dispatch_table;
1909  else
1910 #endif
1911  if(model == (NC_FORMATX_NC3))
1912  dispatcher = NC3_dispatch_table;
1913  else
1914  return NC_ENOTNC;
1915 
1916 havetable:
1917 
1918  /* Create the NC* instance and insert its dispatcher */
1919  stat = new_NC(dispatcher,path,cmode,&ncp);
1920  if(stat) return stat;
1921 
1922  /* Add to list of known open files */
1923  add_to_NCList(ncp);
1924 
1925 #ifdef USE_REFCOUNT
1926  /* bump the refcount */
1927  ncp->refcount++;
1928 #endif
1929 
1930  /* Assume open will fill in remaining ncp fields */
1931  stat = dispatcher->open(path, cmode, basepe, chunksizehintp,
1932  useparallel, parameters, dispatcher, ncp);
1933  if(stat == NC_NOERR) {
1934  if(ncidp) *ncidp = ncp->ext_ncid;
1935  } else {
1936  del_from_NCList(ncp);
1937  free_NC(ncp);
1938  }
1939  return stat;
1940 }
1941 
1942 /*Provide an internal function for generating pseudo file descriptors
1943  for systems that are not file based (e.g. dap, memio).
1944 */
1945 
1946 /* Static counter for pseudo file descriptors (incremented) */
1947 static int pseudofd = 0;
1948 
1949 /* Create a pseudo file descriptor that does not
1950  overlap real file descriptors
1951 */
1952 int
1953 nc__pseudofd(void)
1954 {
1955  if(pseudofd == 0) {
1956  int maxfd = 32767; /* default */
1957 #ifdef HAVE_GETRLIMIT
1958  struct rlimit rl;
1959  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
1960  if(rl.rlim_max != RLIM_INFINITY)
1961  maxfd = (int)rl.rlim_max;
1962  if(rl.rlim_cur != RLIM_INFINITY)
1963  maxfd = (int)rl.rlim_cur;
1964  }
1965  pseudofd = maxfd+1;
1966 #endif
1967  }
1968  return pseudofd++;
1969 }
#define NC_PNETCDF
Use parallel-netcdf library; alias for NC_MPIIO.
Definition: netcdf.h:165
int nc__open(const char *path, int mode, size_t *chunksizehintp, int *ncidp)
Open a netCDF file with extra performance parameters for the classic library.
Definition: dfile.c:703
#define NC_ENFILE
Too many netcdfs open.
Definition: netcdf.h:323
static int NC_interpret_magic_number(char *magic, int *model, int *version, int use_parallel)
Interpret the magic number found in the header of a netCDF file.
Definition: dfile.c:85
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:211
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition: netcdf.h:141
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:878
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:1033
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:163
#define NC_MPIIO
Turn on MPI I/O.
Definition: netcdf.h:158
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:1407
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1495
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:28
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
Definition: netcdf.h:142
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:1442
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:371
#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:138
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1221
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:456
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1162
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:357
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:235
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:325
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1340
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:268
#define NC_NAT
Not A Type.
Definition: netcdf.h:37
int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Inquire about a type.
Definition: dfile.c:1578
#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:442
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition: netcdf.h:154
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 cacheing.
Definition: dfile.c:508
#define NC_FORMAT_NETCDF4_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:183
#define NC_FORMAT_NETCDF4
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:182
#define NC_WRITE
Set read-write access for nc_open().
Definition: netcdf.h:131
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:813
#define NC_NOERR
No Error.
Definition: netcdf.h:315
#define NC_DISKLESS
Use diskless file.
Definition: netcdf.h:135
int nc_open(const char *path, int mode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:646
static int NC_check_file_type(const char *path, int flags, void *parameters, int *model, int *version)
Given an existing file, figure out its format and return that format value (NC_FORMATX_XXX) in model ...
Definition: dfile.c:125
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:942
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:213
int nc_open_mem(const char *path, int mode, size_t size, void *memory, int *ncidp)
Open a netCDF file with the contents taken from a block of memory.
Definition: dfile.c:760
#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
Use diskless file with mmap.
Definition: netcdf.h:136
#define NC_FORMATX_UNDEFINED
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:216
#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:1110
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:438
#define NC_MPIPOSIX
Turn on MPI POSIX I/O.
Definition: netcdf.h:161

Return to the Main Unidata NetCDF page.
Generated on Tue Aug 15 2017 19:06:55 for NetCDF. NetCDF is a Unidata library.