1#include "stream.h"
2
3#include <sys/types.h>
4#include <sys/stat.h>
5
6#include <unistd.h>
7#include <fcntl.h>
8
9#include "sys-mmap.h"
10
11#ifndef O_BINARY
12# define O_BINARY 0
13#endif
14
15int stream_open(stream *f, buffer *fn) {
16	struct stat st;
17#ifdef HAVE_MMAP
18	int fd;
19#elif defined __WIN32
20	HANDLE *fh, *mh;
21	void *p;
22#endif
23
24	f->start = NULL;
25	f->size = 0;
26
27	if (-1 == stat(fn->ptr, &st)) {
28		return -1;
29	}
30
31	if (0 == st.st_size) {
32		/* empty file doesn't need a mapping */
33		return 0;
34	}
35
36#ifdef HAVE_MMAP
37	if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY))) {
38		return -1;
39	}
40
41	f->start = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
42
43	close(fd);
44
45	if (MAP_FAILED == f->start) {
46		f->start = NULL;
47		return -1;
48	}
49
50#elif defined __WIN32
51	fh = CreateFile(fn->ptr,
52			GENERIC_READ,
53			FILE_SHARE_READ,
54			NULL,
55			OPEN_EXISTING,
56			FILE_ATTRIBUTE_READONLY,
57			NULL);
58
59	if (!fh) return -1;
60
61	mh = CreateFileMapping( fh,
62			NULL,
63			PAGE_READONLY,
64			(sizeof(off_t) > 4) ? st.st_size >> 32 : 0,
65			st.st_size & 0xffffffff,
66			NULL);
67
68	if (!mh) {
69/*
70		LPVOID lpMsgBuf;
71		FormatMessage(
72		        FORMAT_MESSAGE_ALLOCATE_BUFFER |
73		        FORMAT_MESSAGE_FROM_SYSTEM,
74		        NULL,
75		        GetLastError(),
76		        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
77		        (LPTSTR) &lpMsgBuf,
78		        0, NULL );
79*/
80		return -1;
81	}
82
83	p = MapViewOfFile(mh,
84			FILE_MAP_READ,
85			0,
86			0,
87			0);
88	CloseHandle(mh);
89	CloseHandle(fh);
90
91	f->start = p;
92#else
93# error no mmap found
94#endif
95
96	f->size = st.st_size;
97
98	return 0;
99}
100
101int stream_close(stream *f) {
102#ifdef HAVE_MMAP
103	if (f->start) munmap(f->start, f->size);
104#elif defined(__WIN32)
105	if (f->start) UnmapViewOfFile(f->start);
106#endif
107
108	f->start = NULL;
109	f->size = 0;
110
111	return 0;
112}
113