summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5FDstream.c310
-rw-r--r--src/H5FDstream.h39
2 files changed, 257 insertions, 92 deletions
diff --git a/src/H5FDstream.c b/src/H5FDstream.c
index 469e43c..733a550 100644
--- a/src/H5FDstream.c
+++ b/src/H5FDstream.c
@@ -11,18 +11,20 @@
* entire HDF5 data file to be processed in main memory.
* In addition to that, the memory image of the file is
* read from/written to a socket during an open/flush operation.
+ *
+ * Version: $Id$
+ *
+ * Modifications:
+ * Thomas Radke, Thursday, October 26, 2000
+ * Added support for Windows.
+ * Catch SIGPIPE on an open socket.
+ *
*/
-/* for windows platform, use winsock.h */
-#ifdef WIN32
-#include <winsock.h>
-#else
-#include <netdb.h> /* gethostbyname */
-#include <sys/types.h> /* socket stuff */
-#include <sys/socket.h> /* socket stuff */
-#include <netinet/in.h> /* socket stuff */
-#include <netinet/tcp.h> /* socket stuff */
-#endif
+#include <H5pubconf.h> /* H5_HAVE_STREAM */
+
+/* Only build this driver if it was configured with --with-Stream-VFD */
+#ifdef H5_HAVE_STREAM
#include <H5Eprivate.h> /* error handling */
#include <H5FDpublic.h> /* VFD structures */
@@ -30,19 +32,44 @@
#include <H5Ppublic.h> /* files */
#include <H5FDstream.h> /* Stream VFD header */
+#ifdef H5FD_STREAM_HAVE_UNIX_SOCKETS
+#include <sys/types.h> /* socket stuff */
+#include <sys/socket.h> /* socket stuff */
+#include <netdb.h> /* gethostbyname */
+#include <netinet/in.h> /* socket stuff */
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h> /* socket stuff */
+#endif
+#endif
-/* Only build this driver if it was configured with --with-Stream-VFD */
-#ifdef H5_HAVE_STREAM
/* Some useful macros */
-#undef MAX
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
+#ifdef MIN
#undef MIN
+#endif
+#ifdef MAX
+#undef MAX
+#endif
#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
/* Uncomment this to switch on debugging output */
/* #define DEBUG 1 */
+/* Define some socket stuff which is different for UNIX and Windows */
+#ifdef H5FD_STREAM_HAVE_UNIX_SOCKETS
+#define H5FD_STREAM_CLOSE_SOCKET(a) close(a)
+#define H5FD_STREAM_IOCTL_SOCKET(a, b, c) ioctl(a, b, c)
+#define H5FD_STREAM_INVALID_SOCKET -1
+#define H5FD_STREAM_ERROR_CHECK(rc) ((rc) < 0)
+#else
+#define H5FD_STREAM_CLOSE_SOCKET(a) closesocket (a)
+#define H5FD_STREAM_IOCTL_SOCKET(a, b, c) ioctlsocket (a, b, (u_long *) (c))
+#define H5FD_STREAM_INVALID_SOCKET SOCKET_ERROR
+#define H5FD_STREAM_ERROR_CHECK(rc) ((rc) == (SOCKET) (SOCKET_ERROR))
+#endif
+
+
/* The driver identification number, initialized at runtime */
static hid_t H5FD_STREAM_g = 0;
@@ -58,7 +85,7 @@ typedef struct H5FD_stream_t
unsigned char *mem; /* the underlying memory */
haddr_t eoa; /* end of allocated region */
haddr_t eof; /* current allocated size */
- int socket; /* socket to write / read from */
+ H5FD_STREAM_SOCKET_TYPE socket; /* socket to write / read from */
hbool_t dirty; /* flag indicating unflushed data */
hbool_t internal_socket; /* flag indicating an internal socket */
} H5FD_stream_t;
@@ -73,7 +100,7 @@ typedef struct H5FD_stream_t
static const H5FD_stream_fapl_t default_fapl =
{
H5FD_STREAM_INCREMENT, /* address space allocation blocksize */
- -1, /* no external socket descriptor */
+ H5FD_STREAM_INVALID_SOCKET, /* no external socket descriptor */
TRUE, /* enable I/O on socket */
H5FD_STREAM_BACKLOG, /* default backlog for listen(2) */
NULL, /* do not broadcast received files */
@@ -117,7 +144,8 @@ static herr_t H5FD_stream_query(const H5FD_t *_f1, unsigned long *flags);
static haddr_t H5FD_stream_get_eoa (H5FD_t *_stream);
static herr_t H5FD_stream_set_eoa (H5FD_t *_stream, haddr_t addr);
static haddr_t H5FD_stream_get_eof (H5FD_t *_stream);
-static herr_t H5FD_stream_read (H5FD_t *_stream, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
+static herr_t H5FD_stream_read (H5FD_t *_stream, H5FD_mem_t type,
+ hid_t fapl_id, haddr_t addr,
hsize_t size, void *buf);
static herr_t H5FD_stream_write (H5FD_t *_stream, H5FD_mem_t type,
hid_t fapl_id, haddr_t addr,
@@ -141,7 +169,7 @@ static const H5FD_class_t H5FD_stream_g =
H5FD_stream_open, /* open */
H5FD_stream_close, /* close */
NULL, /* cmp */
- H5FD_stream_query, /*query */
+ H5FD_stream_query, /*query */
NULL, /* alloc */
NULL, /* free */
H5FD_stream_get_eoa, /* get_eoa */
@@ -178,8 +206,20 @@ hid_t H5FD_stream_init (void)
FUNC_ENTER (H5FD_stream_init, FAIL);
if (H5I_VFL != H5Iget_type (H5FD_STREAM_g))
+ {
H5FD_STREAM_g = H5FDregister (&H5FD_stream_g);
+ /* set the process signal mask to ignore SIGPIPE signals */
+ /* NOTE: Windows doesn't know SIGPIPE signals that's why the #ifdef */
+#ifdef SIGPIPE
+ if (signal (SIGPIPE, SIG_IGN) == SIG_ERR)
+ {
+ fprintf (stderr, "Stream VFD warning: failed to set the process signal "
+ "mask to ignore SIGPIPE signals\n");
+ }
+#endif
+ }
+
FUNC_LEAVE (H5FD_STREAM_g);
}
@@ -190,7 +230,7 @@ hid_t H5FD_stream_init (void)
* Purpose: Modify the file access property list to use the Stream
* driver defined in this source file. The INCREMENT specifies
* how much to grow the memory each time we need more.
- * If a valid SOCKET argument is given this will be used
+ * If a valid socket argument is given this will be used
* by the driver instead of parsing the 'hostname:port' filename
* and opening a socket internally.
*
@@ -214,13 +254,17 @@ herr_t H5Pset_fapl_stream (hid_t fapl_id, H5FD_stream_fapl_t *fapl)
H5TRACE2 ("e", "ix", fapl_id, fapl);
if (H5P_FILE_ACCESS != H5Pget_class (fapl_id))
+ {
HRETURN_ERROR (H5E_PLIST, H5E_BADTYPE, FAIL, "not a fapl");
+ }
if (fapl)
{
if (! fapl->do_socket_io && fapl->broadcast_fn == NULL)
+ {
HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
"read broadcast function pointer is NULL");
+ }
user_fapl = *fapl;
if (fapl->increment == 0)
@@ -262,14 +306,22 @@ herr_t H5Pget_fapl_stream(hid_t fapl_id, H5FD_stream_fapl_t *fapl /* out */)
H5TRACE2("e","ix",fapl_id,fapl);
if (H5P_FILE_ACCESS != H5Pget_class (fapl_id))
+ {
HRETURN_ERROR (H5E_PLIST, H5E_BADTYPE, FAIL, "not a fapl");
+ }
if (H5FD_STREAM != H5Pget_driver (fapl_id))
+ {
HRETURN_ERROR (H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver");
+ }
if (NULL == (this_fapl = H5Pget_driver_info (fapl_id)))
+ {
HRETURN_ERROR (H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info");
+ }
if (fapl)
+ {
*fapl = *this_fapl;
+ }
FUNC_LEAVE (SUCCEED);
}
@@ -299,7 +351,9 @@ static void *H5FD_stream_fapl_get (H5FD_t *_stream)
FUNC_ENTER (H5FD_stream_fapl_get, NULL);
if ((fapl = H5MM_calloc (sizeof (H5FD_stream_fapl_t))) == NULL)
+ {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ }
*fapl = stream->fapl;
@@ -307,21 +361,22 @@ static void *H5FD_stream_fapl_get (H5FD_t *_stream)
}
-static int H5FDstream_open_socket(const char *filename, int o_flags,
- unsigned int backlog,
- const char **errormsg,
- H5E_major_t *major, H5E_minor_t *minor)
+static H5FD_STREAM_SOCKET_TYPE
+H5FDstream_open_socket (const char *filename, int o_flags,
+ unsigned int backlog,
+ const char **errormsg,
+ H5E_major_t *major, H5E_minor_t *minor)
{
- struct sockaddr_in sin;
+ struct sockaddr_in server;
struct hostent *he;
unsigned short int port;
- int sock;
+ H5FD_STREAM_SOCKET_TYPE sock;
char *hostname;
const char *separator, *tmp;
- const int on = 1;
+ int on = 1;
- sock = -1;
+ sock = H5FD_STREAM_INVALID_SOCKET;
*errormsg = NULL;
/* Parse "hostname:port" from filename argument */
@@ -333,7 +388,7 @@ static int H5FDstream_open_socket(const char *filename, int o_flags,
else
{
tmp = separator;
- if (! tmp [1])
+ if (! tmp[1])
{
*errormsg = "no port number";
}
@@ -364,43 +419,61 @@ static int H5FDstream_open_socket(const char *filename, int o_flags,
}
strncpy (hostname, filename, separator - filename);
- hostname [separator - filename] = 0;
+ hostname[separator - filename] = 0;
port = atoi (separator + 1);
- memset (&sin, 0, sizeof (sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons (port);
+ memset (&server, 0, sizeof (server));
+ server.sin_family = AF_INET;
+ server.sin_port = htons (port);
if (! (he = gethostbyname (hostname)))
+ {
*errormsg = "unable to get host address";
- else if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ }
+ else if (H5FD_STREAM_ERROR_CHECK (sock = socket (AF_INET, SOCK_STREAM, 0)))
+ {
*errormsg = "unable to open socket";
+ }
if (*errormsg == NULL)
{
if (O_RDONLY == o_flags)
{
- memcpy (&sin.sin_addr, he->h_addr, he->h_length);
+ memcpy (&server.sin_addr, he->h_addr, he->h_length);
#ifdef DEBUG
fprintf (stderr, "Stream VFD: connecting to host '%s' port %d\n",
hostname, port);
#endif
- if (connect (sock, (struct sockaddr *) &sin, sizeof (sin)) < 0)
+ if (connect (sock, (struct sockaddr *) &server, sizeof (server)) < 0)
+ {
*errormsg = "unable to connect";
+ }
}
else
{
- sin.sin_addr.s_addr = INADDR_ANY;
- if (fcntl (sock, F_SETFL, O_NONBLOCK) < 0)
+ server.sin_addr.s_addr = INADDR_ANY;
+ if (H5FD_STREAM_IOCTL_SOCKET (sock, FIONBIO, &on) < 0)
+ {
*errormsg = "unable to set non-blocking mode for socket";
- else if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
+ }
+ else if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &on,
+ sizeof(on)) < 0)
+ {
*errormsg = "unable to set socket option TCP_NODELAY";
- else if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+ }
+ else if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &on,
+ sizeof(on)) < 0)
+ {
*errormsg = "unable to set socket option SO_REUSEADDR";
- else if (bind (sock, (struct sockaddr *) &sin, sizeof (sin)) < 0)
+ }
+ else if (bind (sock, (struct sockaddr *) &server, sizeof (server)) < 0)
+ {
*errormsg = "unable to bind socket";
+ }
else if (listen (sock, backlog) < 0)
+ {
*errormsg = "unable to listen on socket";
+ }
}
}
@@ -409,10 +482,10 @@ static int H5FDstream_open_socket(const char *filename, int o_flags,
/* Return if opening the socket failed */
if (*errormsg)
{
- if (sock >= 0)
+ if (H5FD_STREAM_ERROR_CHECK (sock))
{
- close (sock);
- sock = -1;
+ H5FD_STREAM_CLOSE_SOCKET (sock);
+ sock = H5FD_STREAM_INVALID_SOCKET;
}
*major = H5E_FILE; *minor = H5E_CANTOPENFILE;
}
@@ -425,11 +498,12 @@ static void H5FDstream_read_from_socket (H5FD_stream_t *stream,
const char **errormsg,
H5E_major_t *major, H5E_minor_t *minor)
{
- ssize_t size;
+ int size;
size_t max_size = 0;
unsigned char *ptr;
+ ptr = NULL;
*errormsg = NULL;
stream->eof = 0;
stream->mem = NULL;
@@ -445,8 +519,10 @@ static void H5FDstream_read_from_socket (H5FD_stream_t *stream,
*/
max_size = stream->fapl.increment;
if (! stream->mem)
+ {
max_size++;
- ptr = H5MM_realloc (stream->mem, stream->eof + max_size);
+ }
+ ptr = H5MM_realloc (stream->mem, (size_t) (stream->eof + max_size));
if (! ptr)
{
*major = H5E_RESOURCE; *minor = H5E_NOSPACE;
@@ -458,9 +534,12 @@ static void H5FDstream_read_from_socket (H5FD_stream_t *stream,
}
/* now receive the next chunk of data */
- size = read (stream->socket, ptr, max_size);
+ size = recv (stream->socket, ptr, max_size, 0);
+
if (size < 0 && (EINTR == errno || EAGAIN == errno))
+ {
continue;
+ }
if (size < 0)
{
*major = H5E_IO; *minor = H5E_READERROR;
@@ -468,13 +547,15 @@ static void H5FDstream_read_from_socket (H5FD_stream_t *stream,
return;
}
if (! size)
+ {
break;
+ }
max_size -= (size_t) size;
stream->eof += (haddr_t) size;
ptr += size;
#ifdef DEBUG
fprintf (stderr, "Stream VFD: read %d bytes (%d total) from socket\n",
- (int) size, (int) stream->eof);
+ size, (int) stream->eof);
#endif
}
@@ -513,17 +594,26 @@ static H5FD_t *H5FD_stream_open (const char *filename,
H5E_major_t major;
H5E_minor_t minor;
const char *errormsg;
+#ifdef WIN32
+ WSADATA wsadata;
+#endif
FUNC_ENTER (H5FD_stream_open, NULL);
/* Check arguments */
if (filename == NULL|| *filename == '\0')
+ {
HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, NULL,"invalid file name");
+ }
if (maxaddr == 0 || HADDR_UNDEF == maxaddr)
+ {
HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr");
+ }
if (ADDR_OVERFLOW (maxaddr))
+ {
HRETURN_ERROR (H5E_ARGS, H5E_OVERFLOW, NULL, "maxaddr overflow");
+ }
/* Build the open flags */
o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
@@ -532,13 +622,28 @@ static H5FD_t *H5FD_stream_open (const char *filename,
if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
if ((O_RDWR & o_flags) && ! (O_CREAT & o_flags))
+ {
HRETURN_ERROR (H5E_ARGS, H5E_UNSUPPORTED, NULL,
"open stream for read/write not supported");
+ }
+#ifdef WIN32
+ if (WSAStartup (MAKEWORD (2, 0), &wsadata))
+ {
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, NULL,
+ "Couldn't start Win32 socket layer");
+ }
+#endif
+
+ fapl = NULL;
if (H5P_DEFAULT != fapl_id)
+ {
fapl = H5Pget_driver_info (fapl_id);
+ }
if (fapl == NULL)
+ {
fapl = &default_fapl;
+ }
/* zero out file structure and set file access property list */
memset (&_stream, 0, sizeof (_stream));
@@ -551,7 +656,7 @@ static H5FD_t *H5FD_stream_open (const char *filename,
is opened internally */
if (fapl->do_socket_io)
{
- if (fapl->socket >= 0)
+ if (! H5FD_STREAM_ERROR_CHECK (fapl->socket))
{
_stream.internal_socket = FALSE;
_stream.socket = fapl->socket;
@@ -565,7 +670,7 @@ static H5FD_t *H5FD_stream_open (const char *filename,
}
else
{
- _stream.socket = -1;
+ _stream.socket = H5FD_STREAM_INVALID_SOCKET;
}
/* read the data from socket into memory */
@@ -605,9 +710,11 @@ static H5FD_t *H5FD_stream_open (const char *filename,
the opened socket is not needed anymore */
if (errormsg == NULL)
{
- if (_stream.internal_socket && _stream.socket >= 0)
- close (_stream.socket);
- _stream.socket = -1;
+ if (_stream.internal_socket && H5FD_STREAM_ERROR_CHECK (_stream.socket))
+ {
+ H5FD_STREAM_CLOSE_SOCKET (_stream.socket);
+ }
+ _stream.socket = H5FD_STREAM_INVALID_SOCKET;
}
}
@@ -630,9 +737,13 @@ static H5FD_t *H5FD_stream_open (const char *filename,
if (errormsg)
{
if (_stream.mem)
+ {
H5MM_xfree (_stream.mem);
- if (_stream.internal_socket && _stream.socket >= 0)
- close (_stream.socket);
+ }
+ if (_stream.internal_socket && H5FD_STREAM_ERROR_CHECK (_stream.socket))
+ {
+ H5FD_STREAM_CLOSE_SOCKET (_stream.socket);
+ }
HRETURN_ERROR (major, minor, NULL, errormsg);
}
@@ -659,56 +770,61 @@ static H5FD_t *H5FD_stream_open (const char *filename,
static herr_t H5FD_stream_flush (H5FD_t *_stream)
{
H5FD_stream_t *stream = (H5FD_stream_t *) _stream;
- haddr_t size;
+ int size;
+ int bytes_send;
+ int on = 1;
unsigned char *ptr;
struct sockaddr from;
#if !(defined(linux) || defined(sun))
typedef int socklen_t;
#endif
socklen_t fromlen;
- int sock;
+ H5FD_STREAM_SOCKET_TYPE sock;
FUNC_ENTER (H5FD_stream_flush, FAIL);
/* Write to backing store */
- if (stream->dirty && stream->socket >= 0)
+ if (stream->dirty && ! H5FD_STREAM_ERROR_CHECK (stream->socket))
{
#ifdef DEBUG
fprintf (stderr, "Stream VFD: accepting client connections\n");
#endif
fromlen = sizeof (from);
- while ((sock = accept (stream->socket, &from, &fromlen)) >= 0)
+ while (! H5FD_STREAM_ERROR_CHECK (sock = accept (stream->socket,
+ &from, &fromlen)))
{
- if (fcntl (sock, F_SETFL, O_NONBLOCK) < 0)
+ if (H5FD_STREAM_IOCTL_SOCKET (sock, FIONBIO, &on) < 0)
{
- close (sock);
+ H5FD_STREAM_CLOSE_SOCKET (sock);
continue; /* continue the loop for other clients' requests */
}
- size = stream->eof;
+ size = (int) stream->eof;
ptr = stream->mem;
while (size)
{
- ssize_t n = write (sock, ptr, size);
- if (n < 0 && (EINTR == errno || EAGAIN == errno))
+ bytes_send = send (sock, ptr, size, 0);
+ if (bytes_send < 0 && (EINTR == errno || EAGAIN == errno))
+ {
continue;
- if (n < 0)
+ }
+ if (bytes_send < 0)
{
- close (sock);
+ H5FD_STREAM_CLOSE_SOCKET (sock);
/* FIXME: continue the loop for other clients here */
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL,
"error writing to socket");
}
- ptr += (size_t) n;
- size -= (size_t) n;
+ ptr += bytes_send;
+ size -= bytes_send;
#ifdef DEBUG
fprintf (stderr, "Stream VFD: wrote %d bytes to socket, %d in total, "
- "%d left\n", (int) n, ptr - stream->mem, (int) size);
+ "%d left\n", bytes_send, (int) (ptr - stream->mem), size);
#endif
}
- close (sock);
+ H5FD_STREAM_CLOSE_SOCKET (sock);
}
stream->dirty = FALSE;
}
@@ -741,12 +857,14 @@ static herr_t H5FD_stream_close (H5FD_t *_stream)
/* Flush */
if (H5FD_stream_flush (_stream) < 0)
+ {
HRETURN_ERROR (H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file");
+ }
/* Release resources */
- if (stream->socket >= 0 && stream->internal_socket)
+ if (H5FD_STREAM_ERROR_CHECK (stream->socket) && stream->internal_socket)
{
- close (stream->socket);
+ H5FD_STREAM_CLOSE_SOCKET (stream->socket);
}
if (stream->mem)
{
@@ -776,19 +894,19 @@ static herr_t H5FD_stream_close (H5FD_t *_stream)
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5FD_stream_query(const UNUSED H5FD_t *_f, unsigned long *flags /* out */)
+static herr_t H5FD_stream_query (const UNUSED H5FD_t *_f,
+ unsigned long *flags /* out */)
{
- herr_t ret_value=SUCCEED;
-
- FUNC_ENTER(H5FD_stream_query, FAIL);
+ FUNC_ENTER (H5FD_stream_query, SUCCEED);
/* Set the VFL feature flags that this driver supports */
- if(flags) {
- *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- } /* end if */
+ if (flags)
+ {
+ /* OK to perform data sieving for faster raw data reads & writes */
+ *flags |= H5FD_FEAT_DATA_SIEVE;
+ }
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE (SUCCEED);
}
@@ -846,7 +964,9 @@ static herr_t H5FD_stream_set_eoa (H5FD_t *_stream,
FUNC_ENTER (H5FD_stream_set_eoa, FAIL);
if (ADDR_OVERFLOW (addr))
+ {
HRETURN_ERROR (H5E_ARGS, H5E_OVERFLOW, FAIL, "address overflow");
+ }
stream->eoa = addr;
@@ -910,8 +1030,8 @@ static herr_t H5FD_stream_read (H5FD_t *_stream,
hsize_t size,
void *buf /*out*/)
{
- H5FD_stream_t *stream = (H5FD_stream_t *) _stream;
- ssize_t nbytes;
+ H5FD_stream_t *stream = (H5FD_stream_t *) _stream;
+ ssize_t nbytes;
FUNC_ENTER (H5FD_stream_read, FAIL);
@@ -921,17 +1041,23 @@ static herr_t H5FD_stream_read (H5FD_t *_stream,
/* Check for overflow conditions */
if (HADDR_UNDEF == addr)
+ {
HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed");
+ }
if (REGION_OVERFLOW (addr, size))
+ {
HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed");
+ }
if (addr + size > stream->eoa)
+ {
HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed");
+ }
/* Read the part which is before the EOF marker */
if (addr < stream->eof)
{
- nbytes = MIN (size, stream->eof - addr);
- memcpy (buf, stream->mem + addr, nbytes);
+ nbytes = (ssize_t) MIN (size, stream->eof - addr);
+ memcpy (buf, stream->mem + addr, (size_t) nbytes);
size -= nbytes;
addr += nbytes;
buf = (char *) buf + nbytes;
@@ -939,7 +1065,9 @@ static herr_t H5FD_stream_read (H5FD_t *_stream,
/* Read zeros for the part which is after the EOF markers */
if (size > 0)
- memset (buf, 0, size);
+ {
+ memset (buf, 0, (size_t) size);
+ }
FUNC_LEAVE (SUCCEED);
}
@@ -979,9 +1107,13 @@ static herr_t H5FD_stream_write (H5FD_t *_stream,
/* Check for overflow conditions */
if (REGION_OVERFLOW (addr, size))
+ {
HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed");
+ }
if (addr + size > stream->eoa)
+ {
HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed");
+ }
/*
* Allocate more memory if necessary, careful of overflow. Also, if the
@@ -1002,21 +1134,23 @@ static herr_t H5FD_stream_write (H5FD_t *_stream,
}
if (stream->mem == NULL)
{
- x = H5MM_malloc (new_eof);
+ x = H5MM_malloc ((size_t) new_eof);
}
else
{
- x = H5MM_realloc (stream->mem, new_eof);
+ x = H5MM_realloc (stream->mem, (size_t) new_eof);
}
if (x == NULL)
+ {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"unable to allocate memory block");
+ }
stream->mem = x;
stream->eof = new_eof;
}
/* Write from BUF to memory */
- memcpy (stream->mem + addr, buf, size);
+ memcpy (stream->mem + addr, buf, (size_t) size);
stream->dirty = TRUE;
FUNC_LEAVE (SUCCEED);
diff --git a/src/H5FDstream.h b/src/H5FDstream.h
index c8acd65..aa0f339 100644
--- a/src/H5FDstream.h
+++ b/src/H5FDstream.h
@@ -7,30 +7,60 @@
* Tuesday, September 12, 2000
*
* Purpose: The public header file for the Stream Virtual File Driver.
+ *
+ * Version: $Header$
+ *
+ * Modifications:
+ * Thomas Radke, Thursday, October 26, 2000
+ * Added support for Windows.
+ *
*/
#ifndef H5FDstream_H
#define H5FDstream_H
#ifdef H5_HAVE_STREAM
+#include <H5pubconf.h>
#include <H5Ipublic.h>
-#ifdef __cplusplus
-extern "C" {
+/* check what sockets type we have (Unix or Windows sockets)
+ Note that only MS compilers require to use Windows sockets
+ but gcc under Windows does not. */
+#if ! defined(H5_HAVE_WINSOCK_H) || defined(__GNUC__)
+#define H5FD_STREAM_HAVE_UNIX_SOCKETS 1
+#endif
+
+/* define the data type for socket descriptors
+ and the constant indicating an invalid descriptor */
+#ifdef H5FD_STREAM_HAVE_UNIX_SOCKETS
+
+#define H5FD_STREAM_SOCKET_TYPE int
+#define H5FD_STREAM_INVALID_SOCKET -1
+
+#else
+#include <winsock.h>
+
+#define H5FD_STREAM_SOCKET_TYPE SOCKET
+#define H5FD_STREAM_INVALID_SOCKET SOCKET_ERROR
+
#endif
#define H5FD_STREAM (H5FD_stream_init())
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* prototype for read broadcast callback routine */
typedef int (*H5FD_stream_broadcast_t) (unsigned char **file,
haddr_t *len,
void *arg);
-/* Driver-specific file access properties */
+/* driver-specific file access properties */
typedef struct H5FD_stream_fapl_t
{
size_t increment; /* how much to grow memory in reallocs */
- int socket; /* external socket descriptor */
+ H5FD_STREAM_SOCKET_TYPE socket; /* external socket descriptor */
hbool_t do_socket_io; /* do I/O on socket */
unsigned int backlog; /* backlog argument for listen call */
H5FD_stream_broadcast_t broadcast_fn; /* READ broadcast callback */
@@ -38,6 +68,7 @@ typedef struct H5FD_stream_fapl_t
} H5FD_stream_fapl_t;
+/* prototypes of exported functions */
__DLL__ hid_t H5FD_stream_init (void);
__DLL__ herr_t H5Pset_fapl_stream (hid_t fapl_id,
H5FD_stream_fapl_t *fapl);