/********************************************************************* * Copyright 2018, UCAR/Unidata * See netcdf/COPYRIGHT file for copying and redistribution conditions. * ********************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Programmer: Dennis Heimbigner dmh@ucar.edu * * Purpose: Access remote datasets using byte range requests. * Derived from the HDF5 H5FDstdio.c file. * * NOTE: This driver is not as well tested as the standard SEC2 driver * and is not intended for production use! */ #include "config.h" #include #include #include #include #include #include #include #include #ifdef H5_HAVE_FLOCK /* Needed for lock type definitions (e.g., LOCK_EX) */ #include #endif /* H5_HAVE_FLOCK */ #ifdef H5_HAVE_UNISTD_H #include #endif /* Define a simple #ifdef test for the version of H5FD_class_t we are using */ #if H5_VERS_MAJOR == 1 #if H5_VERS_MINOR < 10 #define H5FDCLASS1 1 #endif #else #error "Cannot determine version of H5FD_class_t" #endif #ifdef H5_HAVE_WIN32_API /* The following two defines must be before any windows headers are included */ #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */ #define NOGDI /* Exclude Graphic Display Interface macros */ #include #include #endif /* H5_HAVE_WIN32_API */ #include "netcdf.h" #include "ncbytes.h" #include "nclist.h" #include "nchttp.h" #include "H5FDhttp.h" typedef off_t file_offset_t; /* The driver identification number, initialized at runtime */ static hid_t H5FD_HTTP_g = 0; /* File operations */ typedef enum { H5FD_HTTP_OP_UNKNOWN=0, H5FD_HTTP_OP_READ=1, H5FD_HTTP_OP_WRITE=2, H5FD_HTTP_OP_SEEK=3 } H5FD_http_file_op; /* The description of a file belonging to this driver. The 'eoa' and 'eof' * determine the amount of hdf5 address space in use and the high-water mark * of the file (the current size of the underlying Unix file). The 'pos' * value is used to eliminate file position updates when they would be a * no-op. Unfortunately we've found systems that use separate file position * indicators for reading and writing so the lseek can only be eliminated if * the current operation is the same as the previous operation. When opening * a file the 'eof' will be set to the current file size, 'eoa' will be set * to zero, 'pos' will be set to H5F_ADDR_UNDEF (as it is when an error * occurs), and 'op' will be set to H5F_OP_UNKNOWN. */ typedef struct H5FD_http_t { H5FD_t pub; /* public stuff, must be first */ haddr_t eoa; /* end of allocated region */ haddr_t eof; /* end of file; current file size */ haddr_t pos; /* current file I/O position */ unsigned write_access; /* Flag to indicate the file was opened with write access */ H5FD_http_file_op op; /* last operation */ NC_HTTP_STATE* state; /* Curl handle + extra */ char* url; /* The URL (minus any fragment) for the dataset */ } H5FD_http_t; /* These macros check for overflow of various quantities. These macros * assume that file_offset_t is signed and haddr_t and size_t are unsigned. * * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' * is too large to be represented by the second argument * of the file seek function. * * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too * large to be represented by the `size_t' type. * * REGION_OVERFLOW: Checks whether an address and size pair describe data * which can be addressed entirely by the second * argument of the file seek function. */ /* adding for windows NT filesystem support. */ #define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) #define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || ((A) & ~(haddr_t)MAXADDR)) #define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) #define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ HADDR_UNDEF==(A)+(Z) || (file_offset_t)((A)+(Z))<(file_offset_t)(A)) /* Prototypes */ static H5FD_t *H5FD_http_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD_http_close(H5FD_t *lf); static int H5FD_http_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD_http_query(const H5FD_t *_f1, unsigned long *flags); static haddr_t H5FD_http_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); static haddr_t H5FD_http_get_eoa(const H5FD_t *_file, H5FD_mem_t type); static herr_t H5FD_http_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); static herr_t H5FD_http_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle); static herr_t H5FD_http_read(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, void *buf); static herr_t H5FD_http_write(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); /* The H5FD_class_t structure has different versions */ #ifdef H5FDCLASS1 static haddr_t H5FD_http_get_eof(const H5FD_t *_file); static herr_t H5FD_http_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing); static herr_t H5FD_http_lock(H5FD_t *_file, unsigned char* old, unsigned lock_type, hbool_t last); static herr_t H5FD_http_unlock(H5FD_t *file, unsigned char *oid, hbool_t last); #else static herr_t H5FD_http_term(void); static haddr_t H5FD_http_get_eof(const H5FD_t *_file, H5FD_mem_t type); static herr_t H5FD_http_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD_http_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD_http_unlock(H5FD_t *_file); #endif /* Beware, not same as H5FD_HTTP_g */ static const H5FD_class_t H5FD_http_g = { #if H5_VERSION_GE(1,13,2) H5FD_CLASS_VERSION, /* struct version */ H5_VFD_HTTP, /* value */ #endif "http", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ #ifndef H5FDCLASS1 H5FD_http_term, /* terminate */ #endif NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ 0, /* fapl_size */ NULL, /* fapl_get */ NULL, /* fapl_copy */ NULL, /* fapl_free */ 0, /* dxpl_size */ NULL, /* dxpl_copy */ NULL, /* dxpl_free */ H5FD_http_open, /* open */ H5FD_http_close, /* close */ H5FD_http_cmp, /* cmp */ H5FD_http_query, /* query */ NULL, /* get_type_map */ H5FD_http_alloc, /* alloc */ NULL, /* free */ H5FD_http_get_eoa, /* get_eoa */ H5FD_http_set_eoa, /* set_eoa */ H5FD_http_get_eof, /* get_eof */ H5FD_http_get_handle, /* get_handle */ H5FD_http_read, /* read */ H5FD_http_write, /* write */ #if H5_VERSION_GE(1,13,2) NULL, /* read_vector */ NULL, /* write_vector */ NULL, /* read_selection */ NULL, /* write_selection */ #endif H5FD_http_flush, /* flush */ NULL, /* truncate */ H5FD_http_lock, /* lock */ H5FD_http_unlock, /* unlock */ #if H5_VERSION_GE(1,13,2) NULL, /* del */ NULL, /* ctl */ #endif H5FD_FLMAP_DICHOTOMY /* fl_map */ }; /*------------------------------------------------------------------------- * Function: H5FD_http_init * * Purpose: Initialize this driver by registering the driver with the * library. * * Return: Success: The driver ID for the driver. * * Failure: Negative. * * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ EXTERNL hid_t H5FD_http_init(void) { /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); if (H5I_VFL!=H5Iget_type(H5FD_HTTP_g)) H5FD_HTTP_g = H5FDregister(&H5FD_http_g); return H5FD_HTTP_g; } /* end H5FD_http_init() */ /*--------------------------------------------------------------------------- * Function: H5FD_http_term * * Purpose: Shut down the VFD * * Returns: Non-negative on success or negative on failure * * Programmer: Quincey Koziol * Friday, Jan 30, 2004 * *--------------------------------------------------------------------------- */ #ifndef H5FDCLASS1 static herr_t H5FD_http_term(void) { /* Reset VFL ID */ H5FD_HTTP_g = 0; return 0; } /* end H5FD_http_term() */ #endif /*------------------------------------------------------------------------- * Function: H5Pset_fapl_http * * Purpose: Modify the file access property list to use the H5FD_HTTP * 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 * *------------------------------------------------------------------------- */ EXTERNL herr_t H5Pset_fapl_http(hid_t fapl_id) { static const char *func = "H5FDset_fapl_http"; /*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_HTTP, NULL); } /* end H5Pset_fapl_http() */ /*------------------------------------------------------------------------- * Function: H5FD_http_open * * Purpose: Opens a remote Object as an HDF5 file. * * Errors: * IO CANTOPENFILE File doesn't exist and CREAT wasn't * 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: Dennis Heimbigner * *------------------------------------------------------------------------- */ static H5FD_t * H5FD_http_open( const char *name, unsigned flags, hid_t /*UNUSED*/ fapl_id, haddr_t maxaddr) { unsigned write_access = 0; /* File opened with write access? */ H5FD_http_t *file = NULL; static const char *func = "H5FD_http_open"; /* Function Name for error reporting */ long long len = -1; int ncstat = NC_NOERR; NC_HTTP_STATE* state = NULL; /* 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 URL", 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); /* Always read-only */ write_access = 0; /* Open file in read-only mode, to check for existence and get length */ if((ncstat = nc_http_init(&state))) { H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "cannot access object", NULL); } if((ncstat = nc_http_size(state,name,&len))) { H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "cannot access object", NULL); } /* Build the return value */ if(NULL == (file = (H5FD_http_t *)H5allocate_memory(sizeof(H5FD_http_t),0))) { nc_http_close(state); H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL); } /* end if */ memset(file,0,sizeof(H5FD_http_t)); file->op = H5FD_HTTP_OP_SEEK; file->pos = HADDR_UNDEF; file->write_access = write_access; /* Note the write_access for later */ file->eof = (haddr_t)len; file->state = state; state = NULL; file->url = H5allocate_memory(strlen(name)+1,0); if(file->url == NULL) { nc_http_close(state); H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL); } memcpy(file->url,name,strlen(name)+1); return((H5FD_t*)file); } /* end H5FD_HTTP_OPen() */ /*------------------------------------------------------------------------- * Function: H5F_http_close * * Purpose: Closes a file. * * Errors: * IO CLOSEERROR Fclose failed. * * Return: Non-negative on success/Negative on failure * * Programmer: Dennis Heimbigner * *------------------------------------------------------------------------- */ static herr_t H5FD_http_close(H5FD_t *_file) { H5FD_http_t *file = (H5FD_http_t*)_file; #if 0 static const char *func = "H5FD_http_close"; /* Function Name for error reporting */ #endif /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Close the underlying curl handle*/ if(file->state) nc_http_close(file->state); if(file->url) H5free_memory(file->url); H5free_memory(file); return 0; } /* end H5FD_http_close() */ /*------------------------------------------------------------------------- * Function: H5FD_http_cmp * * Purpose: Compares two files belonging to this driver using an * arbitrary (but consistent) ordering. * * Return: * Success: A value like strcmp() * * Failure: never fails (arguments were checked by the caller). * * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ static int H5FD_http_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { const H5FD_http_t *f1 = (const H5FD_http_t*)_f1; const H5FD_http_t *f2 = (const H5FD_http_t*)_f2; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); if(strcmp(f1->url,f2->url) < 0) return -1; if(strcmp(f1->url,f2->url) > 0) return 1; return 0; } /* H5FD_http_cmp() */ /*------------------------------------------------------------------------- * Function: H5FD_http_query * * Purpose: Set the flags that this VFL driver is capable of supporting. * (listed in H5FDpublic.h) * * Return: Success: non-negative * * Failure: negative * * Programmer: Quincey Koziol * Friday, August 25, 2000 * *------------------------------------------------------------------------- */ static herr_t H5FD_http_query(const H5FD_t *_f, unsigned long /*OUT*/ *flags) { /* Quiet the compiler */ _f=_f; /* Set the VFL feature flags that this driver supports. * * Note that this VFD does not support SWMR due to the unpredictable * nature of the buffering layer. */ if(flags) { *flags = 0; *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */ *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ #ifndef H5FDCLASS1 *flags |= H5FD_FEAT_DEFAULT_VFD_COMPATIBLE; /* VFD creates a file which can be opened with the default VFD */ #endif } return 0; } /* end H5FD_http_query() */ /*------------------------------------------------------------------------- * Function: H5FD_http_alloc * * Purpose: Allocates file memory. If fseeko isn't available, makes * sure the file size isn't bigger than 2GB because the * parameter OFFSET of fseek is of the type LONG INT, limiting * the file size to 2GB. * * Return: * Success: Address of new memory * * Failure: HADDR_UNDEF * * Programmer: Raymond Lu * 30 March 2007 * *------------------------------------------------------------------------- */ static haddr_t H5FD_http_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, hsize_t size) { H5FD_http_t *file = (H5FD_http_t*)_file; haddr_t addr; /* Quiet compiler */ type = type; dxpl_id = dxpl_id; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Compute the address for the block to allocate */ addr = file->eoa; file->eoa = addr + size; return addr; } /* end H5FD_http_alloc() */ /*------------------------------------------------------------------------- * Function: H5FD_http_get_eoa * * Purpose: Gets the end-of-address marker for the file. The EOA marker * is the first address past the last byte allocated in the * format address space. * * Return: Success: The end-of-address marker. * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Monday, August 2, 1999 * *------------------------------------------------------------------------- */ static haddr_t H5FD_http_get_eoa(const H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type) { const H5FD_http_t *file = (const H5FD_http_t *)_file; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Quiet compiler */ type = type; return file->eoa; } /* end H5FD_http_get_eoa() */ /*------------------------------------------------------------------------- * Function: H5FD_http_set_eoa * * Purpose: Set the end-of-address marker for the file. This function is * called shortly after an existing HDF5 file is opened in order * to tell the driver where the end of the HDF5 data is located. * * Return: Success: 0 * * Failure: Does not fail * * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ static herr_t H5FD_http_set_eoa(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, haddr_t addr) { H5FD_http_t *file = (H5FD_http_t*)_file; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Quiet the compiler */ type = type; file->eoa = addr; return 0; } /*------------------------------------------------------------------------- * Function: H5FD_http_get_eof * * Purpose: Returns the end-of-file marker, which is the greater of * either the Unix end-of-file or the HDF5 end-of-address * markers. * * Return: Success: End of file address, the first address past * the end of the "file", either the Unix file * or the HDF5 file. * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ static haddr_t #ifdef H5FDCLASS1 H5FD_http_get_eof(const H5FD_t *_file) #else H5FD_http_get_eof(const H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type) #endif { const H5FD_http_t *file = (const H5FD_http_t *)_file; #ifndef H5FDCLASS1 /* Quiet the compiler */ type = type; #endif /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); return(file->eof); } /* end H5FD_http_get_eof() */ /*------------------------------------------------------------------------- * Function: H5FD_http_get_handle * * Purpose: Returns the file handle of file driver. * * Returns: Non-negative if succeed or negative if fails. * * Programmer: Raymond Lu * Sept. 16, 2002 * *------------------------------------------------------------------------- */ static herr_t H5FD_http_get_handle(H5FD_t *_file, hid_t /*UNUSED*/ fapl, void **file_handle) { H5FD_http_t *file = (H5FD_http_t *)_file; static const char *func = "H5FD_http_get_handle"; /* Function Name for error reporting */ /* Quiet the compiler */ fapl = fapl; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); *file_handle = file->state; if(*file_handle == NULL) H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "get handle failed", -1); return 0; } /* end H5FD_http_get_handle() */ /*------------------------------------------------------------------------- * Function: H5FD_http_read * * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and * places them in buffer BUF. Reading past the logical or * physical end of file returns zeros instead of failing. * * Errors: * IO READERROR fread failed. * IO SEEKERROR fseek failed. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Wednesday, October 22, 1997 * *------------------------------------------------------------------------- */ static herr_t H5FD_http_read(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, haddr_t addr, size_t size, void /*OUT*/ *buf) { H5FD_http_t *file = (H5FD_http_t*)_file; static const char *func = "H5FD_http_read"; /* Function Name for error reporting */ int ncstat = NC_NOERR; /* Quiet the compiler */ type = type; dxpl_id = dxpl_id; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Check for overflow */ if (HADDR_UNDEF==addr) H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); if (REGION_OVERFLOW(addr, size)) H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); /* Check easy cases */ if (0 == size) return 0; if ((haddr_t)addr >= file->eof) { memset(buf, 0, size); return 0; } /* Seek to the correct file position. */ if (!(file->op == H5FD_HTTP_OP_READ || file->op == H5FD_HTTP_OP_SEEK) || file->pos != addr) { #if 0 if (file_fseek(file->fp, (file_offset_t)addr, SEEK_SET) < 0) { file->op = H5FD_HTTP_OP_UNKNOWN; file->pos = HADDR_UNDEF; H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1); } #endif file->pos = addr; } /* Read zeros past the logical end of file (physical is handled below) */ if (addr + size > file->eof) { size_t nbytes = (size_t) (addr + size - file->eof); memset((unsigned char *)buf + size - nbytes, 0, nbytes); size -= nbytes; } { NCbytes* bbuf = ncbytesnew(); if((ncstat = nc_http_read(file->state,file->url,addr,size,bbuf))) { file->op = H5FD_HTTP_OP_UNKNOWN; file->pos = HADDR_UNDEF; ncbytesfree(bbuf); bbuf = NULL; H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_READERROR, "HTTP byte-range read failed", -1); } /* end if */ /* Check that proper number of bytes was read */ if(ncbyteslength(bbuf) != size) { ncbytesfree(bbuf); bbuf = NULL; H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_READERROR, "HTTP byte-range read mismatch ", -1); } /* Extract the data from buf */ memcpy(buf,ncbytescontents(bbuf),size); ncbytesfree(bbuf); } /* Update the file position data. */ file->op = H5FD_HTTP_OP_READ; file->pos = addr; return 0; } /*------------------------------------------------------------------------- * Function: H5FD_http_write * * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at * file address ADDR. * * Errors: * IO SEEKERROR fseek failed. * IO WRITEERROR fwrite failed. * * Return: Non-negative on success/Negative on failure * * Programmer: Dennis Heimbigner * *------------------------------------------------------------------------- */ static herr_t H5FD_http_write(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, haddr_t addr, size_t size, const void *buf) { static const char *func = "H5FD_http_write"; /* Function Name for error reporting */ /* Quiet the compiler */ dxpl_id = dxpl_id; type = type; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Always Fails */ H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "file is read-only", -1); return 0; } /*------------------------------------------------------------------------- * Function: H5FD_http_flush * * Purpose: Makes sure that all data is on disk. * * Errors: * IO SEEKERROR fseek failed. * IO WRITEERROR fflush or fwrite failed. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Wednesday, October 22, 1997 * *------------------------------------------------------------------------- */ static herr_t #ifdef H5FDCLASS1 H5FD_http_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing) #else H5FD_http_flush(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, hbool_t closing) #endif { #ifndef H5FDCLASS1 /* Quiet the compiler */ dxpl_id = dxpl_id; #endif /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); return 0; } /* end H5FD_http_flush() */ /*------------------------------------------------------------------------- * Function: H5FD_http_lock * * Purpose: Lock a file via flock * NOTE: This function is a no-op if flock() is not present. * * Errors: * IO FCNTL flock failed. * * Return: Non-negative on success/Negative on failure * * Programmer: Vailin Choi; March 2015 * *------------------------------------------------------------------------- */ static herr_t #ifdef H5FDCLASS1 H5FD_http_lock(H5FD_t *_file, unsigned char* old, unsigned lock_type, hbool_t last) #else H5FD_http_lock(H5FD_t *_file, hbool_t rw) #endif { /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); #ifdef H5FDCLASS1 /* Quiet the compiler */ lock_type = lock_type; last = last; #else rw = rw; #endif return 0; } /* end H5FD_http_lock() */ /*------------------------------------------------------------------------- * Function: H5F_http_unlock * * Purpose: Unlock a file via flock * NOTE: This function is a no-op if flock() is not present. * * Errors: * IO FCNTL flock failed. * * Return: Non-negative on success/Negative on failure * * Programmer: Vailin Choi; March 2015 * *------------------------------------------------------------------------- */ static herr_t #ifdef H5FDCLASS1 H5FD_http_unlock(H5FD_t *file, /*UNUSED*/unsigned char *oid, /*UNUSED*/ hbool_t last) #else H5FD_http_unlock(H5FD_t *_file) #endif { /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Quiet the compiler */ #ifdef H5FDCLASS1 oid = oid; last = last; #endif return 0; } /* end H5FD_http_unlock() */ #ifdef _H5private_H /* * This is not related to the functionality of the driver code. * It is added here to trigger warning if HDF5 private definitions are included * by mistake. The code should use only HDF5 public API and definitions. */ #error "Do not use HDF5 private definitions" #endif