- next is 1.4.56
[lighttpd.git] / src / stream.c
blob9099bf67dc1e30c0f6dc668773717e8a3216e639
1 #include "first.h"
3 #include "stream.h"
5 #include <sys/types.h>
6 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <stdlib.h>
12 #include "sys-mmap.h"
14 #ifndef O_BINARY
15 # define O_BINARY 0
16 #endif
18 /* don't want to block when open()ing a fifo */
19 #if defined(O_NONBLOCK)
20 # define FIFO_NONBLOCK O_NONBLOCK
21 #else
22 # define FIFO_NONBLOCK 0
23 #endif
25 int stream_open(stream *f, const buffer *fn) {
27 #if !defined(__WIN32)
29 struct stat st;
30 int fd;
32 f->start = NULL;
33 f->size = 0;
34 f->mapped = 0;
36 if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY | FIFO_NONBLOCK))) {
37 return -1;
40 if (-1 == fstat(fd, &st)) {
41 close(fd);
42 return -1;
45 if (0 == st.st_size) {
46 /* empty file doesn't need a mapping */
47 close(fd);
48 return 0;
51 f->start = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
53 if (MAP_FAILED == f->start) {
54 f->start = malloc((size_t)st.st_size);
55 if (NULL == f->start
56 || st.st_size != read(fd, f->start, (size_t)st.st_size)) {
57 free(f->start);
58 f->start = NULL;
59 close(fd);
60 return -1;
62 } else {
63 f->mapped = 1;
66 close(fd);
68 f->size = st.st_size;
69 return 0;
71 #elif defined __WIN32
73 HANDLE *fh, *mh;
74 void *p;
75 LARGE_INTEGER fsize;
77 f->start = NULL;
78 f->size = 0;
80 fh = CreateFile(fn->ptr,
81 GENERIC_READ,
82 FILE_SHARE_READ,
83 NULL,
84 OPEN_EXISTING,
85 FILE_ATTRIBUTE_READONLY,
86 NULL);
88 if (!fh) return -1;
90 if (0 != GetFileSizeEx(fh, &fsize)) {
91 CloseHandle(fh);
92 return -1;
95 if (0 == fsize) {
96 CloseHandle(fh);
97 return 0;
100 mh = CreateFileMapping( fh,
101 NULL,
102 PAGE_READONLY,
103 (sizeof(off_t) > 4) ? fsize >> 32 : 0,
104 fsize & 0xffffffff,
105 NULL);
107 if (!mh) {
109 LPVOID lpMsgBuf;
110 FormatMessage(
111 FORMAT_MESSAGE_ALLOCATE_BUFFER |
112 FORMAT_MESSAGE_FROM_SYSTEM,
113 NULL,
114 GetLastError(),
115 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
116 (LPTSTR) &lpMsgBuf,
117 0, NULL );
119 CloseHandle(fh);
120 return -1;
123 p = MapViewOfFile(mh,
124 FILE_MAP_READ,
128 CloseHandle(mh);
129 CloseHandle(fh);
131 f->start = p;
132 f->size = (off_t)fsize;
133 return 0;
135 #endif
139 int stream_close(stream *f) {
140 #ifdef HAVE_MMAP
141 if (f->start) {
142 if (f->mapped) {
143 f->mapped = 0;
144 munmap(f->start, f->size);
145 } else {
146 free(f->start);
149 #elif defined(__WIN32)
150 if (f->start) UnmapViewOfFile(f->start);
151 #endif
153 f->start = NULL;
154 f->size = 0;
156 return 0;