1: #include "first.h"
2:
3: #include "stream.h"
4:
5: #include <sys/types.h>
6: #include <sys/stat.h>
7:
8: #include <unistd.h>
9: #include <fcntl.h>
10:
11: #include "sys-mmap.h"
12:
13: #ifndef O_BINARY
14: # define O_BINARY 0
15: #endif
16:
17: /* don't want to block when open()ing a fifo */
18: #if defined(O_NONBLOCK)
19: # define FIFO_NONBLOCK O_NONBLOCK
20: #else
21: # define FIFO_NONBLOCK 0
22: #endif
23:
24: int stream_open(stream *f, const buffer *fn) {
25:
26: #if !defined(__WIN32)
27:
28: struct stat st;
29: int fd;
30:
31: f->start = NULL;
32: f->size = 0;
33: f->mapped = 0;
34:
35: if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY | FIFO_NONBLOCK))) {
36: return -1;
37: }
38:
39: if (-1 == fstat(fd, &st)) {
40: close(fd);
41: return -1;
42: }
43:
44: if (0 == st.st_size) {
45: /* empty file doesn't need a mapping */
46: close(fd);
47: return 0;
48: }
49:
50: f->start = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
51:
52: if (MAP_FAILED == f->start) {
53: f->start = malloc((size_t)st.st_size);
54: if (NULL == f->start
55: || st.st_size != read(fd, f->start, (size_t)st.st_size)) {
56: free(f->start);
57: f->start = NULL;
58: close(fd);
59: return -1;
60: }
61: } else {
62: f->mapped = 1;
63: }
64:
65: close(fd);
66:
67: f->size = st.st_size;
68: return 0;
69:
70: #elif defined __WIN32
71:
72: HANDLE *fh, *mh;
73: void *p;
74: LARGE_INTEGER fsize;
75:
76: f->start = NULL;
77: f->size = 0;
78:
79: fh = CreateFile(fn->ptr,
80: GENERIC_READ,
81: FILE_SHARE_READ,
82: NULL,
83: OPEN_EXISTING,
84: FILE_ATTRIBUTE_READONLY,
85: NULL);
86:
87: if (!fh) return -1;
88:
89: if (0 != GetFileSizeEx(fh, &fsize)) {
90: CloseHandle(fh);
91: return -1;
92: }
93:
94: if (0 == fsize) {
95: CloseHandle(fh);
96: return 0;
97: }
98:
99: mh = CreateFileMapping( fh,
100: NULL,
101: PAGE_READONLY,
102: (sizeof(off_t) > 4) ? fsize >> 32 : 0,
103: fsize & 0xffffffff,
104: NULL);
105:
106: if (!mh) {
107: /*
108: LPVOID lpMsgBuf;
109: FormatMessage(
110: FORMAT_MESSAGE_ALLOCATE_BUFFER |
111: FORMAT_MESSAGE_FROM_SYSTEM,
112: NULL,
113: GetLastError(),
114: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
115: (LPTSTR) &lpMsgBuf,
116: 0, NULL );
117: */
118: CloseHandle(fh);
119: return -1;
120: }
121:
122: p = MapViewOfFile(mh,
123: FILE_MAP_READ,
124: 0,
125: 0,
126: 0);
127: CloseHandle(mh);
128: CloseHandle(fh);
129:
130: f->start = p;
131: f->size = (off_t)fsize;
132: return 0;
133:
134: #endif
135:
136: }
137:
138: int stream_close(stream *f) {
139: #ifdef HAVE_MMAP
140: if (f->start) {
141: if (f->mapped) {
142: f->mapped = 0;
143: munmap(f->start, f->size);
144: } else {
145: free(f->start);
146: }
147: }
148: #elif defined(__WIN32)
149: if (f->start) UnmapViewOfFile(f->start);
150: #endif
151:
152: f->start = NULL;
153: f->size = 0;
154:
155: return 0;
156: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>