The files libdispatch/dwinpath.c and include/ncwinpath.h

were added to provide a path name converter from e.g. cygwin
paths to e.g. windows paths. This is necessary because
the shell scripts may produce cygwin paths, but the code
may have been compiled with Visual Studio. Similar issues
arise with Mingw.

At appropriate places, and if using Visual Studio or Mingw,
I added calls to the path conversion code.
Apparently I forgot to find all the places where this
conversion was needed. So this pr does the following:
1. Push the calls to the converter to the various libXXX
   directories and out of libdispatch/dfile.c.
2. Add conversion calls to other parts of the code like oc2.

I also turns out that conversion code in dapcvt.c
had a bug when handling DAP Byte type under visual studio.

Notes:
1. there may still be places I missed that need to do path conversion.
2. need to make sure that calls to e.g. H5open also use converted path.
This commit is contained in:
Dennis Heimbigner 2017-07-13 10:40:07 -06:00
parent fd2c575597
commit 715a6fe5eb
17 changed files with 119 additions and 85 deletions

View File

@ -1,5 +1,12 @@
# Visual Studio
VS=1
#VSSETUP=1
if test "x$VSSETUP" = x1 ; then
CFG="Debug"
else
CFG="Release"
fi
# Is netcdf-4 and/or DAP enabled?
NC4=1
@ -33,13 +40,13 @@ NCLIB=`pwd`
if test "x$VS" != x ; then
# Visual Studio
#CFG="RelWithDebInfo"
CFG="Release"
NCLIB="${NCLIB}/build/liblib/$CFG"
export PATH="${NCLIB}:${PATH}"
cmake $FLAGS ..
if test "x$VSSETUP" = x ; then
cmake --build . --config ${CFG}
cmake --build . --config ${CFG} --target RUN_TESTS
fi
else
# GCC
NCLIB="${NCLIB}/build/liblib"

View File

@ -13,7 +13,7 @@
* https://stackoverflow.com/questions/1372480/c-redefinition-header-files-winsock2-h
*/
#define _WINSOCKAPI_
/* #define _WINSOCKAPI_*/
#if _MSC_VER>=1900
#define STDC99

View File

@ -10,13 +10,14 @@
#include <stdio.h>
#include "ncexternl.h"
#ifndef WINPATH
#ifdef _MSC_VER
#define WINPATH 1
#endif
#ifdef __MINGW32__
#define WINPATH 1
#endif
#endif
/* path converter */
EXTERNL char* NCpathcvt(const char* path);

View File

@ -209,17 +209,16 @@ dapcvtattrval(nc_type etype, void* dst, NClist* src)
ok = 0;
switch (etype) {
case NC_BYTE: {
case NC_BYTE: { /* Note that in DAP2, this is unsigned 8-bit integer */
/*Needs special handling because Windows sscanf does not do %hhd*/
char* p = (char*)dstmem;
#ifdef _MSC_VER
int ival;
ok = sscanf(s,"%d%n",&ival,&nread);
#ifdef _MSC_VER
_ASSERTE(_CrtCheckMemory());
if(ival < NC_MIN_BYTE || ival > NC_MAX_BYTE) ok = 0;
*p = (char)ival;
#else
ok = sscanf(s,"%hhu%n",p,&nread);
#endif
if(ival < 0 || ival > NC_MAX_UBYTE) ok = 0;
*p = (char)ival;
} break;
case NC_CHAR: {
signed char* p = (signed char*)dstmem;

View File

@ -20,9 +20,10 @@ dapbreakpoint(int err)
}
int
dapthrow(int err)
dapthrow(int err, int lineno, const char* filename)
{
if(err == 0) return err;
fprintf(stderr,"$dapthrow: err=%d line=%d file=%s\n",err,lineno,filename); fflush(stderr);
return dapbreakpoint(err);
}
#endif

View File

@ -5,7 +5,7 @@
#ifndef DEBUG_H
#define DEBUG_H
#if 0
#if 1
#define DAPDEBUG 1
#define OCDEBUG 1
#endif
@ -51,11 +51,11 @@ extern int dappanic(const char* fmt, ...);
#ifdef CATCHERROR
/* Place breakpoint on dapbreakpoint to catch errors close to where they occur*/
#define THROW(e) dapthrow(e)
#define THROWCHK(e) (void)dapthrow(e)
#define THROW(e) dapthrow(e,__LINE__,__FILE__)
#define THROWCHK(e) (void)dapthrow(e,__LINE__,__FILE__)
extern int dapbreakpoint(int err);
extern int dapthrow(int err);
extern int dapthrow(int err, int lineno, const char* filename);
#else
#define THROW(e) (e)
#define THROWCHK(e)

View File

@ -283,7 +283,7 @@ NCD2_get_vars(int ncid, int varid,
/* See ncd2dispatch.c for other version */
int
NCD2_open(const char * path, int mode,
NCD2_open(const char* path, int mode,
int basepe, size_t *chunksizehintp,
int useparallel, void* mpidata,
NC_Dispatch* dispatch, NC* drno)
@ -295,13 +295,15 @@ NCD2_open(const char * path, int mode,
int nc3id = -1;
if(path == NULL)
return NC_EDAPURL;
if(dispatch == NULL) PANIC("NCD3_open: no dispatch table");
{ncstat = NC_EDAPURL; goto done;}
if(dispatch == NULL)
PANIC("NCD3_open: no dispatch table");
/* Setup our NC and NCDAPCOMMON state*/
dapcomm = (NCDAPCOMMON*)calloc(1,sizeof(NCDAPCOMMON));
if(dapcomm == NULL) {ncstat = NC_ENOMEM; goto done;}
if(dapcomm == NULL)
{ncstat = NC_ENOMEM; goto done;}
NCD2_DATA_SET(drno,dapcomm);
drno->int_ncid = nc__pseudofd(); /* create a unique id */

View File

@ -118,9 +118,11 @@ done:
/*!
Given an existing file, figure out its format
and return that format value (NC_FORMATX_XXX)
in model arg.
in model arg. Assume any path conversion was
already performed at a higher level.
*/
static int NC_check_file_type(const char *path, int flags, void *parameters,
static int
NC_check_file_type(const char *path, int flags, void *parameters,
int* model, int* version)
{
char magic[MAGIC_NUMBER_LEN];
@ -139,6 +141,7 @@ static int NC_check_file_type(const char *path, int flags, void *parameters,
} else {/* presumably a real file */
/* Get the 4-byte magic from the beginning of the file. Don't use posix
* for parallel, use the MPI functions instead. */
#ifdef USE_PARALLEL
if (use_parallel) {
MPI_File fh;
@ -169,19 +172,18 @@ static int NC_check_file_type(const char *path, int flags, void *parameters,
#else
struct stat st;
#endif
if(path == NULL || strlen(path)==0)
if(path == NULL || strlen(path)==0)
{status = NC_EINVAL; goto done;}
if (!(fp = fopen(path, "r")))
if (!(fp = fopen(path, "r")))
{status = errno; goto done;}
#ifdef HAVE_SYS_STAT_H
/* The file must be at least MAGIC_NUMBER_LEN in size,
/* The file must be at least MAGIC_NUMBER_LEN in size,
or otherwise the following fread will exhibit unexpected
behavior. */
/* Windows and fstat have some issues, this will work around that. */
/* Windows and fstat have some issues, this will work around that. */
#ifdef HAVE_FILE_LENGTH_I64
if((file_len = _filelengthi64(fileno(fp))) < 0) {
fclose(fp);
@ -189,7 +191,6 @@ static int NC_check_file_type(const char *path, int flags, void *parameters,
goto done;
}
if(file_len < MAGIC_NUMBER_LEN) {
fclose(fp);
status = NC_ENOTNC;
@ -1659,13 +1660,7 @@ NC_create(const char *path0, int cmode, size_t initialsz,
return stat;
}
#ifdef WINPATH
/* Need to do path conversion */
path = NCpathcvt(path0);
fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
#else
path = nulldup(path0);
#endif
#ifdef USE_REFCOUNT
/* If this path is already open, then fail */
@ -1826,10 +1821,12 @@ NC_open(const char *path0, int cmode,
if(stat) return stat;
}
/* Attempt to do file path conversion: note that this will do
nothing if path is a 'file:...' url, so it will need to be
repeated in protocol code: libdap2 and libdap4
*/
#ifdef WINPATH
/* Need to do path conversion */
path = NCpathcvt(path0);
fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
#else
path = nulldup(path0);
#endif

View File

@ -18,6 +18,8 @@
#include "ncexternl.h"
#include "ncwinpath.h"
#undef PATHDEBUG
/*
Code to provide some path conversion code so that
cygwin and (some) mingw paths can be passed to open/fopen
@ -47,7 +49,7 @@ NCpathcvt(const char* path)
char* q;
size_t pathlen;
if(path == NULL) return NULL; /* defensive driving */
if(path == NULL) goto done; /* defensive driving */
pathlen = strlen(path);
/* 1. look for MSYS path /D/... */
@ -57,7 +59,7 @@ NCpathcvt(const char* path)
&& (path[2] == '/' || path[2] == '\\' || path[2] == '\0')) {
/* Assume this is a mingw path */
outpath = (char*)malloc(pathlen+3); /* conservative */
if(outpath == NULL) return NULL;
if(outpath == NULL) goto done;
q = outpath;
*q++ = path[1];
*q++ = ':';
@ -76,8 +78,8 @@ NCpathcvt(const char* path)
|| path[cdlen+1] == '\0')) {
/* Assume this is a cygwin path */
outpath = (char*)malloc(pathlen+1); /* conservative */
if(outpath == NULL) return NULL;
outpath[0] = path[cdlen];
if(outpath == NULL) goto done;
outpath[0] = path[cdlen]; /* drive letter */
outpath[1] = ':';
strcpy(&outpath[2],&path[cdlen+1]);
if(strlen(outpath) == 2)
@ -99,12 +101,29 @@ NCpathcvt(const char* path)
goto done;
slashtrans:
/* In all #1 or #2 cases, translate '/' -> '\\' */
/* In order to help debugging, and if not using MSC_VER or MINGW,
convert back slashes to forward, else convert forward to back
*/
p = outpath;
/* In all #1 or #2 cases, translate '/' -> '\\' */
for(;*p;p++) {
if(*p == '/') {*p = '\\';}
}
#ifdef PATHDEBUG
#ifndef _MSC_VER
/* Convert '\' back to '/' */
for(;*p;p++) {
if(*p == '\\') {*p = '/';}
}
#endif /*!_MSC_VER*/
#endif /*PATHDEBUG*/
done:
#ifdef PATHDEBUG
fprintf(stderr,"XXXX: inpath=|%s| outpath=|%s|\n",
path?path:"NULL",outpath?outpath:"NULL");
fflush(stderr);
#endif
return outpath;
}
@ -120,8 +139,6 @@ NCfopen(const char* path, const char* flags)
{
FILE* f = NULL;
char* cvtname = NCpathcvt(path);
fprintf(stderr,"XXXX: path=|%s| cvtpath=|%s|\n",path,cvtname?cvtname:"null");
fflush(stderr);
if(cvtname == NULL) return NULL;
f = fopen(cvtname,flags);
free(cvtname);
@ -133,10 +150,8 @@ int
NCopen3(const char* path, int flags, int mode)
{
int fd = -1;
fprintf(stderr,"XXXX: path=|%s|\n",path);
fflush(stderr);
char* cvtname = NCpathcvt(path);
fprintf(stderr,"XXXX: path=|%s| cvtpath=|%s|\n",path,cvtname?cvtname:"null");
fflush(stderr);
if(cvtname == NULL) return -1;
fd = open(cvtname,flags,mode);

View File

@ -1113,7 +1113,7 @@ NC3_open(const char * path, int ioflags,
#if defined(LOCKNUMREC) /* && _CRAYMPP */
if (status = NC_init_pe(nc3, basepe)) {
return status;
goto unwind_alloc;
}
#else
/*
@ -1121,9 +1121,11 @@ NC3_open(const char * path, int ioflags,
*/
if(basepe != 0) {
if(nc3) free(nc3);
return NC_EINVAL;
status = NC_EINVAL;
goto unwind_alloc;
}
#endif
status = ncio_open(path, ioflags, 0, 0, &nc3->chunk, parameters,
&nc3->nciop, NULL);
if(status)

View File

@ -602,15 +602,15 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
/* Check the cmode for validity. */
if((cmode & ILLEGAL_CREATE_FLAGS) != 0)
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
/* Cannot have both */
if((cmode & (NC_MPIIO|NC_MPIPOSIX)) == (NC_MPIIO|NC_MPIPOSIX))
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
/* Currently no parallel diskless io */
if((cmode & (NC_MPIIO | NC_MPIPOSIX)) && (cmode & NC_DISKLESS))
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
#ifndef USE_PARALLEL_POSIX
/* If the HDF5 library has been compiled without the MPI-POSIX VFD, alias
@ -636,8 +636,10 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
LOG((2, "cmode after applying default format: 0x%x", cmode));
nc_file->int_ncid = nc_file->ext_ncid;
res = nc4_create_file(nc_file->path, cmode, comm, info, nc_file);
res = nc4_create_file(path, cmode, comm, info, nc_file);
done:
return res;
}
@ -2845,11 +2847,11 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
/* Check the mode for validity */
if((mode & ILLEGAL_OPEN_FLAGS) != 0)
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
/* Cannot have both */
if((mode & (NC_MPIIO|NC_MPIPOSIX)) == (NC_MPIIO|NC_MPIPOSIX))
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
#ifndef USE_PARALLEL_POSIX
/* If the HDF5 library has been compiled without the MPI-POSIX VFD, alias
@ -2864,7 +2866,7 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
/* Figure out if this is a hdf4 or hdf5 file. */
if ((res = nc_check_for_hdf(path, use_parallel, parameters, &hdf_file)))
return res;
goto done;
/* Depending on the type of file, open it. */
nc_file->int_ncid = nc_file->ext_ncid;
@ -2872,12 +2874,13 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
res = nc4_open_file(path, mode, parameters, nc_file);
#ifdef USE_HDF4
else if (hdf_file == NC_HDF4_FILE && inmemory)
return NC_EDISKLESS;
{res = NC_EDISKLESS; goto done;}
else if (hdf_file == NC_HDF4_FILE)
res = nc4_open_hdf4_file(path, mode, nc_file);
#endif /* USE_HDF4 */
else
assert(0); /* should never happen */
assert(0); /* should never happen */
done:
return res;
}

View File

@ -9,6 +9,7 @@
#include <mpi.h>
#include "nc.h"
#include "ncdispatch.h"
/* Must follow netcdf.h */
#include <pnetcdf.h>
@ -50,15 +51,15 @@ NCP_create(const char *path, int cmode,
/* Check the cmode for only valid flags*/
if(cmode & ~LEGAL_CREATE_FLAGS)
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
/* Cannot have both MPIO flags */
if((cmode & (NC_MPIIO|NC_MPIPOSIX)) == (NC_MPIIO|NC_MPIPOSIX))
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
/* Cannot have both NC_64BIT_OFFSET & NC_64BIT_DATA */
if((cmode & (NC_64BIT_OFFSET|NC_64BIT_DATA)) == (NC_64BIT_OFFSET|NC_64BIT_DATA))
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
default_format = nc_get_default_format();
/* if (default_format == NC_FORMAT_CLASSIC) then we respect the format set in cmode */
@ -72,14 +73,17 @@ NCP_create(const char *path, int cmode,
}
/* No MPI environment initialized */
if (mpidata == NULL) return NC_ENOPAR;
if (mpidata == NULL)
{res = NC_ENOPAR; goto done;}
comm = ((NC_MPI_INFO *)mpidata)->comm;
info = ((NC_MPI_INFO *)mpidata)->info;
/* Create our specific NCP_INFO instance */
nc5 = (NCP_INFO*)calloc(1,sizeof(NCP_INFO));
if(nc5 == NULL) return NC_ENOMEM;
if(nc5 == NULL)
{res = NC_ENOMEM; goto done;}
/* Link nc5 and nc */
NCP_DATA_SET(nc,nc5);
@ -97,9 +101,11 @@ NCP_create(const char *path, int cmode,
*/
/* PnetCDF recognizes the flags below for create and ignores NC_LOCK and NC_SHARE */
cmode &= (NC_WRITE | NC_NOCLOBBER | NC_SHARE | NC_64BIT_OFFSET | NC_64BIT_DATA);
res = ncmpi_create(comm, path, cmode, info, &(nc->int_ncid));
if(res && nc5 != NULL) free(nc5); /* reclaim allocated space */
done:
return res;
}
@ -116,16 +122,15 @@ NCP_open(const char *path, int cmode,
/* Check the cmode for only valid flags*/
if(cmode & ~LEGAL_OPEN_FLAGS)
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
/* Cannot have both MPIO flags */
if((cmode & (NC_MPIIO|NC_MPIPOSIX)) == (NC_MPIIO|NC_MPIPOSIX))
return NC_EINVAL;
{res = NC_EINVAL; goto done;}
/* Appears that this comment is wrong; allow 64 bit offset*/
/* Cannot have 64 bit offset flag */
/* if(cmode & (NC_64BIT_OFFSET)) return NC_EINVAL; */
/* if(cmode & (NC_64BIT_OFFSET)) {res = NC_EINVAL; goto done;} */
if(mpidata != NULL) {
comm = ((NC_MPI_INFO *)mpidata)->comm;
info = ((NC_MPI_INFO *)mpidata)->info;
@ -145,7 +150,7 @@ NCP_open(const char *path, int cmode,
/* Create our specific NCP_INFO instance */
nc5 = (NCP_INFO*)calloc(1,sizeof(NCP_INFO));
if(nc5 == NULL) return NC_ENOMEM;
if(nc5 == NULL) {res = NC_ENOMEM; goto done;}
/* Link nc5 and nc */
NCP_DATA_SET(nc,nc5);
@ -157,7 +162,7 @@ NCP_open(const char *path, int cmode,
res = ncmpi_begin_indep_data(nc->int_ncid);
nc5->pnetcdf_access_mode = NC_INDEPENDENT;
}
done:
return res;
}

View File

@ -14,6 +14,7 @@
#include "occlientparams.h"
#include "occurlfunctions.h"
#include "ochttp.h"
#include "ncwinpath.h"
#undef TRACK
@ -2085,11 +2086,10 @@ oc_set_netrc(OClink* link, const char* file)
if(file == NULL || strlen(file) == 0)
return OC_EINVAL;
nclog(OCLOGDBG,"OC: using netrc file: %s",file);
/* See if it exists and is readable; complain if not */
f = fopen(file,"r");
if(f == NULL)
nclog(NCLOGWARN,"OC: netrc file is not readable; continuing");
else {
/* See if it exists and is readable; ignore if not */
f = NCfopen(file,"r");
if(f != NULL) { /* Log what rc file is being used */
nclog(NCLOGNOTE,"OC: netrc file found: %s",file);
fclose(f);
}
return OCTHROW(ocset_netrc(state,file));
@ -2142,7 +2142,7 @@ oc_set_rcfile(const char* rcfile)
if(rcfile == NULL) {
ocglobalstate.rc.ignore = 1;
} else {
FILE* f = fopen(rcfile,"r");
FILE* f = NCfopen(rcfile,"r");
if(f == NULL) {
stat = (OC_ERCFILE);
goto done;

View File

@ -25,6 +25,7 @@
#include "ochttp.h"
#include "ocread.h"
#include "dapparselex.h"
#include "ncwinpath.h"
#define DATADDSFILE "datadds"
@ -387,7 +388,7 @@ createtempfile(OCstate* state, OCtree* tree)
#endif
tree->data.filename = name; /* remember our tmp file name */
name = NULL;
tree->data.file = fopen(tree->data.filename,"w+");
tree->data.file = NCfopen(tree->data.filename,"w+");
if(tree->data.file == NULL) return OC_EOPEN;
/* unlink the temp file so it will automatically be reclaimed */
if(ocdebug == 0) unlink(tree->data.filename);
@ -640,17 +641,17 @@ ocset_curlproperties(OCstate* state)
FILE* f = NULL;
char* fname = state->curlflags.cookiejar;
/* See if the file exists already */
f = fopen(fname,"r");
f = NCfopen(fname,"r");
if(f == NULL) {
/* Ok, create it */
f = fopen(fname,"w+");
f = NCfopen(fname,"w+");
if(f == NULL) {
fprintf(stderr,"Cookie file cannot be read and written: %s\n",fname);
{stat = OC_EPERM; goto fail;}
}
} else { /* test if file can be written */
fclose(f);
f = fopen(fname,"r+");
f = NCfopen(fname,"r+");
if(f == NULL) {
fprintf(stderr,"Cookie file is cannot be written: %s\n",fname);
{stat = OC_EPERM; goto fail;}

View File

@ -13,6 +13,7 @@
#include "ocinternal.h"
#include "ocdebug.h"
#include "nclog.h"
#include "ncwinpath.h"
#define OCRCFILEENV "DAPRCFILE"
@ -279,7 +280,7 @@ ocrc_compile(const char* path)
ocrc->ntriples = 0; /* reset; nothing to free */
in_file = fopen(path, "r"); /* Open the file to read it */
in_file = NCfopen(path, "r"); /* Open the file to read it */
if (in_file == NULL) {
nclog(NCLOGERR, "Could not open configuration file: %s",path);
return OC_EPERM;
@ -714,9 +715,7 @@ rc_search(const char* prefix, const char* rcname, char** pathp)
goto done;
}
/* see if file is readable */
f = fopen(path,"r");
if(f != NULL)
nclog(NCLOGDBG, "Found rc file=%s",path);
f = NCfopen(path,"r");
done:
if(f == NULL || stat != OC_NOERR) {
if(path != NULL)

View File

@ -19,6 +19,7 @@
#include "ochttp.h"
#include "ocread.h"
#include "occurlfunctions.h"
#include "ncwinpath.h"
/*Forward*/
static int readpacket(OCstate* state, NCURI*, NCbytes*, OCdxd, long*);
@ -214,10 +215,11 @@ readfile(const char* path, const char* suffix, NCbytes* packet)
#ifdef O_BINARY
flags |= O_BINARY;
#endif
fd = open(filename,flags);
fd = NCopen2(filename,flags);
if(fd < 0) {
nclog(NCLOGERR,"open failed:%s",filename);
return OCTHROW(OC_EOPEN);
nclog(NCLOGERR,"open failed: %s file=|%s|",ocerrstring(errno),filename);
stat = OC_EOPEN;
goto done;
}
/* Get the file size */
filesize = lseek(fd,(off_t)0,SEEK_END);

View File

@ -721,9 +721,9 @@ ocmktmp(const char* base, char** tmpnamep)
return OC_EOVERRUN;
}
#if defined(_WIN32) || defined(_WIN64)
fd=open(tmpname,O_RDWR|O_BINARY|O_CREAT, _S_IREAD|_S_IWRITE);
fd=NCopen3(tmpname,O_RDWR|O_BINARY|O_CREAT, _S_IREAD|_S_IWRITE);
# else
fd=open(tmpname,O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
fd=NCopen3(tmpname,O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
# endif
}
#endif /* !HAVE_MKSTEMP */