/*------------------------------------------------------------------------- * Function: H5FD_stdio_open * * Purpose: Create and/or opens a Standard C file as an HDF5 file. * * Errors: * IO CANTOPENFILE File doesn't exist and CREAT wasn't * specified. * IO CANTOPENFILE fopen() failed. * IO FILEEXISTS File exists but CREAT and EXCL were * specified. * * Return: * Success: A pointer to a new file data structure. The * public fields will be initialized by the * caller, which is always H5FD_open(). * * Failure: NULL * * Programmer: Robb Matzke * Wednesday, October 22, 1997 * *------------------------------------------------------------------------- */ static H5FD_t * H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { FILE *f = NULL; unsigned write_access = 0; /* File opened with write access? */ H5FD_stdio_t *file = NULL; static const char *func = "H5FD_stdio_open"; /* Function Name for error reporting */ #ifdef H5_HAVE_WIN32_API struct _BY_HANDLE_FILE_INFORMATION fileinfo; #else /* H5_HAVE_WIN32_API */ struct stat sb; #endif /* H5_HAVE_WIN32_API */ /* Sanity check on file offsets */ assert(sizeof(file_offset_t) >= sizeof(size_t)); /* Quiet compiler */ fapl_id = fapl_id; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Check arguments */ if (!name || !*name) H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADVALUE, "invalid file name", NULL) if (0 == maxaddr || HADDR_UNDEF == maxaddr) H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADRANGE, "bogus maxaddr", NULL) if (ADDR_OVERFLOW(maxaddr)) H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL) /* Tentatively open file in read-only mode, to check for existence */ if(flags & H5F_ACC_RDWR) f = fopen(name, "rb+"); else f = fopen(name, "rb"); if(!f) { /* File doesn't exist */ if(flags & H5F_ACC_CREAT) { assert(flags & H5F_ACC_RDWR); f = fopen(name, "wb+"); write_access = 1; /* Note the write access */ } else H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "file doesn't exist and CREAT wasn't specified", NULL) } else if(flags & H5F_ACC_EXCL) {
/*------------------------------------------------------------------------- * Function: H5FD_stdio_open * * Purpose: Create and/or opens a Standard C file as an HDF5 file. * * Bugs: H5F_ACC_EXCL has a race condition. (? -QAK) * * Errors: * IO CANTOPENFILE File doesn't exist and CREAT wasn't * specified. * IO CANTOPENFILE Fopen failed. * IO FILEEXISTS File exists but CREAT and EXCL were * specified. * * Return: Success: A pointer to a new file data structure. The * public fields will be initialized by the * caller, which is always H5FD_open(). * * Failure: NULL * * Programmer: Robb Matzke * Wednesday, October 22, 1997 * * Modifications: * Ported to VFL/H5FD layer - QAK, 10/18/99 * *------------------------------------------------------------------------- */ static H5FD_t * H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { FILE *f = NULL; unsigned write_access=0; /* File opened with write access? */ H5FD_stdio_t *file=NULL; static const char *func="H5FD_stdio_open"; /* Function Name for error reporting */ #ifdef _WIN32 HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; int fd; #else /* _WIN32 */ struct stat sb; #endif /* _WIN32 */ /* Sanity check on file offsets */ assert(sizeof(file_offset_t)>=sizeof(size_t)); /* Shut compiler up */ fapl_id=fapl_id; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Check arguments */ if (!name || !*name) H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADVALUE, "invalid file name", NULL) if (0==maxaddr || HADDR_UNDEF==maxaddr) H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADRANGE, "bogus maxaddr", NULL) if (ADDR_OVERFLOW(maxaddr)) H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL) if (access(name, F_OK) < 0) { if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) { f = fopen(name, "wb+"); write_access=1; /* Note the write access */ } else H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "file doesn't exist and CREAT wasn't specified", NULL) } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) {
/*------------------------------------------------------------------------- * Function: H5Pset_fapl_stdio * * Purpose: Modify the file access property list to use the H5FD_STDIO * driver defined in this source file. There are no driver * specific properties. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Thursday, February 19, 1998 * *------------------------------------------------------------------------- */ herr_t H5Pset_fapl_stdio(hid_t fapl_id) { static const char *func = "H5FDset_fapl_stdio"; /*for error reporting*/ /*NO TRACE*/ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); if(0 == H5Pisa_class(fapl_id, H5P_FILE_ACCESS)) H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not a file access property list", -1) return H5Pset_driver(fapl_id, H5FD_STDIO, NULL); } /* end H5Pset_fapl_stdio() */