summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--src/stream.c60
2 files changed, 45 insertions, 16 deletions
diff --git a/NEWS b/NEWS
index 37034312..8b394859 100644
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,7 @@ NEWS
* [mod_status] use snprintf() instead of sprintf()
* pass buf size to li_tohex()
* use li_[iu]tostrn() instead of li_[iu]tostr()
+ * [stream] fstat() after open() to obtain file size
- 1.4.39 - 2016-01-02
* [core] fix memset_s call (fixes #2698)
diff --git a/src/stream.c b/src/stream.c
index 51a27676..a17079c0 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -14,32 +14,38 @@
# define O_BINARY 0
#endif
+/* don't want to block when open()ing a fifo */
+#if defined(O_NONBLOCK)
+# define FIFO_NONBLOCK O_NONBLOCK
+#else
+# define FIFO_NONBLOCK 0
+#endif
+
int stream_open(stream *f, buffer *fn) {
- struct stat st;
+
#ifdef HAVE_MMAP
+
+ struct stat st;
int fd;
-#elif defined __WIN32
- HANDLE *fh, *mh;
- void *p;
-#endif
f->start = NULL;
f->size = 0;
- if (-1 == stat(fn->ptr, &st)) {
+ if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY | FIFO_NONBLOCK))) {
+ return -1;
+ }
+
+ if (-1 == fstat(fd, &st)) {
+ close(fd);
return -1;
}
if (0 == st.st_size) {
/* empty file doesn't need a mapping */
+ close(fd);
return 0;
}
-#ifdef HAVE_MMAP
- if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY))) {
- return -1;
- }
-
f->start = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
@@ -49,7 +55,18 @@ int stream_open(stream *f, buffer *fn) {
return -1;
}
+ f->size = st.st_size;
+ return 0;
+
#elif defined __WIN32
+
+ HANDLE *fh, *mh;
+ void *p;
+ LARGE_INTEGER fsize;
+
+ f->start = NULL;
+ f->size = 0;
+
fh = CreateFile(fn->ptr,
GENERIC_READ,
FILE_SHARE_READ,
@@ -60,11 +77,21 @@ int stream_open(stream *f, buffer *fn) {
if (!fh) return -1;
+ if (0 != GetFileSizeEx(fh, &fsize)) {
+ CloseHandle(fh);
+ return -1;
+ }
+
+ if (0 == fsize) {
+ CloseHandle(fh);
+ return 0;
+ }
+
mh = CreateFileMapping( fh,
NULL,
PAGE_READONLY,
- (sizeof(off_t) > 4) ? st.st_size >> 32 : 0,
- st.st_size & 0xffffffff,
+ (sizeof(off_t) > 4) ? fsize >> 32 : 0,
+ fsize & 0xffffffff,
NULL);
if (!mh) {
@@ -79,6 +106,7 @@ int stream_open(stream *f, buffer *fn) {
(LPTSTR) &lpMsgBuf,
0, NULL );
*/
+ CloseHandle(fh);
return -1;
}
@@ -91,13 +119,13 @@ int stream_open(stream *f, buffer *fn) {
CloseHandle(fh);
f->start = p;
+ f->size = (off_t)fsize;
+ return 0;
+
#else
# error no mmap found
#endif
- f->size = st.st_size;
-
- return 0;
}
int stream_close(stream *f) {