NetCDF  4.4.0
dfile.c
Go to the documentation of this file.
1 
11 #include "config.h"
12 #include <stdlib.h>
13 #ifdef HAVE_SYS_RESOURCE_H
14 #include <sys/resource.h>
15 #endif
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
18 #endif
19 #ifdef HAVE_SYS_STAT_H
20 #include <sys/stat.h>
21 #endif
22 #ifdef HAVE_FCNTL_H
23 #include <fcntl.h>
24 #endif
25 #include "ncdispatch.h"
26 
27 extern int NC_initialized;
28 extern int NC_finalized;
29 
67 static int
68 NC_interpret_magic_number(char* magic, int* model, int* version, int use_parallel)
69 {
70  int status = NC_NOERR;
71  /* Look at the magic number */
72  /* Ignore the first byte for HDF */
73 #ifdef USE_NETCDF4
74  if(magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') {
75  *model = NC_FORMATX_NC4;
76  *version = 5;
77 #ifdef USE_HDF4
78  } else if(magic[0] == '\016' && magic[1] == '\003'
79  && magic[2] == '\023' && magic[3] == '\001') {
80  *model = NC_FORMATX_NC4;
81  *version = 4;
82 #endif
83  } else
84 #endif
85  if(magic[0] == 'C' && magic[1] == 'D' && magic[2] == 'F') {
86  if(magic[3] == '\001') {
87  *version = 1; /* netcdf classic version 1 */
88  *model = NC_FORMATX_NC3;
89  } else if(magic[3] == '\002') {
90  *version = 2; /* netcdf classic version 2 */
91  *model = NC_FORMATX_NC3;
92  } else if(magic[3] == '\005') {
93  *version = 5; /* cdf5 (including pnetcdf) file */
94  *model = NC_FORMATX_NC3;
95  } else
96  {status = NC_ENOTNC; goto done;}
97  } else
98  {status = NC_ENOTNC; goto done;}
99 done:
100  return status;
101 }
102 
108 static int
109 NC_check_file_type(const char *path, int flags, void *parameters,
110  int* model, int* version)
111 {
112  char magic[MAGIC_NUMBER_LEN];
113  int status = NC_NOERR;
114  int diskless = ((flags & NC_DISKLESS) == NC_DISKLESS);
115  int use_parallel = ((flags & NC_MPIIO) == NC_MPIIO);
116  int inmemory = (diskless && ((flags & NC_INMEMORY) == NC_INMEMORY));
117 
118  *model = 0;
119 
120  if(inmemory) {
121  NC_MEM_INFO* meminfo = (NC_MEM_INFO*)parameters;
122  if(meminfo == NULL || meminfo->size < MAGIC_NUMBER_LEN)
123  {status = NC_EDISKLESS; goto done;}
124  memcpy(magic,meminfo->memory,MAGIC_NUMBER_LEN);
125  } else {/* presumably a real file */
126  /* Get the 4-byte magic from the beginning of the file. Don't use posix
127  * for parallel, use the MPI functions instead. */
128 #ifdef USE_PARALLEL
129  if (use_parallel) {
130  MPI_File fh;
131  MPI_Status mstatus;
132  int retval;
133  MPI_Comm comm = MPI_COMM_WORLD;
134  MPI_Info info = MPI_INFO_NULL;
135 
136  if(parameters != NULL) {
137  comm = ((NC_MPI_INFO*)parameters)->comm;
138  info = ((NC_MPI_INFO*)parameters)->info;
139  }
140  if((retval = MPI_File_open(comm,(char*)path,MPI_MODE_RDONLY,info,
141  &fh)) != MPI_SUCCESS)
142  {status = NC_EPARINIT; goto done;}
143  if((retval = MPI_File_read(fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR,
144  &mstatus)) != MPI_SUCCESS)
145  {status = NC_EPARINIT; goto done;}
146  if((retval = MPI_File_close(&fh)) != MPI_SUCCESS)
147  {status = NC_EPARINIT; goto done;}
148  } else
149 #endif /* USE_PARALLEL */
150  {
151  FILE *fp;
152  size_t i;
153 #ifdef HAVE_SYS_STAT_H
154  struct stat st;
155 #endif
156  if(path == NULL || strlen(path)==0)
157  {status = NC_EINVAL; goto done;}
158 
159  if (!(fp = fopen(path, "r")))
160  {status = errno; goto done;}
161 
162 #ifdef HAVE_SYS_STAT_H
163  /* The file must be at least MAGIC_NUMBER_LEN in size,
164  or otherwise the following fread will exhibit unexpected
165  behavior. */
166  if(!(fstat(fileno(fp),&st) == 0)) {
167  fclose(fp);
168  status = errno;
169  goto done;
170  }
171 
172  if(st.st_size < MAGIC_NUMBER_LEN) {
173  fclose(fp);
174  status = NC_ENOTNC;
175  goto done;
176  }
177 #endif
178 
179  i = fread(magic, MAGIC_NUMBER_LEN, 1, fp);
180  fclose(fp);
181  if(i == 0)
182  {status = NC_ENOTNC; goto done;}
183  if(i != 1)
184  {status = errno; goto done;}
185  }
186  } /* !inmemory */
187 
188  /* Look at the magic number */
189  status = NC_interpret_magic_number(magic,model,version,use_parallel);
190 
191 done:
192  return status;
193 }
194 
402 int
403 nc_create(const char *path, int cmode, int *ncidp)
404 {
405  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
406 }
407 
469 int
470 nc__create(const char *path, int cmode, size_t initialsz,
471  size_t *chunksizehintp, int *ncidp)
472 {
473  return NC_create(path, cmode, initialsz, 0,
474  chunksizehintp, 0, NULL, ncidp);
475 
476 }
485 int
486 nc__create_mp(const char *path, int cmode, size_t initialsz,
487  int basepe, size_t *chunksizehintp, int *ncidp)
488 {
489  return NC_create(path, cmode, initialsz, basepe,
490  chunksizehintp, 0, NULL, ncidp);
491 }
492 
607 int
608 nc_open(const char *path, int mode, int *ncidp)
609 {
610  return NC_open(path, mode, 0, NULL, 0, NULL, ncidp);
611 }
612 
664 int
665 nc__open(const char *path, int mode,
666  size_t *chunksizehintp, int *ncidp)
667 {
668  /* this API is for non-parallel access: TODO check for illegal cmode
669  * flags, such as NC_PNETCDF, NC_MPIIO, or NC_MPIPOSIX, before entering
670  * NC_open()? Note nc_open_par() also calls NC_open().
671  */
672  return NC_open(path, mode, 0, chunksizehintp, 0,
673  NULL, ncidp);
674 }
675 
721 int
722 nc_open_mem(const char* path, int mode, size_t size, void* memory, int* ncidp)
723 {
724 #ifdef USE_DISKLESS
725  NC_MEM_INFO meminfo;
726 
727  /* Sanity checks */
728  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
729  return NC_EINVAL;
730  if(mode & (NC_WRITE|NC_MPIIO|NC_MPIPOSIX|NC_MMAP))
731  return NC_EINVAL;
732  mode |= (NC_INMEMORY|NC_DISKLESS);
733  meminfo.size = size;
734  meminfo.memory = memory;
735  return NC_open(path, mode, 0, NULL, 0, &meminfo, ncidp);
736 #else
737  return NC_EDISKLESS;
738 #endif
739 }
740 
749 int
750 nc__open_mp(const char *path, int mode, int basepe,
751  size_t *chunksizehintp, int *ncidp)
752 {
753  return NC_open(path, mode, basepe, chunksizehintp,
754  0, NULL, ncidp);
755 }
756 
774 int
775 nc_inq_path(int ncid, size_t *pathlen, char *path)
776 {
777  NC* ncp;
778  int stat = NC_NOERR;
779  if ((stat = NC_check_id(ncid, &ncp)))
780  return stat;
781  if(ncp->path == NULL) {
782  if(pathlen) *pathlen = 0;
783  if(path) path[0] = '\0';
784  } else {
785  if (pathlen) *pathlen = strlen(ncp->path);
786  if (path) strcpy(path, ncp->path);
787  }
788  return stat;
789 }
790 
839 int
840 nc_redef(int ncid)
841 {
842  NC* ncp;
843  int stat = NC_check_id(ncid, &ncp);
844  if(stat != NC_NOERR) return stat;
845  return ncp->dispatch->redef(ncid);
846 }
847 
903 int
904 nc_enddef(int ncid)
905 {
906  int status = NC_NOERR;
907  NC *ncp;
908  status = NC_check_id(ncid, &ncp);
909  if(status != NC_NOERR) return status;
910  return ncp->dispatch->_enddef(ncid,0,1,0,1);
911 }
912 
994 int
995 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
996  size_t r_align)
997 {
998  NC* ncp;
999  int stat = NC_check_id(ncid, &ncp);
1000  if(stat != NC_NOERR) return stat;
1001  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1002 }
1003 
1071 int
1072 nc_sync(int ncid)
1073 {
1074  NC* ncp;
1075  int stat = NC_check_id(ncid, &ncp);
1076  if(stat != NC_NOERR) return stat;
1077  return ncp->dispatch->sync(ncid);
1078 }
1079 
1122 int
1123 nc_abort(int ncid)
1124 {
1125  NC* ncp;
1126  int stat = NC_check_id(ncid, &ncp);
1127  if(stat != NC_NOERR) return stat;
1128 
1129 #ifdef USE_REFCOUNT
1130  /* What to do if refcount > 0? */
1131  /* currently, forcibly abort */
1132  ncp->refcount = 0;
1133 #endif
1134 
1135  stat = ncp->dispatch->abort(ncid);
1136  del_from_NCList(ncp);
1137  free_NC(ncp);
1138  return stat;
1139 }
1140 
1181 int
1182 nc_close(int ncid)
1183 {
1184  NC* ncp;
1185  int stat = NC_check_id(ncid, &ncp);
1186  if(stat != NC_NOERR) return stat;
1187 
1188 #ifdef USE_REFCOUNT
1189  ncp->refcount--;
1190  if(ncp->refcount <= 0)
1191 #endif
1192  {
1193  stat = ncp->dispatch->close(ncid);
1194  /* Remove from the nc list */
1195  del_from_NCList(ncp);
1196  free_NC(ncp);
1197  }
1198  return stat;
1199 }
1200 
1299 int
1300 nc_set_fill(int ncid, int fillmode, int *old_modep)
1301 {
1302  NC* ncp;
1303  int stat = NC_check_id(ncid, &ncp);
1304  if(stat != NC_NOERR) return stat;
1305  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1306 }
1307 
1319 int
1320 nc_inq_base_pe(int ncid, int *pe)
1321 {
1322  NC* ncp;
1323  int stat = NC_check_id(ncid, &ncp);
1324  if(stat != NC_NOERR) return stat;
1325  return ncp->dispatch->inq_base_pe(ncid,pe);
1326 }
1327 
1339 int
1340 nc_set_base_pe(int ncid, int pe)
1341 {
1342  NC* ncp;
1343  int stat = NC_check_id(ncid, &ncp);
1344  if(stat != NC_NOERR) return stat;
1345  return ncp->dispatch->set_base_pe(ncid,pe);
1346 }
1347 
1366 int
1367 nc_inq_format(int ncid, int *formatp)
1368 {
1369  NC* ncp;
1370  int stat = NC_check_id(ncid, &ncp);
1371  if(stat != NC_NOERR) return stat;
1372  return ncp->dispatch->inq_format(ncid,formatp);
1373 }
1374 
1400 int
1401 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1402 {
1403  NC* ncp;
1404  int stat = NC_check_id(ncid, &ncp);
1405  if(stat != NC_NOERR) return stat;
1406  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1407 }
1408 
1453 int
1454 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1455 {
1456  NC* ncp;
1457  int stat = NC_check_id(ncid, &ncp);
1458  if(stat != NC_NOERR) return stat;
1459  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1460 }
1461 
1462 int
1463 nc_inq_nvars(int ncid, int *nvarsp)
1464 {
1465  NC* ncp;
1466  int stat = NC_check_id(ncid, &ncp);
1467  if(stat != NC_NOERR) return stat;
1468  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1469 }
1470 
1536 int
1537 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1538 {
1539  NC* ncp;
1540  int stat;
1541 
1542  /* Do a quick triage on xtype */
1543  if(xtype <= NC_NAT) return NC_EBADTYPE;
1544  /* See if the ncid is valid */
1545  stat = NC_check_id(ncid, &ncp);
1546  if(stat != NC_NOERR) { /* bad ncid; do what we can */
1547  /* For compatibility, we need to allow inq about
1548  atomic types, even if ncid is ill-defined */
1549  if(xtype <= ATOMICTYPEMAX3) {
1550  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1551  if(size) *size = NC_atomictypelen(xtype);
1552  return NC_NOERR;
1553  } else
1554  return NC_EBADTYPE;
1555  } else { /* have good ncid */
1556  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1557  }
1558 #if 0
1559  int maxtype;
1560  int format;
1561  nc_inq_format(ncid, &format);
1562  switch (format) {
1563  case NC_FORMAT_NETCDF4_CLASSIC: /*fall thru*/
1564  case NC_FORMAT_64BIT_OFFSET: /*fall thru*/
1565  case NC_FORMAT_CLASSIC: maxtype = ATOMICTYPEMAX3; break;
1566  case NC_FORMAT_NETCDF4: maxtype = ATOMICTYPEMAX4; break;
1567  case NC_FORMAT_CDF5: maxtype = ATOMICTYPEMAX5; break;
1568  default: return NC_EINVAL;
1569  }
1570 #endif
1571 }
1608 int
1609 NC_create(const char *path, int cmode, size_t initialsz,
1610  int basepe, size_t *chunksizehintp, int useparallel,
1611  void* parameters, int *ncidp)
1612 {
1613  int stat = NC_NOERR;
1614  NC* ncp = NULL;
1615  NC_Dispatch* dispatcher = NULL;
1616  /* Need three pieces of information for now */
1617  int model = NC_FORMATX_UNDEFINED; /* one of the NC_FORMATX values */
1618  int isurl = 0; /* dap or cdmremote or neither */
1619  int xcmode = 0; /* for implied cmode flags */
1620 
1621  /* Initialize the dispatch table. The function pointers in the
1622  * dispatch table will depend on how netCDF was built
1623  * (with/without netCDF-4, DAP, CDMREMOTE). */
1624  if(!NC_initialized)
1625  {
1626  if ((stat = nc_initialize()))
1627  return stat;
1628  }
1629 
1630 #ifdef USE_REFCOUNT
1631  /* If this path is already open, then fail */
1632  ncp = find_in_NCList_by_name(path);
1633  if(ncp != NULL)
1634  return NC_ENFILE;
1635 #endif
1636 
1637  if((isurl = NC_testurl(path)))
1638  model = NC_urlmodel(path);
1639 
1640  /* Look to the incoming cmode for hints */
1641  if(model == NC_FORMATX_UNDEFINED) {
1642 #ifdef USE_NETCDF4
1643  if((cmode & NC_NETCDF4) == NC_NETCDF4)
1644  model = NC_FORMATX_NC4;
1645  else
1646 #endif
1647 #ifdef USE_PNETCDF
1648  /* pnetcdf is used for parallel io on CDF-1, CDF-2, and CDF-5 */
1649  if((cmode & NC_MPIIO) == NC_MPIIO)
1650  model = NC_FORMATX_PNETCDF;
1651  else
1652 #endif
1653  {}
1654  }
1655  if(model == NC_FORMATX_UNDEFINED) {
1656  /* Check default format (not formatx) */
1657  int format = nc_get_default_format();
1658  switch (format) {
1659 #ifdef USE_NETCDF4
1660  case NC_FORMAT_NETCDF4:
1661  xcmode |= NC_NETCDF4;
1662  model = NC_FORMATX_NC4;
1663  break;
1665  xcmode |= NC_CLASSIC_MODEL;
1666  model = NC_FORMATX_NC4;
1667  break;
1668 #endif
1669  case NC_FORMAT_CDF5:
1670  xcmode |= NC_64BIT_DATA;
1671  model = NC_FORMATX_NC3;
1672  break;
1674  xcmode |= NC_64BIT_OFFSET;
1675  model = NC_FORMATX_NC3;
1676  break;
1677  case NC_FORMAT_CLASSIC:
1678  model = NC_FORMATX_NC3;
1679  break;
1680  default:
1681  model = NC_FORMATX_NC3;
1682  break;
1683  }
1684  }
1685 
1686  /* Add inferred flags */
1687  cmode |= xcmode;
1688 
1689  /* Clean up illegal combinations */
1691  cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/
1692 
1693  if((cmode & NC_MPIIO) && (cmode & NC_MPIPOSIX))
1694  return NC_EINVAL;
1695 
1696  if (!(dispatcher = NC_get_dispatch_override()))
1697  {
1698 
1699  /* Figure out what dispatcher to use */
1700 #ifdef USE_NETCDF4
1701  if(model == (NC_FORMATX_NC4))
1702  dispatcher = NC4_dispatch_table;
1703  else
1704 #endif /*USE_NETCDF4*/
1705 #ifdef USE_PNETCDF
1706  if(model == (NC_FORMATX_PNETCDF))
1707  dispatcher = NCP_dispatch_table;
1708  else
1709 #endif
1710  if(model == (NC_FORMATX_NC3))
1711  dispatcher = NC3_dispatch_table;
1712  else
1713  return NC_ENOTNC;
1714  }
1715 
1716  /* Create the NC* instance and insert its dispatcher */
1717  stat = new_NC(dispatcher,path,cmode,&ncp);
1718  if(stat) return stat;
1719 
1720  /* Add to list of known open files and define ext_ncid */
1721  add_to_NCList(ncp);
1722 
1723 #ifdef USE_REFCOUNT
1724  /* bump the refcount */
1725  ncp->refcount++;
1726 #endif
1727 
1728  /* Assume create will fill in remaining ncp fields */
1729  if ((stat = dispatcher->create(path, cmode, initialsz, basepe, chunksizehintp,
1730  useparallel, parameters, dispatcher, ncp))) {
1731  del_from_NCList(ncp); /* oh well */
1732  free_NC(ncp);
1733  } else {
1734  if(ncidp)*ncidp = ncp->ext_ncid;
1735  }
1736  return stat;
1737 }
1738 
1754 int
1755 NC_open(const char *path, int cmode,
1756  int basepe, size_t *chunksizehintp,
1757  int useparallel, void* parameters,
1758  int *ncidp)
1759 {
1760  int stat = NC_NOERR;
1761  NC* ncp = NULL;
1762  NC_Dispatch* dispatcher = NULL;
1763  int inmemory = ((cmode & NC_INMEMORY) == NC_INMEMORY);
1764  /* Need pieces of information for now to decide model*/
1765  int model = 0;
1766  int isurl = 0;
1767  int version = 0;
1768  int flags = 0;
1769 
1770  if(!NC_initialized) {
1771  stat = nc_initialize();
1772  if(stat) return stat;
1773  }
1774 
1775 #ifdef USE_REFCOUNT
1776  /* If this path is already open, then bump the refcount and return it */
1777  ncp = find_in_NCList_by_name(path);
1778  if(ncp != NULL) {
1779  ncp->refcount++;
1780  if(ncidp) *ncidp = ncp->ext_ncid;
1781  return NC_NOERR;
1782  }
1783 #endif
1784 
1785  if(!inmemory) {
1786  isurl = NC_testurl(path);
1787  if(isurl)
1788  model = NC_urlmodel(path);
1789  }
1790  if(model == 0) {
1791  version = 0;
1792  /* Try to find dataset type */
1793  if(useparallel) flags |= NC_MPIIO;
1794  if(inmemory) flags |= NC_INMEMORY;
1795  stat = NC_check_file_type(path,flags,parameters,&model,&version);
1796  if(stat == NC_NOERR) {
1797  if(model == 0)
1798  return NC_ENOTNC;
1799  } else /* presumably not a netcdf file */
1800  return stat;
1801  }
1802 
1803  if(model == 0) {
1804  fprintf(stderr,"Model == 0\n");
1805  return NC_ENOTNC;
1806  }
1807 
1808  /* Force flag consistentcy */
1809  if(model == NC_FORMATX_NC4)
1810  cmode |= NC_NETCDF4;
1811  else if(model == NC_FORMATX_NC3) {
1812  cmode &= ~NC_NETCDF4; /* must be netcdf-3 (CDF-1, CDF-2, CDF-5) */
1813  /* User may want to open file using the pnetcdf library */
1814  if(cmode & NC_PNETCDF) {
1815  /* dispatch is determined by cmode, rather than file format */
1816  model = NC_FORMATX_PNETCDF;
1817  }
1818  /* For opening an existing file, flags NC_64BIT_OFFSET and NC_64BIT_DATA
1819  * will be ignored, as the file is already in either CDF-1, 2, or 5
1820  * format. However, below we add the file format info to cmode so the
1821  * internal netcdf file open subroutine knows what file format to open.
1822  * The mode will be saved in ncp->mode, to be used by
1823  * nc_inq_format_extended() to report the file format.
1824  * See NC3_inq_format_extended() in libsrc/nc3internal.c for example.
1825  */
1826  if(version == 2) cmode |= NC_64BIT_OFFSET;
1827  else if(version == 5) {
1828  cmode |= NC_64BIT_DATA;
1829  cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/
1830  }
1831  } else if(model == NC_FORMATX_PNETCDF) {
1832  cmode &= ~(NC_NETCDF4|NC_64BIT_OFFSET);
1833  cmode |= NC_64BIT_DATA;
1834  }
1835 
1836  if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX))
1837  return NC_EINVAL;
1838 
1839  /* override any other table choice */
1840  dispatcher = NC_get_dispatch_override();
1841  if(dispatcher != NULL) goto havetable;
1842 
1843  /* Figure out what dispatcher to use */
1844 #if defined(USE_CDMREMOTE)
1845  if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR))
1846  dispatcher = NCCR_dispatch_table;
1847  else
1848 #endif
1849 #if defined(USE_DAP)
1850  if(model == (NC_FORMATX_DAP2))
1851  dispatcher = NCD2_dispatch_table;
1852  else
1853 #endif
1854 #if defined(USE_PNETCDF)
1855  if(model == (NC_FORMATX_PNETCDF))
1856  dispatcher = NCP_dispatch_table;
1857  else
1858 #endif
1859 #if defined(USE_NETCDF4)
1860  if(model == (NC_FORMATX_NC4))
1861  dispatcher = NC4_dispatch_table;
1862  else
1863 #endif
1864  if(model == (NC_FORMATX_NC3))
1865  dispatcher = NC3_dispatch_table;
1866  else
1867  return NC_ENOTNC;
1868 
1869 havetable:
1870 
1871  /* Create the NC* instance and insert its dispatcher */
1872  stat = new_NC(dispatcher,path,cmode,&ncp);
1873  if(stat) return stat;
1874 
1875  /* Add to list of known open files */
1876  add_to_NCList(ncp);
1877 
1878 #ifdef USE_REFCOUNT
1879  /* bump the refcount */
1880  ncp->refcount++;
1881 #endif
1882 
1883  /* Assume open will fill in remaining ncp fields */
1884  stat = dispatcher->open(path, cmode, basepe, chunksizehintp,
1885  useparallel, parameters, dispatcher, ncp);
1886  if(stat == NC_NOERR) {
1887  if(ncidp) *ncidp = ncp->ext_ncid;
1888  } else {
1889  del_from_NCList(ncp);
1890  free_NC(ncp);
1891  }
1892  return stat;
1893 }
1894 
1895 /*Provide an internal function for generating pseudo file descriptors
1896  for systems that are not file based (e.g. dap, memio).
1897 */
1898 
1899 /* Static counter for pseudo file descriptors (incremented) */
1900 static int pseudofd = 0;
1901 
1902 /* Create a pseudo file descriptor that does not
1903  overlap real file descriptors
1904 */
1905 int
1906 nc__pseudofd(void)
1907 {
1908  if(pseudofd == 0) {
1909  int maxfd = 32767; /* default */
1910 #ifdef HAVE_GETRLIMIT
1911  struct rlimit rl;
1912  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
1913  if(rl.rlim_max != RLIM_INFINITY)
1914  maxfd = (int)rl.rlim_max;
1915  if(rl.rlim_cur != RLIM_INFINITY)
1916  maxfd = (int)rl.rlim_cur;
1917  }
1918  pseudofd = maxfd+1;
1919 #endif
1920  }
1921  return pseudofd++;
1922 }
#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:665
#define NC_ENFILE
Too many netcdfs open.
Definition: netcdf.h:323
#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:840
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:995
#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:1367
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1454
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:1401
#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:1182
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:456
#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:1300
#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:1537
#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
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:109
#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:470
#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&#39;s file...
Definition: dfile.c:775
#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:608
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:904
#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:722
#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:1072
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:403
#define NC_MPIPOSIX
Turn on MPI POSIX I/O.
Definition: netcdf.h:161

Return to the Main Unidata NetCDF page.
Generated on Tue May 3 2016 08:56:00 for NetCDF. NetCDF is a Unidata library.