netCDF  4.2.1.1
/usr/src/RPM/BUILD/libnetcdf7-seq-4.2.1.1/libdispatch/dfile.c
Go to the documentation of this file.
00001 
00011 #include "config.h"
00012 #include <stdlib.h>
00013 #ifdef HAVE_SYS_RESOURCE_H
00014 #include <sys/resource.h>
00015 #endif
00016 #ifdef HAVE_SYS_TYPES_H
00017 #include <sys/types.h>
00018 #endif
00019 #ifdef HAVE_SYS_STAT_H
00020 #include <sys/stat.h>
00021 #endif
00022 #ifdef HAVE_FCNTL_H
00023 #include <fcntl.h>
00024 #endif
00025 #include "ncdispatch.h"
00026 
00027 static int nc_initialized = 0;
00028 
00066 size_t* NC_coord_zero;
00067 size_t* NC_coord_one;
00068 
00069 static void
00070 nc_local_initialize(void)
00071 {
00072     int i;
00073     NC_coord_zero = (size_t*)malloc(sizeof(size_t)*NC_MAX_VAR_DIMS);
00074     if(NC_coord_zero == NULL) abort();
00075     NC_coord_one = (size_t*)malloc(sizeof(size_t)*NC_MAX_VAR_DIMS);
00076     if(NC_coord_one == NULL) abort();
00077     for(i=0;i<NC_MAX_VAR_DIMS;i++) {
00078         NC_coord_one[i] = 1;
00079         NC_coord_zero[i] = 0;
00080     }
00081 }
00082 
00083 static int
00084 NC_check_file_type(const char *path, int use_parallel, void *mpi_info,
00085                    int *cdf, int *hdf)
00086 {
00087    char magic[MAGIC_NUMBER_LEN];
00088     
00089    *hdf = 0; *cdf = 0;
00090 
00091    /* Get the 4-byte magic from the beginning of the file. Don't use posix
00092     * for parallel, use the MPI functions instead. */
00093 #ifdef USE_PARALLEL_MPIO
00094    if (use_parallel) 
00095    {
00096       MPI_File fh;
00097       MPI_Status status;
00098       int retval;
00099       MPI_Comm comm = 0;
00100       MPI_Info info = 0;
00101 
00102       if(mpi_info != NULL) {
00103          comm = ((NC_MPI_INFO*)mpi_info)->comm;
00104          info = ((NC_MPI_INFO*)mpi_info)->info;
00105       }
00106       if((retval = MPI_File_open(comm, (char *)path, MPI_MODE_RDONLY,info, 
00107                                  &fh)) != MPI_SUCCESS)
00108          return NC_EPARINIT;
00109       if((retval = MPI_File_read(fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR,
00110                                  &status)) != MPI_SUCCESS)
00111          return NC_EPARINIT;
00112       if((retval = MPI_File_close(&fh)) != MPI_SUCCESS)
00113          return NC_EPARINIT;
00114    } else
00115 #endif /* USE_PARALLEL */
00116    {
00117       FILE *fp;
00118       int i;
00119 
00120       if(path == NULL || strlen(path)==0)
00121         return NC_EINVAL;
00122         
00123       if (!(fp = fopen(path, "r")))
00124          return errno;
00125       i = fread(magic, MAGIC_NUMBER_LEN, 1, fp);
00126       fclose(fp);
00127       if(i != 1)
00128          return errno;
00129    }
00130     
00131    /* Ignore the first byte for HDF */
00132    if(magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F')
00133       *hdf = 5;
00134    else if(magic[0] == '\016' && magic[1] == '\003'
00135            && magic[2] == '\023' && magic[3] == '\001')
00136       *hdf = 4;
00137    else if(magic[0] == 'C' && magic[1] == 'D' && magic[2] == 'F') 
00138    {
00139       if(magic[3] == '\001') 
00140          *cdf = 1; /* netcdf classic version 1 */
00141       else if(magic[3] == '\002') 
00142          *cdf = 2; /* netcdf classic version 2 */
00143    }
00144     
00145    return NC_NOERR;
00146 }
00147 
00344 int
00345 nc_create(const char *path, int cmode, int *ncidp)
00346 {
00347    return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
00348 }
00349 
00411 int
00412 nc__create(const char *path, int cmode, size_t initialsz,
00413            size_t *chunksizehintp, int *ncidp)
00414 {
00415    return NC_create(path, cmode, initialsz, 0, 
00416                     chunksizehintp, 0, NULL, ncidp);
00417 
00418 }
00427 int
00428 nc__create_mp(const char *path, int cmode, size_t initialsz, 
00429               int basepe, size_t *chunksizehintp, int *ncidp)
00430 {
00431    return NC_create(path, cmode, initialsz, basepe, 
00432                     chunksizehintp, 0, NULL, ncidp);
00433 }
00434 
00546 int
00547 nc_open(const char *path, int mode, int *ncidp)
00548 {
00549    return NC_open(path, mode, 0, NULL, 0, NULL, ncidp);
00550 }
00551 
00603 int
00604 nc__open(const char *path, int mode,
00605          size_t *chunksizehintp, int *ncidp)
00606 {
00607    return NC_open(path, mode, 0, chunksizehintp, 0, 
00608                   NULL, ncidp);
00609 }
00610 
00619 int
00620 nc__open_mp(const char *path, int mode, int basepe, 
00621             size_t *chunksizehintp, int *ncidp)
00622 {
00623    return NC_open(path, mode, basepe, chunksizehintp,
00624                   0, NULL, ncidp);
00625 }
00626 
00644 int 
00645 nc_inq_path(int ncid, size_t *pathlen, char *path)
00646 {
00647    NC* ncp;
00648    int stat = NC_NOERR;
00649    if ((stat = NC_check_id(ncid, &ncp)))
00650       return stat;
00651    if(ncp->path == NULL) {
00652         if(pathlen) *pathlen = 0;
00653         if(path) path[0] = '\0';
00654    } else {
00655        if (pathlen) *pathlen = strlen(ncp->path);
00656        if (path) strcpy(path, ncp->path);
00657    }
00658    return stat;
00659 }
00660 
00709 int
00710 nc_redef(int ncid)
00711 {
00712    NC* ncp;
00713    int stat = NC_check_id(ncid, &ncp);
00714    if(stat != NC_NOERR) return stat;
00715    return ncp->dispatch->redef(ncid);
00716 }
00717 
00773 int
00774 nc_enddef(int ncid)
00775 {
00776    int status = NC_NOERR;
00777    NC *ncp;
00778    status = NC_check_id(ncid, &ncp); 
00779    if(status != NC_NOERR) return status;
00780    return ncp->dispatch->_enddef(ncid,0,1,0,1);
00781 }
00782 
00864 int
00865 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, 
00866            size_t r_align)
00867 {
00868    NC* ncp;
00869    int stat = NC_check_id(ncid, &ncp);
00870    if(stat != NC_NOERR) return stat;
00871    return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
00872 }
00873 
00941 int
00942 nc_sync(int ncid)
00943 {
00944    NC* ncp;
00945    int stat = NC_check_id(ncid, &ncp);
00946    if(stat != NC_NOERR) return stat;
00947    return ncp->dispatch->sync(ncid);
00948 }
00949 
00992 int
00993 nc_abort(int ncid)
00994 {
00995    NC* ncp;
00996    int stat = NC_check_id(ncid, &ncp);
00997    if(stat != NC_NOERR) return stat;
00998    if(ncp->path != NULL) free(ncp->path);
00999    ncp->path = NULL;   
01000    return ncp->dispatch->abort(ncid);
01001 }
01002 
01043 int
01044 nc_close(int ncid)
01045 {
01046    NC* ncp;
01047    int stat = NC_check_id(ncid, &ncp);
01048    if(stat != NC_NOERR) return stat;
01049    return ncp->dispatch->close(ncid);
01050 }
01051 
01150 int
01151 nc_set_fill(int ncid, int fillmode, int *old_modep)
01152 {
01153    NC* ncp;
01154    int stat = NC_check_id(ncid, &ncp);
01155    if(stat != NC_NOERR) return stat;
01156    return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
01157 }
01158 
01170 int
01171 nc_inq_base_pe(int ncid, int *pe)
01172 {
01173    NC* ncp;
01174    int stat = NC_check_id(ncid, &ncp);
01175    if(stat != NC_NOERR) return stat;
01176    return ncp->dispatch->inq_base_pe(ncid,pe);
01177 }
01178 
01190 int
01191 nc_set_base_pe(int ncid, int pe)
01192 {
01193    NC* ncp;
01194    int stat = NC_check_id(ncid, &ncp);
01195    if(stat != NC_NOERR) return stat;
01196    return ncp->dispatch->set_base_pe(ncid,pe);
01197 }
01198 
01216 int
01217 nc_inq_format(int ncid, int *formatp)
01218 {
01219    NC* ncp;
01220    int stat = NC_check_id(ncid, &ncp);
01221    if(stat != NC_NOERR) return stat;
01222    return ncp->dispatch->inq_format(ncid,formatp);
01223 }
01224 
01269 int
01270 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
01271 {
01272    NC* ncp;
01273    int stat = NC_check_id(ncid, &ncp);
01274    if(stat != NC_NOERR) return stat;
01275    return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
01276 }
01277 
01278 int
01279 nc_inq_nvars(int ncid, int *nvarsp)
01280 {
01281    NC* ncp;
01282    int stat = NC_check_id(ncid, &ncp);
01283    if(stat != NC_NOERR) return stat;
01284    return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
01285 }
01286 
01352 int
01353 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
01354 {
01355    NC* ncp;
01356    /* For compatibility, we need to allow inq about
01357       atomic types, even if ncid is ill-defined */
01358    if(xtype <= ATOMICTYPEMAX) {
01359       if(xtype <= NC_NAT) return NC_EBADTYPE;
01360       if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
01361       if(size) *size = NC_atomictypelen(xtype);
01362       return NC_NOERR;
01363    } else {
01364       int stat = NC_check_id(ncid, &ncp);
01365       if(stat != NC_NOERR) return NC_EBADTYPE; /* compatibility */
01366       return ncp->dispatch->inq_type(ncid,xtype,name,size);
01367    }
01368 }
01405 int
01406 NC_create(const char *path, int cmode, size_t initialsz, 
01407           int basepe, size_t *chunksizehintp, int useparallel, 
01408           void* mpi_info, int *ncidp)
01409 {
01410    int stat = NC_NOERR;
01411    NC* ncp = NULL;
01412    NC_Dispatch* dispatcher = NULL;
01413    /* Need three pieces of information for now */
01414    int model = 0; /* one of the NC_DISPATCH_XXX values */
01415    int isurl = 0;   /* dap or cdmremote or neither */
01416    int xcmode = 0; /* for implied cmode flags */
01417    extern int default_create_format;
01418 
01419    /* Initialize the dispatch table. The function pointers in the
01420     * dispatch table will depend on how netCDF was built
01421     * (with/without netCDF-4, DAP, CDMREMOTE). */
01422    if(!nc_initialized)
01423    {
01424       if ((stat = NC_initialize()))
01425          return stat; 
01426       /* Do local initialization */
01427       nc_local_initialize();
01428       nc_initialized = 1;
01429    }
01430 
01431    if((isurl = NC_testurl(path)))
01432         model = NC_urlmodel(path);
01433 
01434    /* Look to the incoming cmode for hints */
01435    if(model == 0) {
01436       if(cmode & NC_NETCDF4 || cmode & NC_PNETCDF)
01437         model = NC_DISPATCH_NC4;
01438    }
01439 
01440    if(model == 0) {
01441       /* Check default format */
01442       int format = default_create_format;
01443       switch (format) {
01444 #ifdef USE_NETCDF4
01445          case NC_FORMAT_NETCDF4:
01446             xcmode |= NC_NETCDF4;
01447             model = NC_DISPATCH_NC4;
01448             break;
01449          case NC_FORMAT_NETCDF4_CLASSIC:
01450             xcmode |= NC_CLASSIC_MODEL;
01451             model = NC_DISPATCH_NC4;
01452             break;
01453 #endif
01454          case NC_FORMAT_64BIT:
01455             xcmode |= NC_64BIT_OFFSET;
01456             /* fall thru */
01457          case NC_FORMAT_CLASSIC:
01458          default:
01459             model = NC_DISPATCH_NC3;
01460             break;
01461       }
01462    }
01463    
01464    /* Add inferred flags */
01465    cmode |= xcmode;
01466 
01467 #ifdef USE_NETCDF4
01468    if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX))
01469       return  NC_EINVAL;
01470 #endif
01471 
01472    if (!(dispatcher = NC_get_dispatch_override()))
01473    {
01474 
01475       /* Figure out what dispatcher to use */
01476 #ifdef USE_NETCDF4
01477 #ifdef USE_CDMREMOTE
01478       if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR))
01479          dispatcher = NCCR_dispatch_table;
01480       else
01481 #endif
01482       if(model == (NC_DISPATCH_NC4))
01483         dispatcher = NC4_dispatch_table;
01484       else
01485 #endif /*USE_NETCDF4*/
01486 #ifdef USE_DAP
01487       if(model == (NC_DISPATCH_NC3 | NC_DISPATCH_NCD))
01488         dispatcher = NCD3_dispatch_table;
01489       else
01490 #endif
01491       if(model == (NC_DISPATCH_NC3))
01492         dispatcher = NC3_dispatch_table;
01493       else
01494          return NC_ENOTNC;
01495    }
01496 
01497    if ((stat = dispatcher->create(path, cmode, initialsz, basepe, chunksizehintp,
01498                                    useparallel, mpi_info, dispatcher, &ncp)))
01499       return stat;
01500 
01501    ncp->dispatch = dispatcher;
01502    if(ncidp) 
01503       *ncidp = ncp->ext_ncid;
01504    if (!(ncp->path = nulldup(path)))
01505       return NC_ENOMEM;
01506    return NC_NOERR;
01507 }
01508 
01524 int
01525 NC_open(const char *path, int cmode,
01526         int basepe, size_t *chunksizehintp,
01527         int useparallel, void* mpi_info,
01528         int *ncidp)
01529 {
01530    int stat = NC_NOERR;
01531    NC* ncp = NULL;
01532    NC_Dispatch* dispatcher = NULL;
01533    /* Need two pieces of information for now */
01534    int model = 0;
01535    int isurl = 0; 
01536    int cdfversion = 0;
01537    int hdfversion = 0;
01538    extern int default_create_format;
01539 
01540    if(!nc_initialized) {
01541       stat = NC_initialize();
01542       if(stat) return stat;
01543       /* Do local initialization */
01544       nc_local_initialize();
01545       nc_initialized = 1;
01546    }
01547 
01548    isurl = NC_testurl(path);
01549    if(isurl)
01550       model = NC_urlmodel(path);
01551 
01552    if(!isurl) {
01553       /* Look at the file if it exists */
01554       stat = NC_check_file_type(path,useparallel,mpi_info,&cdfversion,&hdfversion);
01555       if(stat == NC_NOERR) {
01556          if(hdfversion != 0) {
01557             model = NC_DISPATCH_NC4;
01558          } else if(cdfversion != 0) {
01559             model = NC_DISPATCH_NC3;
01560          }
01561       } 
01562       /* else ignore the file */
01563    }
01564 
01565    /* Look to the incoming cmode for hints */
01566    if(model == 0) {
01567       if(cmode & NC_NETCDF4 || cmode & NC_PNETCDF) model |= NC_DISPATCH_NC4;
01568    }
01569 
01570    if(model == 0) model = NC_DISPATCH_NC3; /* final default */
01571 
01572    /* Force flag consistentcy */
01573    if(model & NC_DISPATCH_NC4)
01574       cmode |= NC_NETCDF4;
01575    else if(model & NC_DISPATCH_NC3) {
01576       cmode &= ~NC_NETCDF4; /* must be netcdf-3 */
01577       if(cdfversion == 2) cmode |= NC_64BIT_OFFSET;
01578    }
01579 
01580    if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX))
01581       return  NC_EINVAL;
01582 
01583    /* override overrides any other table choice */
01584    dispatcher = NC_get_dispatch_override();
01585    if(dispatcher != NULL) goto havetable;
01586 
01587    /* Figure out what dispatcher to use */
01588 #if  defined(USE_CDMREMOTE)
01589    if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR))
01590         dispatcher = NCCR_dispatch_table;
01591    else
01592 #endif
01593 #if defined(USE_DAP)
01594    if(model == (NC_DISPATCH_NC3 | NC_DISPATCH_NCD))
01595         dispatcher = NCD3_dispatch_table;
01596    else
01597 #endif
01598 #if defined(USE_NETCDF4)
01599    if(model == (NC_DISPATCH_NC4))
01600         dispatcher = NC4_dispatch_table;
01601    else
01602 #endif
01603    if(model == (NC_DISPATCH_NC3))
01604         dispatcher = NC3_dispatch_table;
01605    else
01606       return  NC_ENOTNC;
01607 
01608   havetable:
01609   stat = dispatcher->open(path, cmode, basepe, chunksizehintp,
01610                            useparallel, mpi_info, dispatcher, &ncp);
01611    if(stat == NC_NOERR) {
01612       ncp->dispatch = dispatcher;
01613       if(ncidp) *ncidp = ncp->ext_ncid;
01614       ncp->path = nulldup(path);
01615       if(path == NULL) stat = NC_ENOMEM;        
01616    }
01617    return stat;
01618 }
01619 
01620 /*Provide an internal function for generating pseudo file descriptors
01621   for systems that are not file based (e.g. dap, memio).
01622 */
01623 
01624 /* Static counter for pseudo file descriptors (incremented) */
01625 static int pseudofd = 0;
01626 
01627 /* Create a pseudo file descriptor that does not
01628    overlap real file descriptors
01629 */
01630 int
01631 nc__pseudofd(void)
01632 {
01633     if(pseudofd == 0)  {
01634         int maxfd = 32767; /* default */
01635 #ifdef HAVE_GETRLIMIT
01636         struct rlimit rl;
01637         if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
01638             if(rl.rlim_max != RLIM_INFINITY)
01639                 maxfd = rl.rlim_max;
01640             if(rl.rlim_cur != RLIM_INFINITY)
01641                 maxfd = rl.rlim_cur;
01642         }
01643         pseudofd = maxfd+1;
01644 #endif
01645     }
01646 
01647     return pseudofd++;
01648 }
01649 
01650 
 All Data Structures Files Functions Variables Typedefs Defines

Generated on Sat Sep 15 2012 12:44:33 for netCDF. NetCDF is a Unidata library.