NetCDF 4.9.0
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 "ncpathmgr.h"
39#include "fbits.h"
40
41#undef DEBUG
42
43#ifndef nulldup
44 #define nulldup(s) ((s)?strdup(s):NULL)
45#endif
46
47
48extern int NC_initialized;
50/* User-defined formats. */
51NC_Dispatch *UDF0_dispatch_table = NULL;
52char UDF0_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
53NC_Dispatch *UDF1_dispatch_table = NULL;
54char UDF1_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
55
56/**************************************************/
57
58
124int
125nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
126{
127 /* Check inputs. */
128 if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
129 return NC_EINVAL;
130 if (!dispatch_table)
131 return NC_EINVAL;
132 if (magic_number && strlen(magic_number) > NC_MAX_MAGIC_NUMBER_LEN)
133 return NC_EINVAL;
134
135 /* Check the version of the dispatch table provided. */
136 if (dispatch_table->dispatch_version != NC_DISPATCH_VERSION)
137 return NC_EINVAL;
138
139 /* Retain a pointer to the dispatch_table and a copy of the magic
140 * number, if one was provided. */
141 switch(mode_flag)
142 {
143 case NC_UDF0:
144 UDF0_dispatch_table = dispatch_table;
145 if (magic_number)
146 strncpy(UDF0_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
147 break;
148 case NC_UDF1:
149 UDF1_dispatch_table = dispatch_table;
150 if (magic_number)
151 strncpy(UDF1_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
152 break;
153 }
154
155 return NC_NOERR;
156}
157
174int
175nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
176{
177 /* Check inputs. */
178 if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
179 return NC_EINVAL;
180
181 switch(mode_flag)
182 {
183 case NC_UDF0:
184 if (dispatch_table)
185 *dispatch_table = UDF0_dispatch_table;
186 if (magic_number)
187 strncpy(magic_number, UDF0_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
188 break;
189 case NC_UDF1:
190 if (dispatch_table)
191 *dispatch_table = UDF1_dispatch_table;
192 if (magic_number)
193 strncpy(magic_number, UDF1_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
194 break;
195 }
196
197 return NC_NOERR;
198}
199
393int
394nc_create(const char *path, int cmode, int *ncidp)
395{
396 return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
397}
398
465int
466nc__create(const char *path, int cmode, size_t initialsz,
467 size_t *chunksizehintp, int *ncidp)
468{
469 return NC_create(path, cmode, initialsz, 0,
470 chunksizehintp, 0, NULL, ncidp);
471}
472
511int
512nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
513{
514 if(mode & NC_MMAP) return NC_EINVAL;
515 mode |= NC_INMEMORY; /* Specifically, do not set NC_DISKLESS */
516 return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
517}
518
538int
539nc__create_mp(const char *path, int cmode, size_t initialsz,
540 int basepe, size_t *chunksizehintp, int *ncidp)
541{
542 return NC_create(path, cmode, initialsz, basepe,
543 chunksizehintp, 0, NULL, ncidp);
544}
545
659int
660nc_open(const char *path, int omode, int *ncidp)
661{
662 return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
663}
664
716int
717nc__open(const char *path, int omode,
718 size_t *chunksizehintp, int *ncidp)
719{
720 /* this API is for non-parallel access.
721 * Note nc_open_par() also calls NC_open().
722 */
723 return NC_open(path, omode, 0, chunksizehintp, 0, NULL, ncidp);
724}
725
771int
772nc_open_mem(const char* path, int omode, size_t size, void* memory, int* ncidp)
773{
774 NC_memio meminfo;
775
776 /* Sanity checks */
777 if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
778 return NC_EINVAL;
779 if(omode & (NC_WRITE|NC_MMAP))
780 return NC_EINVAL;
781 omode |= (NC_INMEMORY); /* Note: NC_INMEMORY and NC_DISKLESS are mutually exclusive*/
782 meminfo.size = size;
783 meminfo.memory = memory;
784 meminfo.flags = NC_MEMIO_LOCKED;
785 return NC_open(path, omode, 0, NULL, 0, &meminfo, ncidp);
786}
787
836int
837nc_open_memio(const char* path, int omode, NC_memio* params, int* ncidp)
838{
839 /* Sanity checks */
840 if(path == NULL || params == NULL)
841 return NC_EINVAL;
842 if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
843 return NC_EINVAL;
844
845 if(omode & NC_MMAP)
846 return NC_EINVAL;
847 omode |= (NC_INMEMORY);
848 return NC_open(path, omode, 0, NULL, 0, params, ncidp);
849}
850
869int
870nc__open_mp(const char *path, int omode, int basepe,
871 size_t *chunksizehintp, int *ncidp)
872{
873 return NC_open(path, omode, basepe, chunksizehintp, 0, NULL, ncidp);
874}
875
893int
894nc_inq_path(int ncid, size_t *pathlen, char *path)
895{
896 NC* ncp;
897 int stat = NC_NOERR;
898 if ((stat = NC_check_id(ncid, &ncp)))
899 return stat;
900 if(ncp->path == NULL) {
901 if(pathlen) *pathlen = 0;
902 if(path) path[0] = '\0';
903 } else {
904 if (pathlen) *pathlen = strlen(ncp->path);
905 if (path) strcpy(path, ncp->path);
906 }
907 return stat;
908}
909
958int
959nc_redef(int ncid)
960{
961 NC* ncp;
962 int stat = NC_check_id(ncid, &ncp);
963 if(stat != NC_NOERR) return stat;
964 return ncp->dispatch->redef(ncid);
965}
966
1022int
1023nc_enddef(int ncid)
1024{
1025 int status = NC_NOERR;
1026 NC *ncp;
1027 status = NC_check_id(ncid, &ncp);
1028 if(status != NC_NOERR) return status;
1029 return ncp->dispatch->_enddef(ncid,0,1,0,1);
1030}
1031
1113int
1114nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1115 size_t r_align)
1116{
1117 NC* ncp;
1118 int stat = NC_check_id(ncid, &ncp);
1119 if(stat != NC_NOERR) return stat;
1120 return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1121}
1122
1190int
1191nc_sync(int ncid)
1192{
1193 NC* ncp;
1194 int stat = NC_check_id(ncid, &ncp);
1195 if(stat != NC_NOERR) return stat;
1196 return ncp->dispatch->sync(ncid);
1197}
1198
1242int
1243nc_abort(int ncid)
1244{
1245 NC* ncp;
1246 int stat = NC_check_id(ncid, &ncp);
1247 if(stat != NC_NOERR) return stat;
1248
1249 stat = ncp->dispatch->abort(ncid);
1250 del_from_NCList(ncp);
1251 free_NC(ncp);
1252 return stat;
1253}
1254
1295int
1296nc_close(int ncid)
1297{
1298 NC* ncp;
1299 int stat = NC_check_id(ncid, &ncp);
1300 if(stat != NC_NOERR) return stat;
1301
1302 stat = ncp->dispatch->close(ncid,NULL);
1303 /* Remove from the nc list */
1304 if (!stat)
1305 {
1306 del_from_NCList(ncp);
1307 free_NC(ncp);
1308 }
1309 return stat;
1310}
1311
1354int
1355nc_close_memio(int ncid, NC_memio* memio)
1356{
1357 NC* ncp;
1358 int stat = NC_check_id(ncid, &ncp);
1359 if(stat != NC_NOERR) return stat;
1360
1361 stat = ncp->dispatch->close(ncid,memio);
1362 /* Remove from the nc list */
1363 if (!stat)
1364 {
1365 del_from_NCList(ncp);
1366 free_NC(ncp);
1367 }
1368 return stat;
1369}
1370
1469int
1470nc_set_fill(int ncid, int fillmode, int *old_modep)
1471{
1472 NC* ncp;
1473 int stat = NC_check_id(ncid, &ncp);
1474 if(stat != NC_NOERR) return stat;
1475 return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1476}
1477
1492int
1493nc_inq_base_pe(int ncid, int *pe)
1494{
1495 NC* ncp;
1496 int stat = NC_check_id(ncid, &ncp);
1497 if(stat != NC_NOERR) return stat;
1498 if (pe) *pe = 0;
1499 return NC_NOERR;
1500}
1501
1516int
1517nc_set_base_pe(int ncid, int pe)
1518{
1519 NC* ncp;
1520 int stat = NC_check_id(ncid, &ncp);
1521 if(stat != NC_NOERR) return stat;
1522 return NC_NOERR;
1523}
1524
1542int
1543nc_inq_format(int ncid, int *formatp)
1544{
1545 NC* ncp;
1546 int stat = NC_check_id(ncid, &ncp);
1547 if(stat != NC_NOERR) return stat;
1548 return ncp->dispatch->inq_format(ncid,formatp);
1549}
1550
1577int
1578nc_inq_format_extended(int ncid, int *formatp, int *modep)
1579{
1580 NC* ncp;
1581 int stat = NC_check_id(ncid, &ncp);
1582 if(stat != NC_NOERR) return stat;
1583 return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1584}
1585
1630int
1631nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1632{
1633 NC* ncp;
1634 int stat = NC_check_id(ncid, &ncp);
1635 if(stat != NC_NOERR) return stat;
1636 return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1637}
1638
1649int
1650nc_inq_nvars(int ncid, int *nvarsp)
1651{
1652 NC* ncp;
1653 int stat = NC_check_id(ncid, &ncp);
1654 if(stat != NC_NOERR) return stat;
1655 return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1656}
1657
1723int
1724nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1725{
1726 NC* ncp;
1727 int stat;
1728
1729 /* Do a quick triage on xtype */
1730 if(xtype <= NC_NAT) return NC_EBADTYPE;
1731 /* For compatibility, we need to allow inq about
1732 atomic types, even if ncid is ill-defined */
1733 if(xtype <= ATOMICTYPEMAX4) {
1734 if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1735 if(size) *size = NC_atomictypelen(xtype);
1736 return NC_NOERR;
1737 }
1738 /* Apparently asking about a user defined type, so we need
1739 a valid ncid */
1740 stat = NC_check_id(ncid, &ncp);
1741 if(stat != NC_NOERR) /* bad ncid */
1742 return NC_EBADTYPE;
1743 /* have good ncid */
1744 return ncp->dispatch->inq_type(ncid,xtype,name,size);
1745}
1746
1763static int
1765{
1766 int mode_format;
1767 int mmap = 0;
1768 int inmemory = 0;
1769 int diskless = 0;
1770
1771 /* This is a clever check to see if more than one format bit is
1772 * set. */
1773 mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
1774 (mode & NC_CDF5);
1775 if (mode_format && (mode_format & (mode_format - 1)))
1776 return NC_EINVAL;
1777
1778 mmap = ((mode & NC_MMAP) == NC_MMAP);
1779 inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
1780 diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
1781
1782 /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1783 if(diskless && inmemory) return NC_EDISKLESS;
1784 if(diskless && mmap) return NC_EDISKLESS;
1785 if(inmemory && mmap) return NC_EINMEMORY;
1786
1787 /* mmap is not allowed for netcdf-4 */
1788 if(mmap && (mode & NC_NETCDF4)) return NC_EINVAL;
1789
1790#ifndef USE_NETCDF4
1791 /* If the user asks for a netCDF-4 file, and the library was built
1792 * without netCDF-4, then return an error.*/
1793 if (mode & NC_NETCDF4)
1794 return NC_ENOTBUILT;
1795#endif /* USE_NETCDF4 undefined */
1796
1797 /* Well I guess there is some sanity in the world after all. */
1798 return NC_NOERR;
1799}
1800
1828int
1829NC_create(const char *path0, int cmode, size_t initialsz,
1830 int basepe, size_t *chunksizehintp, int useparallel,
1831 void* parameters, int *ncidp)
1832{
1833 int stat = NC_NOERR;
1834 NC* ncp = NULL;
1835 const NC_Dispatch* dispatcher = NULL;
1836 char* path = NULL;
1837 NCmodel model;
1838 char* newpath = NULL;
1839
1840 TRACE(nc_create);
1841 if(path0 == NULL)
1842 return NC_EINVAL;
1843
1844 /* Check mode flag for sanity. */
1845 if ((stat = check_create_mode(cmode)))
1846 return stat;
1847
1848 /* Initialize the library. The available dispatch tables
1849 * will depend on how netCDF was built
1850 * (with/without netCDF-4, DAP, CDMREMOTE). */
1851 if(!NC_initialized)
1852 {
1853 if ((stat = nc_initialize()))
1854 return stat;
1855 }
1856
1857 {
1858 /* Skip past any leading whitespace in path */
1859 const unsigned char* p;
1860 for(p=(const unsigned char*)path0;*p;p++) {if(*p > ' ') break;}
1861 path = nulldup((const char*)p);
1862 }
1863
1864 memset(&model,0,sizeof(model));
1865 newpath = NULL;
1866 if((stat = NC_infermodel(path,&cmode,1,useparallel,NULL,&model,&newpath))) {
1867 nullfree(newpath);
1868 goto done;
1869 }
1870 if(newpath) {
1871 nullfree(path);
1872 path = newpath;
1873 newpath = NULL;
1874 }
1875
1876 assert(model.format != 0 && model.impl != 0);
1877
1878 /* Now, check for NC_ENOTBUILT cases limited to create (so e.g. HDF4 is not listed) */
1879#ifndef USE_HDF5
1880 if (model.impl == NC_FORMATX_NC4)
1881 {stat = NC_ENOTBUILT; goto done;}
1882#endif
1883#ifndef USE_PNETCDF
1884 if (model.impl == NC_FORMATX_PNETCDF)
1885 {stat = NC_ENOTBUILT; goto done;}
1886#endif
1887#ifndef ENABLE_CDF5
1888 if (model.impl == NC_FORMATX_NC3 && (cmode & NC_64BIT_DATA))
1889 {stat = NC_ENOTBUILT; goto done;}
1890#endif
1891
1892 /* Figure out what dispatcher to use */
1893 switch (model.impl) {
1894#ifdef USE_HDF5
1895 case NC_FORMATX_NC4:
1896 dispatcher = HDF5_dispatch_table;
1897 break;
1898#endif
1899#ifdef USE_PNETCDF
1900 case NC_FORMATX_PNETCDF:
1901 dispatcher = NCP_dispatch_table;
1902 break;
1903#endif
1904#ifdef USE_NETCDF4
1905 case NC_FORMATX_UDF0:
1906 dispatcher = UDF0_dispatch_table;
1907 break;
1908 case NC_FORMATX_UDF1:
1909 dispatcher = UDF1_dispatch_table;
1910 break;
1911#endif /* USE_NETCDF4 */
1912#ifdef ENABLE_NCZARR
1913 case NC_FORMATX_NCZARR:
1914 dispatcher = NCZ_dispatch_table;
1915 break;
1916#endif
1917 case NC_FORMATX_NC3:
1918 dispatcher = NC3_dispatch_table;
1919 break;
1920 default:
1921 return NC_ENOTNC;
1922 }
1923
1924 /* Create the NC* instance and insert its dispatcher and model */
1925 if((stat = new_NC(dispatcher,path,cmode,&ncp))) goto done;
1926
1927 /* Add to list of known open files and define ext_ncid */
1928 add_to_NCList(ncp);
1929
1930 /* Assume create will fill in remaining ncp fields */
1931 if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp,
1932 parameters, dispatcher, ncp->ext_ncid))) {
1933 del_from_NCList(ncp); /* oh well */
1934 free_NC(ncp);
1935 } else {
1936 if(ncidp)*ncidp = ncp->ext_ncid;
1937 }
1938done:
1939 nullfree(path);
1940 return stat;
1941}
1942
1966int
1967NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
1968 int useparallel, void* parameters, int *ncidp)
1969{
1970 int stat = NC_NOERR;
1971 NC* ncp = NULL;
1972 const NC_Dispatch* dispatcher = NULL;
1973 int inmemory = 0;
1974 int diskless = 0;
1975 int mmap = 0;
1976 char* path = NULL;
1977 NCmodel model;
1978 char* newpath = NULL;
1979
1980 TRACE(nc_open);
1981 if(!NC_initialized) {
1982 stat = nc_initialize();
1983 if(stat) return stat;
1984 }
1985
1986 /* Check inputs. */
1987 if (!path0)
1988 return NC_EINVAL;
1989
1990 /* Capture the inmemory related flags */
1991 mmap = ((omode & NC_MMAP) == NC_MMAP);
1992 diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
1993 inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
1994
1995 /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1996 if(diskless && inmemory) {stat = NC_EDISKLESS; goto done;}
1997 if(diskless && mmap) {stat = NC_EDISKLESS; goto done;}
1998 if(inmemory && mmap) {stat = NC_EINMEMORY; goto done;}
1999
2000 /* mmap is not allowed for netcdf-4 */
2001 if(mmap && (omode & NC_NETCDF4)) {stat = NC_EINVAL; goto done;}
2002
2003 /* Attempt to do file path conversion: note that this will do
2004 nothing if path is a 'file:...' url, so it will need to be
2005 repeated in protocol code (e.g. libdap2, libdap4, etc).
2006 */
2007
2008 {
2009 /* Skip past any leading whitespace in path */
2010 const char* p;
2011 for(p=(const char*)path0;*p;p++) {if(*p < 0 || *p > ' ') break;}
2012 path = nulldup(p);
2013 }
2014
2015 memset(&model,0,sizeof(model));
2016 /* Infer model implementation and format, possibly by reading the file */
2017 if((stat = NC_infermodel(path,&omode,0,useparallel,parameters,&model,&newpath)))
2018 goto done;
2019 if(newpath) {
2020 nullfree(path);
2021 path = newpath;
2022 newpath = NULL;
2023 }
2024
2025 /* Still no implementation, give up */
2026 if(model.impl == 0) {
2027#ifdef DEBUG
2028 fprintf(stderr,"implementation == 0\n");
2029#endif
2030 {stat = NC_ENOTNC; goto done;}
2031 }
2032
2033 /* Suppress unsupported formats */
2034 /* (should be more compact, table-driven, way to do this) */
2035 {
2036 int hdf5built = 0;
2037 int hdf4built = 0;
2038 int cdf5built = 0;
2039 int udf0built = 0;
2040 int udf1built = 0;
2041 int nczarrbuilt = 0;
2042#ifdef USE_NETCDF4
2043 hdf5built = 1;
2044#ifdef USE_HDF4
2045 hdf4built = 1;
2046#endif
2047#endif
2048#ifdef ENABLE_CDF5
2049 cdf5built = 1;
2050#endif
2051#ifdef ENABLE_NCZARR
2052 nczarrbuilt = 1;
2053#endif
2054 if(UDF0_dispatch_table != NULL)
2055 udf0built = 1;
2056 if(UDF1_dispatch_table != NULL)
2057 udf1built = 1;
2058
2059 if(!hdf5built && model.impl == NC_FORMATX_NC4)
2060 {stat = NC_ENOTBUILT; goto done;}
2061 if(!hdf4built && model.impl == NC_FORMATX_NC_HDF4)
2062 {stat = NC_ENOTBUILT; goto done;}
2063 if(!cdf5built && model.impl == NC_FORMATX_NC3 && model.format == NC_FORMAT_CDF5)
2064 {stat = NC_ENOTBUILT; goto done;}
2065 if(!nczarrbuilt && model.impl == NC_FORMATX_NCZARR)
2066 {stat = NC_ENOTBUILT; goto done;}
2067 if(!udf0built && model.impl == NC_FORMATX_UDF0)
2068 {stat = NC_ENOTBUILT; goto done;}
2069 if(!udf1built && model.impl == NC_FORMATX_UDF1)
2070 {stat = NC_ENOTBUILT; goto done;}
2071 }
2072 /* Figure out what dispatcher to use */
2073 if (!dispatcher) {
2074 switch (model.impl) {
2075#ifdef ENABLE_DAP
2076 case NC_FORMATX_DAP2:
2077 dispatcher = NCD2_dispatch_table;
2078 break;
2079#endif
2080#ifdef ENABLE_DAP4
2081 case NC_FORMATX_DAP4:
2082 dispatcher = NCD4_dispatch_table;
2083 break;
2084#endif
2085#ifdef ENABLE_NCZARR
2086 case NC_FORMATX_NCZARR:
2087 dispatcher = NCZ_dispatch_table;
2088 break;
2089#endif
2090#ifdef USE_PNETCDF
2091 case NC_FORMATX_PNETCDF:
2092 dispatcher = NCP_dispatch_table;
2093 break;
2094#endif
2095#ifdef USE_HDF5
2096 case NC_FORMATX_NC4:
2097 dispatcher = HDF5_dispatch_table;
2098 break;
2099#endif
2100#ifdef USE_HDF4
2101 case NC_FORMATX_NC_HDF4:
2102 dispatcher = HDF4_dispatch_table;
2103 break;
2104#endif
2105#ifdef USE_NETCDF4
2106 case NC_FORMATX_UDF0:
2107 dispatcher = UDF0_dispatch_table;
2108 break;
2109 case NC_FORMATX_UDF1:
2110 dispatcher = UDF1_dispatch_table;
2111 break;
2112#endif /* USE_NETCDF4 */
2113 case NC_FORMATX_NC3:
2114 dispatcher = NC3_dispatch_table;
2115 break;
2116 default:
2117 stat = NC_ENOTNC;
2118 goto done;
2119 }
2120 }
2121
2122
2123 /* If we can't figure out what dispatch table to use, give up. */
2124 if (!dispatcher) {stat = NC_ENOTNC; goto done;}
2125
2126 /* Create the NC* instance and insert its dispatcher */
2127 if((stat = new_NC(dispatcher,path,omode,&ncp))) goto done;
2128
2129 /* Add to list of known open files. This assigns an ext_ncid. */
2130 add_to_NCList(ncp);
2131
2132 /* Assume open will fill in remaining ncp fields */
2133 stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2134 parameters, dispatcher, ncp->ext_ncid);
2135 if(stat == NC_NOERR) {
2136 if(ncidp) *ncidp = ncp->ext_ncid;
2137 } else {
2138 del_from_NCList(ncp);
2139 free_NC(ncp);
2140 }
2141
2142done:
2143 nullfree(path);
2144 nullfree(newpath);
2145 return stat;
2146}
2147
2148/*Provide an internal function for generating pseudo file descriptors
2149 for systems that are not file based (e.g. dap, memio).
2150*/
2151
2153static int pseudofd = 0;
2154
2162int
2163nc__pseudofd(void)
2164{
2165 if(pseudofd == 0) {
2166#ifdef HAVE_GETRLIMIT
2167 int maxfd = 32767; /* default */
2168 struct rlimit rl;
2169 if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2170 if(rl.rlim_max != RLIM_INFINITY)
2171 maxfd = (int)rl.rlim_max;
2172 if(rl.rlim_cur != RLIM_INFINITY)
2173 maxfd = (int)rl.rlim_cur;
2174 }
2175 pseudofd = maxfd+1;
2176#endif
2177 }
2178 return pseudofd++;
2179}
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition: dfile.c:1650
int NC_initialized
True when dispatch table is initialized.
static int check_create_mode(int mode)
Check the create mode parameter for sanity.
Definition: dfile.c:1764
int nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
Inquire about user-defined format.
Definition: dfile.c:175
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:466
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1296
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1243
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:394
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1631
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:1578
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:1355
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:1114
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1470
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:512
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:717
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:894
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:772
int nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
Add handling of user-defined format.
Definition: dfile.c:125
int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Inquire about a type.
Definition: dfile.c:1724
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:1023
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:959
int nc_open(const char *path, int omode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:660
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:837
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:1543
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
Definition: dfile.c:1191
#define NC_MAX_MAGIC_NUMBER_LEN
Max len of user-defined format magic number.
Definition: netcdf.h:169
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition: netcdf.h:153
#define NC_UDF0
User-defined format 0.
Definition: netcdf.h:137
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:509
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:245
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:410
#define NC_MMAP
Definition: netcdf.h:132
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:163
#define NC_CDF5
Alias NC_CDF5 to NC_64BIT_DATA.
Definition: netcdf.h:135
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:216
#define NC_FORMATX_NCZARR
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:225
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:424
#define NC_NAT
Not A Type.
Definition: netcdf.h:34
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
Definition: netcdf.h:141
#define NC_EINMEMORY
In-memory file error.
Definition: netcdf.h:516
#define NC_FORMATX_UDF1
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:224
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:220
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:191
#define NC_FORMATX_NC_HDF4
netCDF-4 subset of HDF4
Definition: netcdf.h:219
#define NC_WRITE
Set read-write access for nc_open().
Definition: netcdf.h:127
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:222
#define NC_FORMATX_UDF0
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:223
#define NC_DISKLESS
Use diskless file.
Definition: netcdf.h:131
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:221
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:378
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:281
#define NC_NOERR
No Error.
Definition: netcdf.h:368
#define NC_64BIT_DATA
CDF-5 format: classic model but 64 bit dimensions and sizes.
Definition: netcdf.h:134
#define NC_ENOTBUILT
Attempt to use feature that was not turned on when netCDF was built.
Definition: netcdf.h:508
#define NC_UDF1
User-defined format 1.
Definition: netcdf.h:138
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:25
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:218
Main header file for in-memory (diskless) functionality.