NetCDF  4.5.0
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 #include "ncdispatch.h"
24 #include "netcdf_mem.h"
25 #include "ncwinpath.h"
26 
27 extern int NC_initialized;
28 extern int NC_finalized;
29 
82 static int
83 NC_interpret_magic_number(char* magic, int* model, int* version, int use_parallel)
84 {
85  int status = NC_NOERR;
86  /* Look at the magic number */
87  /* Ignore the first byte for HDF */
88 #ifdef USE_NETCDF4
89  if(magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') {
90  *model = NC_FORMATX_NC4;
91  *version = 5;
92 #ifdef USE_HDF4
93  } else if(magic[0] == '\016' && magic[1] == '\003'
94  && magic[2] == '\023' && magic[3] == '\001') {
95  *model = NC_FORMATX_NC4;
96  *version = 4;
97 #endif
98  } else
99 #endif
100  if(magic[0] == 'C' && magic[1] == 'D' && magic[2] == 'F') {
101  if(magic[3] == '\001') {
102  *version = 1; /* netcdf classic version 1 */
103  *model = NC_FORMATX_NC3;
104  } else if(magic[3] == '\002') {
105  *version = 2; /* netcdf classic version 2 */
106  *model = NC_FORMATX_NC3;
107 #ifdef USE_CDF5
108  } else if(magic[3] == '\005') {
109  *version = 5; /* cdf5 (including pnetcdf) file */
110  *model = NC_FORMATX_NC3;
111 #endif
112  } else
113  {status = NC_ENOTNC; goto done;}
114  } else
115  {status = NC_ENOTNC; goto done;}
116 done:
117  return status;
118 }
119 
126 static int
127 NC_check_file_type(const char *path, int flags, void *parameters,
128  int* model, int* version)
129 {
130  char magic[MAGIC_NUMBER_LEN];
131  int status = NC_NOERR;
132  int diskless = ((flags & NC_DISKLESS) == NC_DISKLESS);
133  int use_parallel = ((flags & NC_MPIIO) == NC_MPIIO);
134  int inmemory = (diskless && ((flags & NC_INMEMORY) == NC_INMEMORY));
135 
136  *model = 0;
137 
138  if(inmemory) {
139  NC_MEM_INFO* meminfo = (NC_MEM_INFO*)parameters;
140  if(meminfo == NULL || meminfo->size < MAGIC_NUMBER_LEN)
141  {status = NC_EDISKLESS; goto done;}
142  memcpy(magic,meminfo->memory,MAGIC_NUMBER_LEN);
143  } else {/* presumably a real file */
144  /* Get the 4-byte magic from the beginning of the file. Don't use posix
145  * for parallel, use the MPI functions instead. */
146 
147 #ifdef USE_PARALLEL
148  if (use_parallel) {
149  MPI_File fh;
150  MPI_Status mstatus;
151  int retval;
152  MPI_Comm comm = MPI_COMM_WORLD;
153  MPI_Info info = MPI_INFO_NULL;
154 
155  if(parameters != NULL) {
156  comm = ((NC_MPI_INFO*)parameters)->comm;
157  info = ((NC_MPI_INFO*)parameters)->info;
158  }
159  if((retval = MPI_File_open(comm,(char*)path,MPI_MODE_RDONLY,info,
160  &fh)) != MPI_SUCCESS)
161  {status = NC_EPARINIT; goto done;}
162  if((retval = MPI_File_read(fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR,
163  &mstatus)) != MPI_SUCCESS)
164  {status = NC_EPARINIT; goto done;}
165  if((retval = MPI_File_close(&fh)) != MPI_SUCCESS)
166  {status = NC_EPARINIT; goto done;}
167  } else
168 #endif /* USE_PARALLEL */
169  {
170  FILE *fp;
171  size_t i;
172 #ifdef HAVE_FILE_LENGTH_I64
173  __int64 file_len = 0;
174 #else
175  struct stat st;
176 #endif
177  if(path == NULL || strlen(path)==0)
178  {status = NC_EINVAL; goto done;}
179 
180  if (!(fp = fopen(path, "r")))
181  {status = errno; goto done;}
182 
183 #ifdef HAVE_SYS_STAT_H
184  /* The file must be at least MAGIC_NUMBER_LEN in size,
185  or otherwise the following fread will exhibit unexpected
186  behavior. */
187 
188  /* Windows and fstat have some issues, this will work around that. */
189 #ifdef HAVE_FILE_LENGTH_I64
190  if((file_len = _filelengthi64(fileno(fp))) < 0) {
191  fclose(fp);
192  status = errno;
193  goto done;
194  }
195 
196  if(file_len < MAGIC_NUMBER_LEN) {
197  fclose(fp);
198  status = NC_ENOTNC;
199  goto done;
200  }
201 #else
202  { int fno = fileno(fp);
203  if(!(fstat(fno,&st) == 0)) {
204  fclose(fp);
205  status = errno;
206  goto done;
207  }
208  if(st.st_size < MAGIC_NUMBER_LEN) {
209  fclose(fp);
210  status = NC_ENOTNC;
211  goto done;
212  }
213  }
214 #endif //HAVE_FILE_LENGTH_I64
215 
216 #endif //HAVE_SYS_STAT_H
217 
218  i = fread(magic, MAGIC_NUMBER_LEN, 1, fp);
219  fclose(fp);
220  if(i == 0)
221  {status = NC_ENOTNC; goto done;}
222  if(i != 1)
223  {status = errno; goto done;}
224  }
225  } /* !inmemory */
226 
227  /* Look at the magic number */
228  status = NC_interpret_magic_number(magic,model,version,use_parallel);
229 
230 done:
231  return status;
232 }
233 
441 int
442 nc_create(const char *path, int cmode, int *ncidp)
443 {
444  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
445 }
446 
511 int
512 nc__create(const char *path, int cmode, size_t initialsz,
513  size_t *chunksizehintp, int *ncidp)
514 {
515  return NC_create(path, cmode, initialsz, 0,
516  chunksizehintp, 0, NULL, ncidp);
517 
518 }
527 int
528 nc__create_mp(const char *path, int cmode, size_t initialsz,
529  int basepe, size_t *chunksizehintp, int *ncidp)
530 {
531  return NC_create(path, cmode, initialsz, basepe,
532  chunksizehintp, 0, NULL, ncidp);
533 }
534 
649 int
650 nc_open(const char *path, int mode, int *ncidp)
651 {
652  return NC_open(path, mode, 0, NULL, 0, NULL, ncidp);
653 }
654 
706 int
707 nc__open(const char *path, int mode,
708  size_t *chunksizehintp, int *ncidp)
709 {
710  /* this API is for non-parallel access: TODO check for illegal cmode
711  * flags, such as NC_PNETCDF, NC_MPIIO, or NC_MPIPOSIX, before entering
712  * NC_open()? Note nc_open_par() also calls NC_open().
713  */
714  return NC_open(path, mode, 0, chunksizehintp, 0,
715  NULL, ncidp);
716 }
717 
763 int
764 nc_open_mem(const char* path, int mode, size_t size, void* memory, int* ncidp)
765 {
766 #ifdef USE_DISKLESS
767  NC_MEM_INFO meminfo;
768 
769  /* Sanity checks */
770  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
771  return NC_EINVAL;
772  if(mode & (NC_WRITE|NC_MPIIO|NC_MPIPOSIX|NC_MMAP))
773  return NC_EINVAL;
774  mode |= (NC_INMEMORY|NC_DISKLESS);
775  meminfo.size = size;
776  meminfo.memory = memory;
777  return NC_open(path, mode, 0, NULL, 0, &meminfo, ncidp);
778 #else
779  return NC_EDISKLESS;
780 #endif
781 }
782 
791 int
792 nc__open_mp(const char *path, int mode, int basepe,
793  size_t *chunksizehintp, int *ncidp)
794 {
795  return NC_open(path, mode, basepe, chunksizehintp,
796  0, NULL, ncidp);
797 }
798 
816 int
817 nc_inq_path(int ncid, size_t *pathlen, char *path)
818 {
819  NC* ncp;
820  int stat = NC_NOERR;
821  if ((stat = NC_check_id(ncid, &ncp)))
822  return stat;
823  if(ncp->path == NULL) {
824  if(pathlen) *pathlen = 0;
825  if(path) path[0] = '\0';
826  } else {
827  if (pathlen) *pathlen = strlen(ncp->path);
828  if (path) strcpy(path, ncp->path);
829  }
830  return stat;
831 }
832 
881 int
882 nc_redef(int ncid)
883 {
884  NC* ncp;
885  int stat = NC_check_id(ncid, &ncp);
886  if(stat != NC_NOERR) return stat;
887  return ncp->dispatch->redef(ncid);
888 }
889 
945 int
946 nc_enddef(int ncid)
947 {
948  int status = NC_NOERR;
949  NC *ncp;
950  status = NC_check_id(ncid, &ncp);
951  if(status != NC_NOERR) return status;
952  return ncp->dispatch->_enddef(ncid,0,1,0,1);
953 }
954 
1036 int
1037 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1038  size_t r_align)
1039 {
1040  NC* ncp;
1041  int stat = NC_check_id(ncid, &ncp);
1042  if(stat != NC_NOERR) return stat;
1043  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1044 }
1045 
1113 int
1114 nc_sync(int ncid)
1115 {
1116  NC* ncp;
1117  int stat = NC_check_id(ncid, &ncp);
1118  if(stat != NC_NOERR) return stat;
1119  return ncp->dispatch->sync(ncid);
1120 }
1121 
1165 int
1166 nc_abort(int ncid)
1167 {
1168  NC* ncp;
1169  int stat = NC_check_id(ncid, &ncp);
1170  if(stat != NC_NOERR) return stat;
1171 
1172 #ifdef USE_REFCOUNT
1173  /* What to do if refcount > 0? */
1174  /* currently, forcibly abort */
1175  ncp->refcount = 0;
1176 #endif
1177 
1178  stat = ncp->dispatch->abort(ncid);
1179  del_from_NCList(ncp);
1180  free_NC(ncp);
1181  return stat;
1182 }
1183 
1224 int
1225 nc_close(int ncid)
1226 {
1227  NC* ncp;
1228  int stat = NC_check_id(ncid, &ncp);
1229  if(stat != NC_NOERR) return stat;
1230 
1231 #ifdef USE_REFCOUNT
1232  ncp->refcount--;
1233  if(ncp->refcount <= 0)
1234 #endif
1235  {
1236 
1237  stat = ncp->dispatch->close(ncid);
1238  /* Remove from the nc list */
1239  del_from_NCList(ncp);
1240  free_NC(ncp);
1241  }
1242  return stat;
1243 }
1244 
1343 int
1344 nc_set_fill(int ncid, int fillmode, int *old_modep)
1345 {
1346  NC* ncp;
1347  int stat = NC_check_id(ncid, &ncp);
1348  if(stat != NC_NOERR) return stat;
1349  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1350 }
1351 
1363 int
1364 nc_inq_base_pe(int ncid, int *pe)
1365 {
1366  NC* ncp;
1367  int stat = NC_check_id(ncid, &ncp);
1368  if(stat != NC_NOERR) return stat;
1369  return ncp->dispatch->inq_base_pe(ncid,pe);
1370 }
1371 
1383 int
1384 nc_set_base_pe(int ncid, int pe)
1385 {
1386  NC* ncp;
1387  int stat = NC_check_id(ncid, &ncp);
1388  if(stat != NC_NOERR) return stat;
1389  return ncp->dispatch->set_base_pe(ncid,pe);
1390 }
1391 
1410 int
1411 nc_inq_format(int ncid, int *formatp)
1412 {
1413  NC* ncp;
1414  int stat = NC_check_id(ncid, &ncp);
1415  if(stat != NC_NOERR) return stat;
1416  return ncp->dispatch->inq_format(ncid,formatp);
1417 }
1418 
1445 int
1446 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1447 {
1448  NC* ncp;
1449  int stat = NC_check_id(ncid, &ncp);
1450  if(stat != NC_NOERR) return stat;
1451  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1452 }
1453 
1498 int
1499 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1500 {
1501  NC* ncp;
1502  int stat = NC_check_id(ncid, &ncp);
1503  if(stat != NC_NOERR) return stat;
1504  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1505 }
1506 
1507 int
1508 nc_inq_nvars(int ncid, int *nvarsp)
1509 {
1510  NC* ncp;
1511  int stat = NC_check_id(ncid, &ncp);
1512  if(stat != NC_NOERR) return stat;
1513  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1514 }
1515 
1581 int
1582 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1583 {
1584  NC* ncp;
1585  int stat;
1586 
1587  /* Do a quick triage on xtype */
1588  if(xtype <= NC_NAT) return NC_EBADTYPE;
1589  /* For compatibility, we need to allow inq about
1590  atomic types, even if ncid is ill-defined */
1591  if(xtype <= ATOMICTYPEMAX4) {
1592  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1593  if(size) *size = NC_atomictypelen(xtype);
1594  return NC_NOERR;
1595  }
1596  /* Apparently asking about a user defined type, so we need
1597  a valid ncid */
1598  stat = NC_check_id(ncid, &ncp);
1599  if(stat != NC_NOERR) /* bad ncid */
1600  return NC_EBADTYPE;
1601  /* have good ncid */
1602  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1603 }
1604 
1638 int
1639 NC_create(const char *path0, int cmode, size_t initialsz,
1640  int basepe, size_t *chunksizehintp, int useparallel,
1641  void* parameters, int *ncidp)
1642 {
1643  int stat = NC_NOERR;
1644  NC* ncp = NULL;
1645  NC_Dispatch* dispatcher = NULL;
1646  /* Need three pieces of information for now */
1647  int model = NC_FORMATX_UNDEFINED; /* one of the NC_FORMATX values */
1648  int isurl = 0; /* dap or cdmremote or neither */
1649  int xcmode = 0; /* for implied cmode flags */
1650  char* path = NULL;
1651 
1652  TRACE(nc_create);
1653  if(path0 == NULL)
1654  return NC_EINVAL;
1655  /* Initialize the dispatch table. The function pointers in the
1656  * dispatch table will depend on how netCDF was built
1657  * (with/without netCDF-4, DAP, CDMREMOTE). */
1658  if(!NC_initialized)
1659  {
1660  if ((stat = nc_initialize()))
1661  return stat;
1662  }
1663 
1664 #ifndef USE_DISKLESS
1665  cmode &= (~ NC_DISKLESS); /* Force off */
1666 #endif
1667 
1668 #ifdef WINPATH
1669  /* Need to do path conversion */
1670  path = NCpathcvt(path0);
1671 fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
1672 #else
1673  path = nulldup(path0);
1674 #endif
1675 
1676 #ifdef USE_REFCOUNT
1677  /* If this path is already open, then fail */
1678  ncp = find_in_NCList_by_name(path);
1679  if(ncp != NULL) {
1680  nullfree(path);
1681  return NC_ENFILE;
1682  }
1683 #endif
1684 
1685  {
1686  char* newpath = NULL;
1687  model = NC_urlmodel(path,cmode,&newpath);
1688  isurl = (model != 0);
1689  if(isurl) {
1690  nullfree(path);
1691  path = newpath;
1692  }
1693  }
1694 
1695  /* Look to the incoming cmode for hints */
1696  if(model == NC_FORMATX_UNDEFINED) {
1697 #ifdef USE_NETCDF4
1698  if((cmode & NC_NETCDF4) == NC_NETCDF4)
1699  model = NC_FORMATX_NC4;
1700  else
1701 #endif
1702 #ifdef USE_PNETCDF
1703  /* pnetcdf is used for parallel io on CDF-1, CDF-2, and CDF-5 */
1704  if((cmode & NC_MPIIO) == NC_MPIIO)
1705  model = NC_FORMATX_PNETCDF;
1706  else
1707 #endif
1708  {}
1709  }
1710  if(model == NC_FORMATX_UNDEFINED) {
1711  /* Check default format (not formatx) */
1712  int format = nc_get_default_format();
1713  switch (format) {
1714 #ifdef USE_NETCDF4
1715  case NC_FORMAT_NETCDF4:
1716  xcmode |= NC_NETCDF4;
1717  model = NC_FORMATX_NC4;
1718  break;
1720  xcmode |= NC_CLASSIC_MODEL;
1721  model = NC_FORMATX_NC4;
1722  break;
1723 #endif
1724 #ifdef USE_CDF5
1725  case NC_FORMAT_CDF5:
1726  xcmode |= NC_64BIT_DATA;
1727  model = NC_FORMATX_NC3;
1728  break;
1729 #endif
1731  xcmode |= NC_64BIT_OFFSET;
1732  model = NC_FORMATX_NC3;
1733  break;
1734  case NC_FORMAT_CLASSIC:
1735  model = NC_FORMATX_NC3;
1736  break;
1737  default:
1738  model = NC_FORMATX_NC3;
1739  break;
1740  }
1741  }
1742 
1743  /* Add inferred flags */
1744  cmode |= xcmode;
1745 
1746  /* Clean up illegal combinations */
1748  cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/
1749 
1750  if((cmode & NC_MPIIO) && (cmode & NC_MPIPOSIX))
1751  return NC_EINVAL;
1752 
1753  if (dispatcher == NULL)
1754  {
1755 
1756  /* Figure out what dispatcher to use */
1757 #ifdef USE_NETCDF4
1758  if(model == (NC_FORMATX_NC4))
1759  dispatcher = NC4_dispatch_table;
1760  else
1761 #endif /*USE_NETCDF4*/
1762 #ifdef USE_PNETCDF
1763  if(model == (NC_FORMATX_PNETCDF))
1764  dispatcher = NCP_dispatch_table;
1765  else
1766 #endif
1767  if(model == (NC_FORMATX_NC3))
1768  dispatcher = NC3_dispatch_table;
1769  else
1770  return NC_ENOTNC;
1771  }
1772 
1773  /* Create the NC* instance and insert its dispatcher */
1774  stat = new_NC(dispatcher,path,cmode,&ncp);
1775  nullfree(path); path = NULL; /* no longer needed */
1776 
1777  if(stat) return stat;
1778 
1779  /* Add to list of known open files and define ext_ncid */
1780  add_to_NCList(ncp);
1781 
1782 #ifdef USE_REFCOUNT
1783  /* bump the refcount */
1784  ncp->refcount++;
1785 #endif
1786 
1787  /* Assume create will fill in remaining ncp fields */
1788  if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp,
1789  useparallel, parameters, dispatcher, ncp))) {
1790  del_from_NCList(ncp); /* oh well */
1791  free_NC(ncp);
1792  } else {
1793  if(ncidp)*ncidp = ncp->ext_ncid;
1794  }
1795  return stat;
1796 }
1797 
1813 int
1814 NC_open(const char *path0, int cmode,
1815  int basepe, size_t *chunksizehintp,
1816  int useparallel, void* parameters,
1817  int *ncidp)
1818 {
1819  int stat = NC_NOERR;
1820  NC* ncp = NULL;
1821  NC_Dispatch* dispatcher = NULL;
1822  int inmemory = 0;
1823  int diskless = 0;
1824  /* Need pieces of information for now to decide model*/
1825  int model = 0;
1826  int isurl = 0;
1827  int version = 0;
1828  int flags = 0;
1829  char* path = NULL;
1830 
1831  TRACE(nc_open);
1832  if(!NC_initialized) {
1833  stat = nc_initialize();
1834  if(stat) return stat;
1835  }
1836 
1837  /* Attempt to do file path conversion: note that this will do
1838  nothing if path is a 'file:...' url, so it will need to be
1839  repeated in protocol code: libdap2 and libdap4
1840  */
1841 
1842 #ifndef USE_DISKLESS
1843  /* Clean up cmode */
1844  cmode &= (~ NC_DISKLESS);
1845 #endif
1846 
1847  inmemory = ((cmode & NC_INMEMORY) == NC_INMEMORY);
1848  diskless = ((cmode & NC_DISKLESS) == NC_DISKLESS);
1849 
1850 
1851 #ifdef WINPATH
1852  path = NCpathcvt(path0);
1853 #else
1854  path = nulldup(path0);
1855 #endif
1856 
1857 #ifdef USE_REFCOUNT
1858  /* If this path is already open, then bump the refcount and return it */
1859  ncp = find_in_NCList_by_name(path);
1860  if(ncp != NULL) {
1861  nullfree(path);
1862  ncp->refcount++;
1863  if(ncidp) *ncidp = ncp->ext_ncid;
1864  return NC_NOERR;
1865  }
1866 #endif
1867 
1868  if(!inmemory) {
1869  char* newpath = NULL;
1870  model = NC_urlmodel(path,cmode,&newpath);
1871  isurl = (model != 0);
1872  if(isurl) {
1873  nullfree(path);
1874  path = newpath;
1875  } else
1876  nullfree(newpath);
1877  }
1878  if(model == 0) {
1879  version = 0;
1880  /* Try to find dataset type */
1881  if(useparallel) flags |= NC_MPIIO;
1882  if(inmemory) flags |= NC_INMEMORY;
1883  if(diskless) flags |= NC_DISKLESS;
1884  stat = NC_check_file_type(path,flags,parameters,&model,&version);
1885  if(stat == NC_NOERR) {
1886  if(model == 0)
1887  return NC_ENOTNC;
1888  } else /* presumably not a netcdf file */
1889  return stat;
1890  }
1891 
1892  if(model == 0) {
1893  fprintf(stderr,"Model == 0\n");
1894  return NC_ENOTNC;
1895  }
1896 
1897  /* Force flag consistentcy */
1898  if(model == NC_FORMATX_NC4 || model == NC_FORMATX_DAP4)
1899  cmode |= NC_NETCDF4;
1900  else if(model == NC_FORMATX_DAP2) {
1901  cmode &= ~NC_NETCDF4;
1902  cmode &= ~NC_PNETCDF;
1903  cmode &= ~NC_64BIT_OFFSET;
1904  } else if(model == NC_FORMATX_NC3) {
1905  cmode &= ~NC_NETCDF4; /* must be netcdf-3 (CDF-1, CDF-2, CDF-5) */
1906  /* User may want to open file using the pnetcdf library */
1907  if(cmode & NC_PNETCDF) {
1908  /* dispatch is determined by cmode, rather than file format */
1909  model = NC_FORMATX_PNETCDF;
1910  }
1911  /* For opening an existing file, flags NC_64BIT_OFFSET and NC_64BIT_DATA
1912  * will be ignored, as the file is already in either CDF-1, 2, or 5
1913  * format. However, below we add the file format info to cmode so the
1914  * internal netcdf file open subroutine knows what file format to open.
1915  * The mode will be saved in ncp->mode, to be used by
1916  * nc_inq_format_extended() to report the file format.
1917  * See NC3_inq_format_extended() in libsrc/nc3internal.c for example.
1918  */
1919  if(version == 2) cmode |= NC_64BIT_OFFSET;
1920  else if(version == 5) {
1921  cmode |= NC_64BIT_DATA;
1922  cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/
1923  }
1924  } else if(model == NC_FORMATX_PNETCDF) {
1925  cmode &= ~(NC_NETCDF4|NC_64BIT_OFFSET);
1926  cmode |= NC_64BIT_DATA;
1927  }
1928 
1929  if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX))
1930  return NC_EINVAL;
1931 
1932  /* override any other table choice */
1933  if(dispatcher != NULL) goto havetable;
1934 
1935  /* Figure out what dispatcher to use */
1936 #if defined(ENABLE_DAP)
1937  if(model == (NC_FORMATX_DAP2))
1938  dispatcher = NCD2_dispatch_table;
1939  else
1940 #endif
1941 #if defined(ENABLE_DAP4)
1942  if(model == (NC_FORMATX_DAP4))
1943  dispatcher = NCD4_dispatch_table;
1944  else
1945 #endif
1946 #if defined(USE_PNETCDF)
1947  if(model == (NC_FORMATX_PNETCDF))
1948  dispatcher = NCP_dispatch_table;
1949  else
1950 #endif
1951 #if defined(USE_NETCDF4)
1952  if(model == (NC_FORMATX_NC4))
1953  dispatcher = NC4_dispatch_table;
1954  else
1955 #endif
1956  if(model == (NC_FORMATX_NC3))
1957  dispatcher = NC3_dispatch_table;
1958  else
1959  return NC_ENOTNC;
1960 
1961 havetable:
1962 
1963  if(dispatcher == NULL)
1964  return NC_ENOTNC;
1965 
1966  /* Create the NC* instance and insert its dispatcher */
1967  stat = new_NC(dispatcher,path,cmode,&ncp);
1968  nullfree(path); path = NULL; /* no longer need path */
1969  if(stat) return stat;
1970 
1971  /* Add to list of known open files */
1972  add_to_NCList(ncp);
1973 
1974 #ifdef USE_REFCOUNT
1975  /* bump the refcount */
1976  ncp->refcount++;
1977 #endif
1978 
1979  /* Assume open will fill in remaining ncp fields */
1980  stat = dispatcher->open(ncp->path, cmode, basepe, chunksizehintp,
1981  useparallel, parameters, dispatcher, ncp);
1982  if(stat == NC_NOERR) {
1983  if(ncidp) *ncidp = ncp->ext_ncid;
1984  } else {
1985  del_from_NCList(ncp);
1986  free_NC(ncp);
1987  }
1988  return stat;
1989 }
1990 
1991 /*Provide an internal function for generating pseudo file descriptors
1992  for systems that are not file based (e.g. dap, memio).
1993 */
1994 
1995 /* Static counter for pseudo file descriptors (incremented) */
1996 static int pseudofd = 0;
1997 
1998 /* Create a pseudo file descriptor that does not
1999  overlap real file descriptors
2000 */
2001 int
2002 nc__pseudofd(void)
2003 {
2004  if(pseudofd == 0) {
2005  int maxfd = 32767; /* default */
2006 #ifdef HAVE_GETRLIMIT
2007  struct rlimit rl;
2008  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2009  if(rl.rlim_max != RLIM_INFINITY)
2010  maxfd = (int)rl.rlim_max;
2011  if(rl.rlim_cur != RLIM_INFINITY)
2012  maxfd = (int)rl.rlim_cur;
2013  }
2014  pseudofd = maxfd+1;
2015 #endif
2016  }
2017  return pseudofd++;
2018 }
#define NC_PNETCDF
Use parallel-netcdf library; alias for NC_MPIIO.
Definition: netcdf.h:158
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:707
#define NC_ENFILE
Too many netcdfs open.
Definition: netcdf.h:316
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:83
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:204
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition: netcdf.h:134
Main header file for in-memory (diskless) functionality.
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:882
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:1037
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:156
#define NC_MPIIO
Turn on MPI I/O.
Definition: netcdf.h:151
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:1411
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1499
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:24
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
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:1446
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:364
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:180
#define NC_64BIT_DATA
CDF-5 format: classic model but 64 bit dimensions and sizes.
Definition: netcdf.h:131
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1225
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:451
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1166
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:350
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:228
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:318
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1344
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:261
#define NC_NAT
Not A Type.
Definition: netcdf.h:33
int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Inquire about a type.
Definition: dfile.c:1582
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:207
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:202
#define NC_EPARINIT
Error initializing for parallel access.
Definition: netcdf.h:437
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition: netcdf.h:147
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:512
#define NC_FORMAT_NETCDF4_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:176
#define NC_FORMAT_NETCDF4
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:175
#define NC_WRITE
Set read-write access for nc_open().
Definition: netcdf.h:124
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&#39;s file...
Definition: dfile.c:817
#define NC_NOERR
No Error.
Definition: netcdf.h:308
#define NC_DISKLESS
Use diskless file.
Definition: netcdf.h:128
int nc_open(const char *path, int mode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:650
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:208
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:127
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:946
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:206
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:764
#define NC_FORMAT_64BIT_OFFSET
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:173
#define NC_MMAP
Use diskless file with mmap.
Definition: netcdf.h:129
#define NC_FORMATX_UNDEFINED
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:209
#define NC_FORMAT_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:167
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
Definition: dfile.c:1114
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:442
#define NC_MPIPOSIX
Turn on MPI POSIX I/O.
Definition: netcdf.h:154

Return to the Main Unidata NetCDF page.
Generated on Thu Oct 26 2017 08:14:39 for NetCDF. NetCDF is a Unidata library.