Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/iobuffer.c @ 92:a73e43fa20e0 HEAD
warn if io_buffer_create_mmap() contains invalid size parameter
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 29 Aug 2002 01:52:57 +0300 |
parents | 954aadb2b2c2 |
children | 9b87ee7cc19f |
rev | line source |
---|---|
0 | 1 /* |
2 iobuffer.c : Input/output transmit buffer handling | |
3 | |
4 Copyright (c) 2002 Timo Sirainen | |
5 | |
6 Permission is hereby granted, free of charge, to any person obtaining | |
7 a copy of this software and associated documentation files (the | |
8 "Software"), to deal in the Software without restriction, including | |
9 without limitation the rights to use, copy, modify, merge, publish, | |
10 distribute, sublicense, and/or sell copies of the Software, and to | |
11 permit persons to whom the Software is furnished to do so, subject to | |
12 the following conditions: | |
13 | |
14 The above copyright notice and this permission notice shall be | |
15 included in all copies or substantial portions of the Software. | |
16 | |
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
20 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
21 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
22 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
23 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
24 */ | |
25 | |
26 #include "lib.h" | |
27 #include "ioloop.h" | |
28 #include "iobuffer.h" | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
29 #include "mmap-util.h" |
58
8aaa39e7aec8
sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
56
diff
changeset
|
30 #include "sendfile-util.h" |
0 | 31 #include "network.h" |
32 | |
33 #include <unistd.h> | |
34 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
35 static unsigned int mmap_pagesize = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
36 static unsigned int mmap_pagemask = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
37 |
0 | 38 IOBuffer *io_buffer_create(int fd, Pool pool, int priority, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
39 unsigned int max_buffer_size) |
0 | 40 { |
41 IOBuffer *buf; | |
42 | |
43 i_assert(fd >= 0); | |
44 i_assert(pool != NULL); | |
45 | |
46 buf = p_new(pool, IOBuffer, 1); | |
47 buf->fd = fd; | |
48 buf->pool = pool; | |
49 buf->priority = priority; | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
50 buf->max_buffer_size = max_buffer_size; |
0 | 51 return buf; |
52 } | |
53 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
54 IOBuffer *io_buffer_create_file(int fd, Pool pool, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
55 unsigned int max_buffer_size) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
56 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
57 IOBuffer *buf; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
58 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
59 buf = io_buffer_create(fd, pool, IO_PRIORITY_DEFAULT, max_buffer_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
60 buf->file = TRUE; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
61 return buf; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
62 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
63 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
64 IOBuffer *io_buffer_create_mmap(int fd, Pool pool, unsigned int block_size, |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
65 uoff_t size) |
0 | 66 { |
67 IOBuffer *buf; | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
68 off_t start_offset, stop_offset; |
0 | 69 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
70 /* block size must be page aligned, and at least two pages long */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
71 if (mmap_pagesize == 0) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
72 mmap_pagesize = getpagesize(); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
73 mmap_pagemask = mmap_pagesize-1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
74 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
75 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
76 if (block_size < mmap_pagesize*2) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
77 block_size = mmap_pagesize*2; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
78 else if ((block_size & mmap_pagemask) != 0) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
79 block_size &= ~mmap_pagemask; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
80 block_size += mmap_pagesize; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
81 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
82 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
83 buf = io_buffer_create_file(fd, pool, block_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
84 buf->mmaped = TRUE; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
85 buf->receive = TRUE; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
86 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
87 /* set offsets */ |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
88 start_offset = lseek(fd, 0, SEEK_CUR); |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
89 stop_offset = lseek(fd, 0, SEEK_END); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
90 |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
91 if (start_offset < 0 || stop_offset < 0) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
92 i_error("io_buffer_create_mmap(): lseek() failed: %m"); |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
93 buf->start_offset = buf->size = 0; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
94 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
95 |
92
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
96 if (start_offset > stop_offset) |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
97 start_offset = stop_offset; |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
98 |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
99 if (size > (uoff_t) (stop_offset-start_offset)) { |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
100 i_warning("Trying to create IOBuffer with size %"UOFF_T_FORMAT |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
101 " but we have only %"UOFF_T_FORMAT" bytes available " |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
102 "in file", size, stop_offset-start_offset); |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
103 size = stop_offset-start_offset; |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
104 } |
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
105 |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
106 buf->start_offset = start_offset; |
92
a73e43fa20e0
warn if io_buffer_create_mmap() contains invalid size parameter
Timo Sirainen <tss@iki.fi>
parents:
84
diff
changeset
|
107 buf->size = size > 0 ? size : stop_offset - start_offset; |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
108 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
109 buf->skip = buf->pos = buf->start_offset; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
110 return buf; |
0 | 111 } |
112 | |
113 void io_buffer_destroy(IOBuffer *buf) | |
114 { | |
115 if (buf == NULL) | |
116 return; | |
117 | |
118 if (buf->io != NULL) | |
119 io_remove(buf->io); | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
120 if (buf->buffer != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
121 if (!buf->mmaped) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
122 p_free(buf->pool, buf->buffer); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
123 else |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
124 (void)munmap(buf->buffer, buf->buffer_size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
125 } |
0 | 126 p_free(buf->pool, buf); |
127 } | |
128 | |
129 void io_buffer_close(IOBuffer *buf) | |
130 { | |
131 if (buf == NULL) | |
132 return; | |
133 | |
134 buf->closed = TRUE; | |
135 } | |
136 | |
137 void io_buffer_reset(IOBuffer *buf) | |
138 { | |
139 buf->pos = buf->skip = buf->cr_lookup_pos = 0; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
140 buf->last_cr = FALSE; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
141 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
142 if (buf->mmaped && buf->buffer != NULL) { |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
143 (void)munmap(buf->buffer, buf->buffer_size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
144 buf->buffer = NULL; |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
145 buf->buffer_size = 0; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
146 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
147 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
148 buf->mmap_offset = buf->offset = 0; |
0 | 149 } |
150 | |
151 IOBuffer *io_buffer_set_pool(IOBuffer *buf, Pool pool) | |
152 { | |
153 IOBuffer *newbuf; | |
154 | |
155 i_assert(buf != NULL); | |
156 i_assert(pool != NULL); | |
157 | |
158 newbuf = p_new(pool, IOBuffer, 1); | |
159 memcpy(newbuf, buf, sizeof(IOBuffer)); | |
160 | |
161 newbuf->pool = pool; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
162 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
163 if (!newbuf->mmaped) { |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
164 newbuf->buffer = p_malloc(pool, buf->buffer_size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
165 memcpy(newbuf->buffer, buf->buffer + buf->skip, |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
166 buf->buffer_size - buf->skip); |
0 | 167 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
168 newbuf->cr_lookup_pos -= newbuf->skip; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
169 newbuf->pos -= newbuf->skip; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
170 newbuf->skip = 0; |
0 | 171 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
172 p_free(buf->pool, buf->buffer); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
173 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
174 |
0 | 175 p_free(buf->pool, buf); |
176 return newbuf; | |
177 } | |
178 | |
179 void io_buffer_set_max_size(IOBuffer *buf, unsigned int max_size) | |
180 { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
181 i_assert(!buf->mmaped); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
182 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
183 buf->max_buffer_size = max_size; |
0 | 184 } |
185 | |
186 void io_buffer_set_send_blocking(IOBuffer *buf, unsigned int max_size, | |
187 int timeout_msecs, TimeoutFunc timeout_func, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
188 void *context) |
0 | 189 { |
190 i_assert(!buf->receive); | |
191 | |
192 buf->transmit = TRUE; | |
193 buf->timeout_msecs = timeout_msecs; | |
194 buf->timeout_func = timeout_func; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
195 buf->timeout_context = context; |
0 | 196 buf->blocking = max_size > 0; |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
197 buf->max_buffer_size = max_size; |
0 | 198 } |
199 | |
200 static int my_write(int fd, const void *buf, unsigned int size) | |
201 { | |
202 int ret; | |
203 | |
204 i_assert(size <= INT_MAX); | |
205 | |
206 if (size == 0) | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
207 return 0; |
0 | 208 |
209 ret = write(fd, buf, size); | |
210 if (ret < 0 && (errno == EINTR || errno == EAGAIN)) | |
211 ret = 0; | |
212 | |
213 return ret; | |
214 } | |
215 | |
216 static void buf_send_real(IOBuffer *buf) | |
217 { | |
218 int ret; | |
219 | |
220 if (!buf->file) { | |
221 ret = net_transmit(buf->fd, buf->buffer + buf->skip, | |
222 buf->pos - buf->skip); | |
223 } else { | |
224 ret = my_write(buf->fd, buf->buffer + buf->skip, | |
225 buf->pos - buf->skip); | |
226 } | |
227 | |
228 if (ret < 0) { | |
229 buf->closed = TRUE; | |
230 } else { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
231 buf->offset += ret; |
0 | 232 buf->skip += ret; |
233 if (buf->skip == buf->pos) { | |
234 /* everything sent */ | |
235 buf->skip = buf->pos = 0; | |
236 | |
237 /* call flush function */ | |
238 if (buf->flush_func != NULL) { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
239 buf->flush_func(buf->flush_context, buf); |
0 | 240 buf->flush_func = NULL; |
241 | |
242 if (buf->corked) { | |
243 /* remove cork */ | |
244 net_set_cork(buf->fd, FALSE); | |
245 buf->corked = FALSE; | |
246 } | |
247 } | |
248 } | |
249 } | |
250 } | |
251 | |
252 static int buf_send(IOBuffer *buf) | |
253 { | |
254 buf_send_real(buf); | |
255 | |
256 if (buf->closed || buf->pos == 0) { | |
257 io_remove(buf->io); | |
258 buf->io = NULL; | |
259 return FALSE; | |
260 } | |
261 | |
262 return TRUE; | |
263 } | |
264 | |
265 typedef struct { | |
266 IOLoop ioloop; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
267 IOBuffer *outbuf; |
0 | 268 |
269 const char *data; | |
270 unsigned int size; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
271 IOBuffer *inbuf; |
0 | 272 |
273 int timeout; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
274 } IOBufferBlockContext; |
0 | 275 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
276 static void block_loop_send(IOBufferBlockContext *ctx) |
0 | 277 { |
278 int ret; | |
279 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
280 if (ctx->outbuf->skip != ctx->outbuf->pos) { |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
281 buf_send_real(ctx->outbuf); |
0 | 282 } else { |
283 /* send the data */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
284 ret = !ctx->outbuf->file ? |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
285 net_transmit(ctx->outbuf->fd, ctx->data, ctx->size) : |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
286 my_write(ctx->outbuf->fd, ctx->data, ctx->size); |
0 | 287 |
288 if (ret < 0) { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
289 ctx->outbuf->closed = TRUE; |
0 | 290 } else { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
291 ctx->outbuf->offset += ret; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
292 ctx->data += ret; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
293 ctx->size -= ret; |
0 | 294 } |
295 } | |
296 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
297 if (ctx->outbuf->closed || ctx->size == 0) |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
298 io_loop_stop(ctx->ioloop); |
0 | 299 } |
300 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
301 static void block_loop_timeout(void *context, Timeout timeout __attr_unused__) |
0 | 302 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
303 IOBufferBlockContext *ctx = context; |
0 | 304 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
305 ctx->timeout = TRUE; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
306 io_loop_stop(ctx->ioloop); |
0 | 307 } |
308 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
309 static int io_buffer_ioloop(IOBuffer *buf, IOBufferBlockContext *ctx, |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
310 void (*send_func)(IOBufferBlockContext *ctx)) |
0 | 311 { |
312 Timeout to; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
313 int save_errno; |
0 | 314 |
315 /* close old IO */ | |
316 if (buf->io != NULL) | |
317 io_remove(buf->io); | |
318 | |
319 /* create a new I/O loop */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
320 ctx->ioloop = io_loop_create(); |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
321 ctx->outbuf = buf; |
0 | 322 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
323 buf->io = io_add(buf->fd, IO_WRITE, (IOFunc) send_func, ctx); |
0 | 324 to = buf->timeout_msecs <= 0 ? NULL : |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
325 timeout_add(buf->timeout_msecs, block_loop_timeout, ctx); |
0 | 326 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
327 io_loop_run(ctx->ioloop); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
328 save_errno = errno; |
0 | 329 |
330 if (buf->corked) { | |
331 /* remove cork */ | |
332 net_set_cork(buf->fd, FALSE); | |
333 buf->corked = FALSE; | |
334 } | |
335 | |
336 if (buf->io != NULL) { | |
337 io_remove(buf->io); | |
338 buf->io = NULL; | |
339 } | |
340 | |
341 if (to != NULL) { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
342 if (ctx->timeout && buf->timeout_func != NULL) { |
0 | 343 /* call user-given timeout function */ |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
344 buf->timeout_func(buf->timeout_context, to); |
0 | 345 } |
346 timeout_remove(to); | |
347 } | |
348 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
349 io_loop_destroy(ctx->ioloop); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
350 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
351 errno = save_errno; |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
352 return ctx->size > 0 ? -1 : 1; |
0 | 353 } |
354 | |
355 static int io_buffer_send_blocking(IOBuffer *buf, const void *data, | |
356 unsigned int size) | |
357 { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
358 IOBufferBlockContext ctx; |
0 | 359 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
360 memset(&ctx, 0, sizeof(ctx)); |
0 | 361 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
362 ctx.data = data; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
363 ctx.size = size; |
0 | 364 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
365 return io_buffer_ioloop(buf, &ctx, block_loop_send); |
0 | 366 } |
367 | |
368 void io_buffer_cork(IOBuffer *buf) | |
369 { | |
370 i_assert(!buf->receive); | |
371 | |
372 if (!buf->file && !buf->corked) { | |
373 net_set_cork(buf->fd, TRUE); | |
374 buf->corked = TRUE; | |
375 } | |
376 } | |
377 | |
378 static void buffer_alloc_more(IOBuffer *buf, unsigned int size) | |
379 { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
380 i_assert(!buf->mmaped); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
381 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
382 buf->buffer_size = buf->pos+size; |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
383 buf->buffer_size = |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
384 buf->buffer_size <= IO_BUFFER_MIN_SIZE ? IO_BUFFER_MIN_SIZE : |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
385 nearest_power(buf->buffer_size); |
0 | 386 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
387 if (buf->max_buffer_size > 0 && buf->buffer_size > buf->max_buffer_size) |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
388 buf->buffer_size = buf->max_buffer_size; |
0 | 389 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
390 buf->buffer = p_realloc(buf->pool, buf->buffer, buf->buffer_size); |
0 | 391 if (buf->buffer == NULL) { |
392 /* pool limit exceeded */ | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
393 buf->pos = buf->buffer_size = 0; |
0 | 394 } |
395 } | |
396 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
397 static void io_buffer_compress(IOBuffer *buf) |
0 | 398 { |
399 memmove(buf->buffer, buf->buffer + buf->skip, | |
400 buf->pos - buf->skip); | |
401 buf->pos -= buf->skip; | |
402 | |
403 if (buf->skip > buf->cr_lookup_pos) | |
404 buf->cr_lookup_pos = 0; | |
405 else | |
406 buf->cr_lookup_pos -= buf->skip; | |
407 | |
408 buf->skip = 0; | |
409 } | |
410 | |
411 int io_buffer_send(IOBuffer *buf, const void *data, unsigned int size) | |
412 { | |
413 int ret; | |
414 | |
415 i_assert(!buf->receive); | |
416 i_assert(data != NULL); | |
417 i_assert(size < INT_MAX); | |
418 buf->transmit = TRUE; | |
419 | |
420 if (buf->closed) | |
421 return -1; | |
422 | |
423 if (buf->pos == 0) { | |
424 /* buffer is empty, try to send the data immediately */ | |
425 ret = buf->file ? my_write(buf->fd, data, size) : | |
426 net_transmit(buf->fd, data, size); | |
427 if (ret < 0) { | |
428 /* disconnected */ | |
429 buf->closed = TRUE; | |
430 return -1; | |
431 } | |
432 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
433 buf->offset += ret; |
0 | 434 data = (const char *) data + ret; |
39 | 435 size -= ret; |
436 } | |
437 | |
438 if (size == 0) { | |
439 /* all sent */ | |
440 return 1; | |
0 | 441 } |
442 | |
443 if (io_buffer_get_space(buf, size) == NULL) { | |
444 if (buf->blocking) { | |
445 /* if we don't have space, we block */ | |
446 return io_buffer_send_blocking(buf, data, size); | |
447 } | |
448 return -2; | |
449 } | |
450 | |
451 /* add to buffer */ | |
452 memcpy(buf->buffer + buf->pos, data, size); | |
453 buf->pos += size; | |
454 | |
455 if (buf->io == NULL) { | |
456 buf->io = io_add_priority(buf->fd, buf->priority, IO_WRITE, | |
457 (IOFunc) buf_send, buf); | |
458 } | |
459 return 1; | |
460 } | |
461 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
462 static void block_loop_sendfile(IOBufferBlockContext *ctx) |
0 | 463 { |
464 int ret; | |
465 | |
56 | 466 i_assert(ctx->inbuf->offset < OFF_T_MAX); |
467 | |
58
8aaa39e7aec8
sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
56
diff
changeset
|
468 ret = safe_sendfile(ctx->outbuf->fd, ctx->inbuf->fd, |
8aaa39e7aec8
sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
56
diff
changeset
|
469 &ctx->inbuf->offset, ctx->size); |
0 | 470 if (ret < 0) { |
471 if (errno != EINTR && errno != EAGAIN) | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
472 ctx->outbuf->closed = TRUE; |
0 | 473 ret = 0; |
474 } | |
475 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
476 ctx->size -= ret; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
477 if (ctx->outbuf->closed || ctx->size == 0) |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
478 io_loop_stop(ctx->ioloop); |
0 | 479 } |
480 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
481 static int io_buffer_sendfile(IOBuffer *outbuf, IOBuffer *inbuf, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
482 unsigned int size) |
0 | 483 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
484 IOBufferBlockContext ctx; |
0 | 485 int ret; |
486 | |
56 | 487 i_assert(inbuf->offset < OFF_T_MAX); |
488 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
489 io_buffer_send_flush(outbuf); |
0 | 490 |
491 /* first try if we can do it with a single sendfile() call */ | |
58
8aaa39e7aec8
sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
56
diff
changeset
|
492 ret = safe_sendfile(outbuf->fd, inbuf->fd, &inbuf->offset, size); |
0 | 493 if (ret < 0) { |
494 if (errno != EINTR && errno != EAGAIN) | |
495 return -1; | |
496 ret = 0; | |
497 } | |
498 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
499 if ((unsigned int) ret == size) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
500 /* yes, all sent */ |
0 | 501 return 1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
502 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
503 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
504 memset(&ctx, 0, sizeof(ctx)); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
505 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
506 ctx.inbuf = inbuf; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
507 ctx.size = size - ret; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
508 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
509 ret = io_buffer_ioloop(outbuf, &ctx, block_loop_sendfile); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
510 if (ret < 0 && errno == EINVAL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
511 /* this shouldn't happen, must be a bug. It would also |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
512 mess up later if we let this pass. */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
513 i_fatal("io_buffer_sendfile() failed: %m"); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
514 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
515 return ret; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
516 } |
0 | 517 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
518 static void block_loop_copy(IOBufferBlockContext *ctx) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
519 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
520 unsigned char *in_data; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
521 unsigned int size; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
522 int ret; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
523 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
524 while ((ret = io_buffer_read_data(ctx->inbuf, &in_data, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
525 &size, 0)) <= 0) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
526 if (ret == -1) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
527 /* disconnected */ |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
528 ctx->outbuf->closed = TRUE; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
529 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
530 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
531 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
532 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
533 /* send the data */ |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
534 ctx->data = (const char *) in_data; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
535 ctx->size = size; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
536 block_loop_send(ctx); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
537 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
538 io_buffer_skip(ctx->inbuf, size - ctx->size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
539 } |
0 | 540 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
541 int io_buffer_send_buf(IOBuffer *outbuf, IOBuffer *inbuf, unsigned int size) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
542 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
543 IOBufferBlockContext ctx; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
544 unsigned char *in_data; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
545 unsigned int in_size; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
546 int ret; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
547 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
548 i_assert(size < INT_MAX); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
549 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
550 ret = io_buffer_sendfile(outbuf, inbuf, size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
551 if (ret >= 0 || errno != EINVAL) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
552 return ret; |
0 | 553 |
58
8aaa39e7aec8
sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
56
diff
changeset
|
554 /* sendfile() not supported (with this fd), fallback to |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
555 regular sending */ |
58
8aaa39e7aec8
sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
56
diff
changeset
|
556 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
557 /* see if we can do it at one go */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
558 ret = io_buffer_read_data(inbuf, &in_data, &in_size, 0); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
559 if (ret == -1) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
560 return -1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
561 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
562 ret = !outbuf->file ? |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
563 net_transmit(outbuf->fd, in_data, in_size) : |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
564 my_write(outbuf->fd, in_data, in_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
565 if (ret < 0) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
566 return -1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
567 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
568 outbuf->offset += ret; |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
569 io_buffer_skip(inbuf, (unsigned int)ret); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
570 if ((unsigned int) ret == size) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
571 /* all sent */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
572 return 1; |
0 | 573 } |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
574 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
575 /* create blocking send loop */ |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
576 memset(&ctx, 0, sizeof(ctx)); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
577 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
578 ctx.inbuf = inbuf; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
579 ctx.size = size; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
580 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
581 return io_buffer_ioloop(outbuf, &ctx, block_loop_copy); |
0 | 582 } |
583 | |
584 void io_buffer_send_flush(IOBuffer *buf) | |
585 { | |
586 i_assert(!buf->receive); | |
587 | |
588 if (buf->closed || buf->io == NULL) | |
589 return; | |
590 | |
591 if (buf->skip != buf->pos) | |
592 io_buffer_send_blocking(buf, NULL, 0); | |
593 } | |
594 | |
595 void io_buffer_send_flush_callback(IOBuffer *buf, IOBufferFlushFunc func, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
596 void *context) |
0 | 597 { |
598 i_assert(!buf->receive); | |
599 | |
600 if (buf->skip == buf->pos) { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
601 func(context, buf); |
0 | 602 return; |
603 } | |
604 | |
605 buf->flush_func = func; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
606 buf->flush_context = context; |
0 | 607 } |
608 | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
609 static int io_buffer_read_mmaped(IOBuffer *buf, unsigned int size) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
610 { |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
611 uoff_t stop_offset; |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
612 unsigned int aligned_skip; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
613 |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
614 stop_offset = buf->start_offset + buf->size; |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
615 if (stop_offset - buf->mmap_offset <= buf->buffer_size) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
616 /* end of file is already mapped */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
617 return -1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
618 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
619 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
620 aligned_skip = buf->skip & ~mmap_pagemask; |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
621 if (aligned_skip == 0 && buf->buffer != NULL) { |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
622 /* didn't skip enough bytes */ |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
623 return -2; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
624 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
625 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
626 buf->skip -= aligned_skip; |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
627 buf->mmap_offset += aligned_skip; |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
628 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
629 if (buf->buffer != NULL) |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
630 (void)munmap(buf->buffer, buf->buffer_size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
631 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
632 buf->buffer_size = stop_offset - buf->mmap_offset; |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
633 if (buf->buffer_size > buf->max_buffer_size) |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
634 buf->buffer_size = buf->max_buffer_size; |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
635 if (buf->buffer_size > size) |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
636 buf->buffer_size = size; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
637 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
638 buf->buffer = mmap(NULL, buf->buffer_size, PROT_READ, MAP_PRIVATE, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
639 buf->fd, buf->mmap_offset); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
640 if (buf->buffer == MAP_FAILED) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
641 i_error("io_buffer_read_mmaped(): mmap() failed: %m"); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
642 return -1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
643 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
644 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
645 (void)madvise(buf->buffer, buf->buffer_size, MADV_SEQUENTIAL); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
646 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
647 buf->pos = buf->buffer_size; |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
648 return buf->buffer_size; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
649 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
650 |
0 | 651 int io_buffer_read_max(IOBuffer *buf, unsigned int size) |
652 { | |
653 int ret; | |
654 | |
655 i_assert(size <= INT_MAX || size == UINT_MAX); | |
656 i_assert(!buf->transmit); | |
657 buf->receive = TRUE; | |
658 | |
659 if (buf->closed) | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
660 return -1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
661 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
662 if (buf->mmaped) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
663 return io_buffer_read_mmaped(buf, size); |
0 | 664 |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
665 if (buf->pos == buf->buffer_size) { |
0 | 666 if (buf->skip > 0) { |
667 /* remove the unused bytes from beginning of buffer */ | |
668 io_buffer_compress(buf); | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
669 } else if (buf->max_buffer_size == 0 || |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
670 buf->buffer_size < buf->max_buffer_size) { |
0 | 671 /* buffer is full - grow it */ |
672 buffer_alloc_more(buf, IO_BUFFER_MIN_SIZE); | |
673 } | |
674 | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
675 if (buf->pos == buf->buffer_size) |
0 | 676 return -2; /* buffer full */ |
677 } | |
678 | |
679 /* fill the buffer */ | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
680 if (buf->buffer_size-buf->pos < size) |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
681 size = buf->buffer_size - buf->pos; |
0 | 682 |
683 if (!buf->file) { | |
684 ret = net_receive(buf->fd, buf->buffer + buf->pos, | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
685 buf->buffer_size - buf->pos); |
0 | 686 } else { |
687 ret = read(buf->fd, buf->buffer + buf->pos, | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
688 buf->buffer_size - buf->pos); |
0 | 689 if (ret == 0) |
690 ret = -1; /* EOF */ | |
691 else if (ret < 0 && (errno == EINTR || errno == EAGAIN)) | |
692 ret = 0; | |
693 } | |
694 | |
695 if (ret < 0) { | |
696 /* disconnected */ | |
697 return -1; | |
698 } | |
699 | |
700 buf->pos += ret; | |
701 return ret; | |
702 } | |
703 | |
704 int io_buffer_read(IOBuffer *buf) | |
705 { | |
706 return io_buffer_read_max(buf, UINT_MAX); | |
707 } | |
708 | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
709 void io_buffer_skip(IOBuffer *buf, uoff_t size) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
710 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
711 int ret; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
712 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
713 buf->offset += size; |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
714 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
715 if (size <= buf->pos - buf->skip) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
716 buf->skip += size; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
717 return; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
718 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
719 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
720 if (buf->mmaped) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
721 /* these point outside mmap now, next io_buffer_read_mmaped() |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
722 will fix them */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
723 buf->skip += size; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
724 buf->pos = buf->skip; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
725 } else { |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
726 if (buf->buffer_size == 0) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
727 buffer_alloc_more(buf, IO_BUFFER_MIN_SIZE); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
728 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
729 size -= buf->skip; |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
730 while (size > buf->buffer_size) { |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
731 ret = io_buffer_read_max(buf, buf->buffer_size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
732 if (ret <= 0) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
733 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
734 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
735 size -= ret; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
736 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
737 |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
738 (void)io_buffer_read_max(buf, (unsigned int)size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
739 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
740 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
741 |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
742 int io_buffer_seek(IOBuffer *buf, uoff_t offset) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
743 { |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
744 uoff_t real_offset; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
745 |
75
7418fefb57a8
IOBuffer was buggy if start_offset wasn't 0
Timo Sirainen <tss@iki.fi>
parents:
63
diff
changeset
|
746 real_offset = buf->start_offset + offset; |
7418fefb57a8
IOBuffer was buggy if start_offset wasn't 0
Timo Sirainen <tss@iki.fi>
parents:
63
diff
changeset
|
747 if (real_offset > OFF_T_MAX) { |
7418fefb57a8
IOBuffer was buggy if start_offset wasn't 0
Timo Sirainen <tss@iki.fi>
parents:
63
diff
changeset
|
748 errno = EINVAL; |
7418fefb57a8
IOBuffer was buggy if start_offset wasn't 0
Timo Sirainen <tss@iki.fi>
parents:
63
diff
changeset
|
749 return FALSE; |
7418fefb57a8
IOBuffer was buggy if start_offset wasn't 0
Timo Sirainen <tss@iki.fi>
parents:
63
diff
changeset
|
750 } |
7418fefb57a8
IOBuffer was buggy if start_offset wasn't 0
Timo Sirainen <tss@iki.fi>
parents:
63
diff
changeset
|
751 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
752 if (buf->mmaped) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
753 /* first reset everything */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
754 io_buffer_reset(buf); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
755 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
756 /* then set the wanted position, next read will |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
757 pick up from there */ |
75
7418fefb57a8
IOBuffer was buggy if start_offset wasn't 0
Timo Sirainen <tss@iki.fi>
parents:
63
diff
changeset
|
758 buf->pos = buf->skip = real_offset; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
759 } else { |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
760 if (lseek(buf->fd, (off_t)real_offset, SEEK_SET) != |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
39
diff
changeset
|
761 (off_t)real_offset) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
762 return FALSE; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
763 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
764 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
765 buf->offset = offset; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
766 return TRUE; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
767 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
768 |
0 | 769 /* skip the first LF, if it exists */ |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
770 static void io_buffer_skip_lf(IOBuffer *buf) |
0 | 771 { |
772 if (!buf->last_cr || buf->skip >= buf->pos) | |
773 return; | |
774 | |
775 if (buf->buffer[buf->skip] == 10) { | |
776 if (buf->skip == buf->cr_lookup_pos) | |
777 buf->cr_lookup_pos++; | |
778 buf->skip++; | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
779 buf->offset++; |
0 | 780 } |
781 buf->last_cr = FALSE; | |
782 } | |
783 | |
784 char *io_buffer_next_line(IOBuffer *buf) | |
785 { | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
786 /* FIXME: buf->offset isn't updated right.. (skip_lf thing?) */ |
0 | 787 unsigned char *ret_buf; |
788 unsigned int i; | |
789 | |
790 i_assert(buf != NULL); | |
791 | |
792 io_buffer_skip_lf(buf); | |
793 if (buf->skip >= buf->pos) | |
794 return NULL; | |
795 | |
796 ret_buf = NULL; | |
797 for (i = buf->cr_lookup_pos; i < buf->pos; i++) { | |
798 if (buf->buffer[i] == 13 || buf->buffer[i] == 10) { | |
799 /* got it */ | |
800 buf->last_cr = buf->buffer[i] == 13; | |
801 buf->buffer[i] = '\0'; | |
802 ret_buf = buf->buffer + buf->skip; | |
803 | |
804 i++; | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
805 buf->offset += i - buf->skip; |
0 | 806 buf->skip = i; |
807 break; | |
808 } | |
809 } | |
810 | |
811 buf->cr_lookup_pos = i; | |
63 | 812 return ret_buf; |
0 | 813 } |
814 | |
815 unsigned char *io_buffer_get_data(IOBuffer *buf, unsigned int *size) | |
816 { | |
817 io_buffer_skip_lf(buf); | |
818 | |
819 if (buf->skip >= buf->pos) { | |
820 *size = 0; | |
821 return NULL; | |
822 } | |
823 | |
824 *size = buf->pos - buf->skip; | |
825 return buf->buffer + buf->skip; | |
826 } | |
827 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
828 int io_buffer_read_data(IOBuffer *buf, unsigned char **data, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
829 unsigned int *size, unsigned int threshold) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
830 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
831 int ret; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
832 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
833 if (buf->pos - buf->skip <= threshold) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
834 /* we need more data */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
835 ret = io_buffer_read(buf); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
836 if (ret <= 0) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
837 *size = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
838 *data = NULL; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
839 return ret; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
840 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
841 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
842 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
843 *data = io_buffer_get_data(buf, size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
844 return 1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
845 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
846 |
0 | 847 unsigned char *io_buffer_get_space(IOBuffer *buf, unsigned int size) |
848 { | |
39 | 849 i_assert(size > 0); |
0 | 850 i_assert(size <= INT_MAX); |
851 i_assert(!buf->receive); | |
852 buf->transmit = TRUE; | |
853 | |
854 /* make sure we have enough space in buffer */ | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
855 if (buf->buffer_size - buf->pos < size && buf->skip > 0) { |
0 | 856 /* remove the unused bytes from beginning of buffer */ |
857 io_buffer_compress(buf); | |
858 } | |
859 | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
860 if (buf->buffer_size - buf->pos < size && |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
861 (buf->max_buffer_size == 0 || |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
862 size <= buf->max_buffer_size - buf->pos)) { |
0 | 863 /* allocate more space */ |
864 buffer_alloc_more(buf, size); | |
865 } | |
866 | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
867 if (buf->buffer_size - buf->pos < size) |
0 | 868 return NULL; |
869 | |
870 return buf->buffer + buf->pos; | |
871 } | |
872 | |
873 int io_buffer_send_buffer(IOBuffer *buf, unsigned int size) | |
874 { | |
875 int ret; | |
876 | |
877 i_assert(size <= INT_MAX); | |
878 i_assert(!buf->receive); | |
879 | |
880 if (buf->pos == 0) { | |
881 /* buffer is empty, try to send the data immediately */ | |
882 ret = buf->file ? my_write(buf->fd, buf->buffer, size) : | |
883 net_transmit(buf->fd, buf->buffer, size); | |
884 if (ret < 0) { | |
885 /* disconnected */ | |
886 buf->closed = TRUE; | |
887 return -1; | |
888 } | |
889 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
890 buf->offset += ret; |
0 | 891 if ((unsigned int) ret == size) { |
892 /* all sent */ | |
893 return 1; | |
894 } | |
895 | |
896 buf->skip += ret; | |
897 } | |
898 | |
899 buf->pos += size; | |
900 | |
901 if (buf->io == NULL) { | |
902 buf->io = io_add_priority(buf->fd, buf->priority, IO_WRITE, | |
903 (IOFunc) buf_send, buf); | |
904 } | |
905 | |
906 return 1; | |
907 } | |
908 | |
909 int io_buffer_set_data(IOBuffer *buf, const void *data, unsigned int size) | |
910 { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
911 i_assert(!buf->mmaped); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
912 |
0 | 913 io_buffer_reset(buf); |
914 | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
915 if (buf->buffer_size < size) { |
0 | 916 buffer_alloc_more(buf, size); |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
917 if (buf->buffer_size < size) |
0 | 918 return -2; |
919 } | |
920 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
921 buf->offset += size; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
922 buf->offset -= buf->pos - buf->skip; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
923 |
0 | 924 memcpy(buf->buffer, data, size); |
925 buf->pos = size; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
926 buf->skip = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
927 return 1; |
0 | 928 } |
929 | |
930 int io_buffer_is_empty(IOBuffer *buf) | |
931 { | |
932 return buf->skip >= buf->pos; | |
933 } |