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) {