Mercurial > dovecot > core-2.2
annotate src/lib/ostream-file.c @ 22955:812e5c961328
fts: Indexing virtual mailbox didn't always index the last mails
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 03 May 2018 18:33:00 +0300 |
parents | cb108f786fb4 |
children |
rev | line source |
---|---|
22713
cb108f786fb4
Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21390
diff
changeset
|
1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
3 /* @UNSAFE: whole file */ |
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
4 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "lib.h" |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "ioloop.h" |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
7 #include "write-full.h" |
15187
02451e967a06
Renamed network.[ch] to net.[ch].
Timo Sirainen <tss@iki.fi>
parents:
14963
diff
changeset
|
8 #include "net.h" |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 #include "sendfile-util.h" |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include "istream.h" |
13529
cf77e448295c
Renamed lib/*-internal.h files to lib/*-private.h for consistency.
Timo Sirainen <tss@iki.fi>
parents:
13417
diff
changeset
|
11 #include "istream-private.h" |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
12 #include "ostream-file-private.h" |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 #include <unistd.h> |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
15 #include <sys/stat.h> |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 #ifdef HAVE_SYS_UIO_H |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 # include <sys/uio.h> |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 #endif |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
20 /* try to keep the buffer size within 4k..128k. ReiserFS may actually return |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
21 128k as optimal size. */ |
11309
88d7a36c7fa5
Use IO_BLOCK_SIZE macro to specify how large read/write syscalls to use.
Timo Sirainen <tss@iki.fi>
parents:
10847
diff
changeset
|
22 #define DEFAULT_OPTIMAL_BLOCK_SIZE IO_BLOCK_SIZE |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
23 #define MAX_OPTIMAL_BLOCK_SIZE (128*1024) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 #define IS_STREAM_EMPTY(fstream) \ |
920 | 26 ((fstream)->head == (fstream)->tail && !(fstream)->full) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 #define MAX_SSIZE_T(size) \ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 ((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 |
4907
5b4c9b20eba0
Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents:
4838
diff
changeset
|
31 static void stream_send_io(struct file_ostream *fstream); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
32 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
33 static void stream_closed(struct file_ostream *fstream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 { |
3960
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
35 if (fstream->io != NULL) |
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
36 io_remove(&fstream->io); |
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
37 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 if (fstream->autoclose_fd && fstream->fd != -1) { |
10847
5f16e488e7f6
i/ostreams can now have a name (e.g. file path).
Timo Sirainen <tss@iki.fi>
parents:
10708
diff
changeset
|
39 if (close(fstream->fd) < 0) { |
5f16e488e7f6
i/ostreams can now have a name (e.g. file path).
Timo Sirainen <tss@iki.fi>
parents:
10708
diff
changeset
|
40 i_error("file_ostream.close(%s) failed: %m", |
5f16e488e7f6
i/ostreams can now have a name (e.g. file path).
Timo Sirainen <tss@iki.fi>
parents:
10708
diff
changeset
|
41 o_stream_get_name(&fstream->ostream.ostream)); |
5f16e488e7f6
i/ostreams can now have a name (e.g. file path).
Timo Sirainen <tss@iki.fi>
parents:
10708
diff
changeset
|
42 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 } |
4766
b96086a311a9
When i/ostream is closed, change the fd to be -1 so it won't be accidentally
Timo Sirainen <tss@iki.fi>
parents:
4122
diff
changeset
|
44 fstream->fd = -1; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 fstream->ostream.ostream.closed = TRUE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
49 void o_stream_file_close(struct iostream_private *stream, |
16020
6cabb95d32ec
iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs.
Timo Sirainen <tss@iki.fi>
parents:
15913
diff
changeset
|
50 bool close_parent ATTR_UNUSED) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
52 struct file_ostream *fstream = (struct file_ostream *)stream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 /* flush output before really closing it */ |
14681
ca37d1577291
Added o_stream_nsend*() and related functions to make delayed error handling safer.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
55 (void)o_stream_flush(&fstream->ostream.ostream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 stream_closed(fstream); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
60 static void o_stream_file_destroy(struct iostream_private *stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
62 struct file_ostream *fstream = (struct file_ostream *)stream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 |
6142
6c0bfc35af03
Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents:
4938
diff
changeset
|
64 i_free(fstream->buffer); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 |
8923 | 67 static size_t file_buffer_get_used_size(struct file_ostream *fstream) |
68 { | |
69 if (fstream->head == fstream->tail) | |
70 return fstream->full ? fstream->buffer_size : 0; | |
71 else if (fstream->head < fstream->tail) { | |
72 /* ...HXXXT... */ | |
73 return fstream->tail - fstream->head; | |
74 } else { | |
75 /* XXXT...HXXX */ | |
76 return fstream->tail + | |
77 (fstream->buffer_size - fstream->head); | |
78 } | |
79 } | |
80 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
81 static void update_buffer(struct file_ostream *fstream, size_t size) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 size_t used; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 |
2647
a17d7463a4dc
If we couldn't send any bytes, don't reset buffer's full-flag.
Timo Sirainen <tss@iki.fi>
parents:
2634
diff
changeset
|
85 if (IS_STREAM_EMPTY(fstream) || size == 0) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 return; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 if (fstream->head < fstream->tail) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 /* ...HXXXT... */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 used = fstream->tail - fstream->head; |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
91 i_assert(size <= used); |
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
92 fstream->head += size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 } else { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 /* XXXT...HXXX */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 used = fstream->buffer_size - fstream->head; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 if (size > used) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 size -= used; |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
98 i_assert(size <= fstream->tail); |
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
99 fstream->head = size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 } else { |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
101 fstream->head += size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 fstream->full = FALSE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 if (fstream->head == fstream->tail) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 fstream->head = fstream->tail = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 if (fstream->head == fstream->buffer_size) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 fstream->head = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 |
4938
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
114 static void o_stream_socket_cork(struct file_ostream *fstream) |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
115 { |
10708
3b544841d5d7
ostream: If cork method isn't implemented, keep track of corking state internally.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
116 if (fstream->ostream.corked && !fstream->socket_cork_set) { |
4938
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
117 if (!fstream->no_socket_cork) { |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
118 if (net_set_cork(fstream->fd, TRUE) < 0) |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
119 fstream->no_socket_cork = TRUE; |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
120 else |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
121 fstream->socket_cork_set = TRUE; |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
122 } |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
123 } |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
124 } |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
125 |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
126 static int o_stream_lseek(struct file_ostream *fstream) |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
127 { |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
128 off_t ret; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
129 |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
130 if (fstream->real_offset == fstream->buffer_offset) |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
131 return 0; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
132 |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
133 ret = lseek(fstream->fd, (off_t)fstream->buffer_offset, SEEK_SET); |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
134 if (ret < 0) { |
16773
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
135 io_stream_set_error(&fstream->ostream.iostream, |
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
136 "lseek() failed: %m"); |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
137 fstream->ostream.ostream.stream_errno = errno; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
138 return -1; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
139 } |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
140 |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
141 if (ret != (off_t)fstream->buffer_offset) { |
16773
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
142 io_stream_set_error(&fstream->ostream.iostream, |
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
143 "lseek() returned wrong value"); |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
144 fstream->ostream.ostream.stream_errno = EINVAL; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
145 return -1; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
146 } |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
147 fstream->real_offset = fstream->buffer_offset; |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
148 return 0; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
149 } |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
150 |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
151 ssize_t o_stream_file_writev(struct file_ostream *fstream, |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
152 const struct const_iovec *iov, |
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
153 unsigned int iov_count) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
154 { |
20858
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
155 ssize_t ret; |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
156 size_t size, sent; |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
157 unsigned int i; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
159 if (iov_count == 1) { |
14915
23e9660f0473
ostream-file: Fixed writing with zero buffer size.
Timo Sirainen <tss@iki.fi>
parents:
14851
diff
changeset
|
160 i_assert(iov->iov_len > 0); |
23e9660f0473
ostream-file: Fixed writing with zero buffer size.
Timo Sirainen <tss@iki.fi>
parents:
14851
diff
changeset
|
161 |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
162 if (!fstream->file || |
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
163 fstream->real_offset == fstream->buffer_offset) { |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
164 ret = write(fstream->fd, iov->iov_base, iov->iov_len); |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
165 if (ret > 0) |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
166 fstream->real_offset += ret; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
167 } else { |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
168 ret = pwrite(fstream->fd, iov->iov_base, iov->iov_len, |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
169 fstream->buffer_offset); |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
170 } |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
171 } else { |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
172 if (o_stream_lseek(fstream) < 0) |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
173 return -1; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
174 |
20858
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
175 sent = 0; |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
176 while (iov_count > IOV_MAX) { |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
177 size = 0; |
3623
085ebc6e341c
Use IOV_MAX instead of UIO_MAXIOV when available.
Timo Sirainen <tss@iki.fi>
parents:
3618
diff
changeset
|
178 for (i = 0; i < IOV_MAX; i++) |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
179 size += iov[i].iov_len; |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
180 |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
181 ret = writev(fstream->fd, (const struct iovec *)iov, |
3623
085ebc6e341c
Use IOV_MAX instead of UIO_MAXIOV when available.
Timo Sirainen <tss@iki.fi>
parents:
3618
diff
changeset
|
182 IOV_MAX); |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
183 if (ret != (ssize_t)size) { |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
184 break; |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
185 } |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
186 |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
187 fstream->real_offset += ret; |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
188 fstream->buffer_offset += ret; |
2471
4fa0f02369b1
o_stream_sendv() returned wrong value if sending more than UIO_MAXIOV
Timo Sirainen <tss@iki.fi>
parents:
2432
diff
changeset
|
189 sent += ret; |
3623
085ebc6e341c
Use IOV_MAX instead of UIO_MAXIOV when available.
Timo Sirainen <tss@iki.fi>
parents:
3618
diff
changeset
|
190 iov += IOV_MAX; |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
191 iov_count -= IOV_MAX; |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
192 } |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
193 |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
194 if (iov_count <= IOV_MAX) { |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
195 size = 0; |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
196 for (i = 0; i < iov_count; i++) |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
197 size += iov[i].iov_len; |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
198 |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
199 ret = writev(fstream->fd, (const struct iovec *)iov, |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
200 iov_count); |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
201 } |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
202 if (ret > 0) { |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
203 fstream->real_offset += ret; |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
204 ret += sent; |
7061
4ff39d30aa4a
If writev() fails for non-file and nothing was sent, return failure instead
Timo Sirainen <tss@iki.fi>
parents:
6851
diff
changeset
|
205 } else if (!fstream->file && sent > 0) { |
6851
6a9080055e54
Handle write failures with files better.
Timo Sirainen <tss@iki.fi>
parents:
6849
diff
changeset
|
206 /* return what we managed to get sent */ |
6254
28b9873da2cc
If we do multiple writev() calls and the last one fails, we shouldn't treat
Timo Sirainen <tss@iki.fi>
parents:
6164
diff
changeset
|
207 ret = sent; |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
208 } |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
209 } |
20858
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
210 return ret; |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
211 } |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
212 |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
213 static ssize_t |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
214 o_stream_file_writev_full(struct file_ostream *fstream, |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
215 const struct const_iovec *iov, |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
216 unsigned int iov_count) |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
217 { |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
218 ssize_t ret, ret2; |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
219 size_t size, total_size; |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
220 bool partial; |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
221 unsigned int i; |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
222 |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
223 for (i = 0, total_size = 0; i < iov_count; i++) |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
224 total_size += iov[i].iov_len; |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
225 |
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
226 o_stream_socket_cork(fstream); |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
227 ret = fstream->writev(fstream, iov, iov_count); |
20858
decbc9f93ddf
lib: ostream-file: Split o_stream_file_writev() from o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20857
diff
changeset
|
228 partial = ret != (ssize_t)total_size; |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
229 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
230 if (ret < 0) { |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
231 if (fstream->file) { |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
232 if (errno == EINTR) { |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
233 /* automatically retry */ |
20857
45e7b2203260
lib: ostream-file: Renamed o_stream_writev() to o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20856
diff
changeset
|
234 return o_stream_file_writev_full(fstream, iov, iov_count); |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
235 } |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
236 } else if (errno == EAGAIN || errno == EINTR) { |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
237 /* try again later */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
238 return 0; |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
239 } |
1224
b661eb87bd26
if connection was closed while trying to write data to client, we sometimes
Timo Sirainen <tss@iki.fi>
parents:
1207
diff
changeset
|
240 fstream->ostream.ostream.stream_errno = errno; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 stream_closed(fstream); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 return -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
243 } |
6851
6a9080055e54
Handle write failures with files better.
Timo Sirainen <tss@iki.fi>
parents:
6849
diff
changeset
|
244 if (unlikely(ret == 0 && fstream->file)) { |
6a9080055e54
Handle write failures with files better.
Timo Sirainen <tss@iki.fi>
parents:
6849
diff
changeset
|
245 /* assume out of disk space */ |
6a9080055e54
Handle write failures with files better.
Timo Sirainen <tss@iki.fi>
parents:
6849
diff
changeset
|
246 fstream->ostream.ostream.stream_errno = ENOSPC; |
6a9080055e54
Handle write failures with files better.
Timo Sirainen <tss@iki.fi>
parents:
6849
diff
changeset
|
247 stream_closed(fstream); |
6a9080055e54
Handle write failures with files better.
Timo Sirainen <tss@iki.fi>
parents:
6849
diff
changeset
|
248 return -1; |
6a9080055e54
Handle write failures with files better.
Timo Sirainen <tss@iki.fi>
parents:
6849
diff
changeset
|
249 } |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
250 fstream->buffer_offset += ret; |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
251 if (partial && fstream->file) { |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
252 /* we failed to write everything to a file. either we ran out |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
253 of disk space or we're writing to NFS. try to write the |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
254 rest to resolve this. */ |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
255 size = ret; |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
256 while (iov_count > 0 && size >= iov->iov_len) { |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
257 size -= iov->iov_len; |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
258 iov++; |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
259 iov_count--; |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
260 } |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
261 i_assert(iov_count > 0); |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
262 if (size == 0) |
20857
45e7b2203260
lib: ostream-file: Renamed o_stream_writev() to o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20856
diff
changeset
|
263 ret2 = o_stream_file_writev_full(fstream, iov, iov_count); |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
264 else { |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
265 /* write the first iov separately */ |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
266 struct const_iovec new_iov; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
268 new_iov.iov_base = |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
269 CONST_PTR_OFFSET(iov->iov_base, size); |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
270 new_iov.iov_len = iov->iov_len - size; |
20857
45e7b2203260
lib: ostream-file: Renamed o_stream_writev() to o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20856
diff
changeset
|
271 ret2 = o_stream_file_writev_full(fstream, &new_iov, 1); |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
272 if (ret2 > 0) { |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
273 i_assert((size_t)ret2 == new_iov.iov_len); |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
274 /* write the rest */ |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
275 if (iov_count > 1) { |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
276 ret += ret2; |
20857
45e7b2203260
lib: ostream-file: Renamed o_stream_writev() to o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20856
diff
changeset
|
277 ret2 = o_stream_file_writev_full(fstream, iov + 1, |
20856
0b861a3aceca
lib: ostream-file: Renamed iov_size to iov_count everywhere and made it unsigned int for consistency.
Stephan Bosch <stephan@rename-it.nl>
parents:
19552
diff
changeset
|
278 iov_count - 1); |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
279 } |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
280 } |
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
281 } |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
282 i_assert(ret2 != 0); |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
283 if (ret2 < 0) |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
284 ret = ret2; |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
285 else |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
286 ret += ret2; |
8124
744f9dbff89c
ostream: Make sure writing to files always fully succeeds or fails.
Timo Sirainen <tss@iki.fi>
parents:
7912
diff
changeset
|
287 } |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
288 i_assert(ret < 0 || !fstream->file || |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
289 (size_t)ret == total_size); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 return ret; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
292 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
293 /* returns how much of vector was used */ |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
294 static int o_stream_fill_iovec(struct file_ostream *fstream, |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
295 struct const_iovec iov[2]) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 if (IS_STREAM_EMPTY(fstream)) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 return 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 if (fstream->head < fstream->tail) { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
301 iov[0].iov_base = fstream->buffer + fstream->head; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
302 iov[0].iov_len = fstream->tail - fstream->head; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 return 1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
304 } else { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
305 iov[0].iov_base = fstream->buffer + fstream->head; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
306 iov[0].iov_len = fstream->buffer_size - fstream->head; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
307 if (fstream->tail == 0) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
308 return 1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 else { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
310 iov[1].iov_base = fstream->buffer; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 iov[1].iov_len = fstream->tail; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 return 2; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
316 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
317 static int buffer_flush(struct file_ostream *fstream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
319 struct const_iovec iov[2]; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
320 int iov_len; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
321 ssize_t ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
323 iov_len = o_stream_fill_iovec(fstream, iov); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
324 if (iov_len > 0) { |
20857
45e7b2203260
lib: ostream-file: Renamed o_stream_writev() to o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20856
diff
changeset
|
325 ret = o_stream_file_writev_full(fstream, iov, iov_len); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
326 if (ret < 0) |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
327 return -1; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
328 |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
329 update_buffer(fstream, ret); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
331 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
332 return IS_STREAM_EMPTY(fstream) ? 1 : 0; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
333 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
334 |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
335 static void o_stream_file_cork(struct ostream_private *stream, bool set) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
336 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
337 struct file_ostream *fstream = (struct file_ostream *)stream; |
3337
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
338 int ret; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
339 |
10708
3b544841d5d7
ostream: If cork method isn't implemented, keep track of corking state internally.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
340 if (stream->corked != set && !stream->ostream.closed) { |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
341 if (set && fstream->io != NULL) |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
342 io_remove(&fstream->io); |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
343 else if (!set) { |
4838
2ccd3ad66e29
If connection is closed while buffer is being flushed in uncorking, don't
Timo Sirainen <tss@iki.fi>
parents:
4766
diff
changeset
|
344 /* buffer flushing might close the stream */ |
3337
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
345 ret = buffer_flush(fstream); |
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
346 if (fstream->io == NULL && |
4838
2ccd3ad66e29
If connection is closed while buffer is being flushed in uncorking, don't
Timo Sirainen <tss@iki.fi>
parents:
4766
diff
changeset
|
347 (ret == 0 || fstream->flush_pending) && |
2ccd3ad66e29
If connection is closed while buffer is being flushed in uncorking, don't
Timo Sirainen <tss@iki.fi>
parents:
4766
diff
changeset
|
348 !stream->ostream.closed) { |
3337
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
349 fstream->io = io_add(fstream->fd, IO_WRITE, |
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
350 stream_send_io, fstream); |
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
351 } |
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
352 } |
b47043d0d131
Try to flush output before uncorking
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
353 |
4938
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
354 if (fstream->socket_cork_set) { |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
355 i_assert(!set); |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
356 if (net_set_cork(fstream->fd, FALSE) < 0) |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
357 fstream->no_socket_cork = TRUE; |
4938
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
358 fstream->socket_cork_set = FALSE; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
359 } |
10708
3b544841d5d7
ostream: If cork method isn't implemented, keep track of corking state internally.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
360 stream->corked = set; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
361 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
362 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
363 |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
364 static int o_stream_file_flush(struct ostream_private *stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
365 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
366 struct file_ostream *fstream = (struct file_ostream *) stream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
367 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
368 return buffer_flush(fstream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
369 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
370 |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
371 static void |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
372 o_stream_file_flush_pending(struct ostream_private *stream, bool set) |
3336
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
373 { |
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
374 struct file_ostream *fstream = (struct file_ostream *) stream; |
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
375 |
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
376 fstream->flush_pending = set; |
10708
3b544841d5d7
ostream: If cork method isn't implemented, keep track of corking state internally.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
377 if (set && !stream->corked && fstream->io == NULL) { |
3336
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
378 fstream->io = io_add(fstream->fd, IO_WRITE, |
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
379 stream_send_io, fstream); |
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
380 } |
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
381 } |
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
382 |
7912
81806d402514
Added more consts, ATTR_CONSTs and ATTR_PUREs.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
383 static size_t get_unused_space(const struct file_ostream *fstream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
384 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
385 if (fstream->head > fstream->tail) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
386 /* XXXT...HXXX */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
387 return fstream->head - fstream->tail; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
388 } else if (fstream->head < fstream->tail) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
389 /* ...HXXXT... */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
390 return (fstream->buffer_size - fstream->tail) + fstream->head; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
391 } else { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
392 /* either fully unused or fully used */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
393 return fstream->full ? 0 : fstream->buffer_size; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
394 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
395 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
396 |
7912
81806d402514
Added more consts, ATTR_CONSTs and ATTR_PUREs.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
397 static size_t o_stream_file_get_used_size(const struct ostream_private *stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
398 { |
7912
81806d402514
Added more consts, ATTR_CONSTs and ATTR_PUREs.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
399 const struct file_ostream *fstream = |
81806d402514
Added more consts, ATTR_CONSTs and ATTR_PUREs.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
400 (const struct file_ostream *)stream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
401 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
402 return fstream->buffer_size - get_unused_space(fstream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
403 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
404 |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
405 static int o_stream_file_seek(struct ostream_private *stream, uoff_t offset) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
406 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
407 struct file_ostream *fstream = (struct file_ostream *)stream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
408 |
16773
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
409 if (offset > OFF_T_MAX) { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
410 stream->ostream.stream_errno = EINVAL; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
411 return -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
412 } |
16773
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
413 if (!fstream->file) { |
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
414 stream->ostream.stream_errno = ESPIPE; |
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
415 return -1; |
76d5e3c8cec3
iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents:
16020
diff
changeset
|
416 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
417 |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
418 if (buffer_flush(fstream) < 0) |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
419 return -1; |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
420 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
421 stream->ostream.offset = offset; |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
422 fstream->buffer_offset = offset; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
423 return 1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
424 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
425 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
426 static void o_stream_grow_buffer(struct file_ostream *fstream, size_t bytes) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
427 { |
2756
9cd5d91509bb
Growing output buffer size broke the data inside it.
Timo Sirainen <tss@iki.fi>
parents:
2750
diff
changeset
|
428 size_t size, new_size, end_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
429 |
6142
6c0bfc35af03
Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents:
4938
diff
changeset
|
430 size = nearest_power(fstream->buffer_size + bytes); |
10083
bad043de6a7a
ostream: Simplified implementing ostreams.
Timo Sirainen <tss@iki.fi>
parents:
9557
diff
changeset
|
431 if (size > fstream->ostream.max_buffer_size) { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
432 /* limit the size */ |
10083
bad043de6a7a
ostream: Simplified implementing ostreams.
Timo Sirainen <tss@iki.fi>
parents:
9557
diff
changeset
|
433 size = fstream->ostream.max_buffer_size; |
10708
3b544841d5d7
ostream: If cork method isn't implemented, keep track of corking state internally.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
434 } else if (fstream->ostream.corked) { |
2657
b89f471a0e04
When corked, don't limit buffer size to optimal_block_size. Fixes problems
Timo Sirainen <tss@iki.fi>
parents:
2647
diff
changeset
|
435 /* try to use optimal buffer size with corking */ |
b89f471a0e04
When corked, don't limit buffer size to optimal_block_size. Fixes problems
Timo Sirainen <tss@iki.fi>
parents:
2647
diff
changeset
|
436 new_size = I_MIN(fstream->optimal_block_size, |
10083
bad043de6a7a
ostream: Simplified implementing ostreams.
Timo Sirainen <tss@iki.fi>
parents:
9557
diff
changeset
|
437 fstream->ostream.max_buffer_size); |
2657
b89f471a0e04
When corked, don't limit buffer size to optimal_block_size. Fixes problems
Timo Sirainen <tss@iki.fi>
parents:
2647
diff
changeset
|
438 if (new_size > size) |
b89f471a0e04
When corked, don't limit buffer size to optimal_block_size. Fixes problems
Timo Sirainen <tss@iki.fi>
parents:
2647
diff
changeset
|
439 size = new_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
440 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
441 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
442 if (size <= fstream->buffer_size) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
443 return; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
444 |
6142
6c0bfc35af03
Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents:
4938
diff
changeset
|
445 fstream->buffer = i_realloc(fstream->buffer, |
941
4d6b69558add
Added old_size parameter to p_realloc() - we rarely need it and this way
Timo Sirainen <tss@iki.fi>
parents:
920
diff
changeset
|
446 fstream->buffer_size, size); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
447 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
448 if (fstream->tail <= fstream->head && !IS_STREAM_EMPTY(fstream)) { |
2756
9cd5d91509bb
Growing output buffer size broke the data inside it.
Timo Sirainen <tss@iki.fi>
parents:
2750
diff
changeset
|
449 /* move head forward to end of buffer */ |
9cd5d91509bb
Growing output buffer size broke the data inside it.
Timo Sirainen <tss@iki.fi>
parents:
2750
diff
changeset
|
450 end_size = fstream->buffer_size - fstream->head; |
9cd5d91509bb
Growing output buffer size broke the data inside it.
Timo Sirainen <tss@iki.fi>
parents:
2750
diff
changeset
|
451 memmove(fstream->buffer + size - end_size, |
9cd5d91509bb
Growing output buffer size broke the data inside it.
Timo Sirainen <tss@iki.fi>
parents:
2750
diff
changeset
|
452 fstream->buffer + fstream->head, end_size); |
9cd5d91509bb
Growing output buffer size broke the data inside it.
Timo Sirainen <tss@iki.fi>
parents:
2750
diff
changeset
|
453 fstream->head = size - end_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
454 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
455 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
456 fstream->full = FALSE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
457 fstream->buffer_size = size; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
458 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
459 |
4907
5b4c9b20eba0
Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents:
4838
diff
changeset
|
460 static void stream_send_io(struct file_ostream *fstream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
461 { |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
462 struct ostream *ostream = &fstream->ostream.ostream; |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
463 int ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
464 |
3392
e8c0736ec5be
Don't forget o_stream_set_flush_pending() call if it's called in flush
Timo Sirainen <tss@iki.fi>
parents:
3337
diff
changeset
|
465 /* Set flush_pending = FALSE first before calling the flush callback, |
e8c0736ec5be
Don't forget o_stream_set_flush_pending() call if it's called in flush
Timo Sirainen <tss@iki.fi>
parents:
3337
diff
changeset
|
466 and change it to TRUE only if callback returns 0. That way the |
e8c0736ec5be
Don't forget o_stream_set_flush_pending() call if it's called in flush
Timo Sirainen <tss@iki.fi>
parents:
3337
diff
changeset
|
467 callback can call o_stream_set_flush_pending() again and we don't |
e8c0736ec5be
Don't forget o_stream_set_flush_pending() call if it's called in flush
Timo Sirainen <tss@iki.fi>
parents:
3337
diff
changeset
|
468 forget it even if flush callback returns 1. */ |
e8c0736ec5be
Don't forget o_stream_set_flush_pending() call if it's called in flush
Timo Sirainen <tss@iki.fi>
parents:
3337
diff
changeset
|
469 fstream->flush_pending = FALSE; |
e8c0736ec5be
Don't forget o_stream_set_flush_pending() call if it's called in flush
Timo Sirainen <tss@iki.fi>
parents:
3337
diff
changeset
|
470 |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
471 o_stream_ref(ostream); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
472 if (fstream->ostream.callback != NULL) |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
473 ret = fstream->ostream.callback(fstream->ostream.context); |
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
474 else |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
475 ret = o_stream_file_flush(&fstream->ostream); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
476 |
3395
5573554dce0c
Don't remove output handler if flush_pending is still set after callback.
Timo Sirainen <tss@iki.fi>
parents:
3392
diff
changeset
|
477 if (ret == 0) |
5573554dce0c
Don't remove output handler if flush_pending is still set after callback.
Timo Sirainen <tss@iki.fi>
parents:
3392
diff
changeset
|
478 fstream->flush_pending = TRUE; |
5573554dce0c
Don't remove output handler if flush_pending is still set after callback.
Timo Sirainen <tss@iki.fi>
parents:
3392
diff
changeset
|
479 |
3401
c19d6448f856
Set output I/O handler after output callback if needed.
Timo Sirainen <tss@iki.fi>
parents:
3395
diff
changeset
|
480 if (!fstream->flush_pending && IS_STREAM_EMPTY(fstream)) { |
c19d6448f856
Set output I/O handler after output callback if needed.
Timo Sirainen <tss@iki.fi>
parents:
3395
diff
changeset
|
481 if (fstream->io != NULL) { |
c19d6448f856
Set output I/O handler after output callback if needed.
Timo Sirainen <tss@iki.fi>
parents:
3395
diff
changeset
|
482 /* all sent */ |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
483 io_remove(&fstream->io); |
3401
c19d6448f856
Set output I/O handler after output callback if needed.
Timo Sirainen <tss@iki.fi>
parents:
3395
diff
changeset
|
484 } |
4122
9e5af78ea530
If output flush callback closed the stream, don't add another flush I/O
Timo Sirainen <tss@iki.fi>
parents:
3960
diff
changeset
|
485 } else if (!fstream->ostream.ostream.closed) { |
3665
1f4b4387595b
Revert previous "cleanup" which broke things.. Added a comment.
Timo Sirainen <tss@iki.fi>
parents:
3653
diff
changeset
|
486 /* Add the IO handler if it's not there already. Callback |
1f4b4387595b
Revert previous "cleanup" which broke things.. Added a comment.
Timo Sirainen <tss@iki.fi>
parents:
3653
diff
changeset
|
487 might have just returned 0 without there being any data |
1f4b4387595b
Revert previous "cleanup" which broke things.. Added a comment.
Timo Sirainen <tss@iki.fi>
parents:
3653
diff
changeset
|
488 to be sent. */ |
1f4b4387595b
Revert previous "cleanup" which broke things.. Added a comment.
Timo Sirainen <tss@iki.fi>
parents:
3653
diff
changeset
|
489 if (fstream->io == NULL) { |
1f4b4387595b
Revert previous "cleanup" which broke things.. Added a comment.
Timo Sirainen <tss@iki.fi>
parents:
3653
diff
changeset
|
490 fstream->io = io_add(fstream->fd, IO_WRITE, |
1f4b4387595b
Revert previous "cleanup" which broke things.. Added a comment.
Timo Sirainen <tss@iki.fi>
parents:
3653
diff
changeset
|
491 stream_send_io, fstream); |
1f4b4387595b
Revert previous "cleanup" which broke things.. Added a comment.
Timo Sirainen <tss@iki.fi>
parents:
3653
diff
changeset
|
492 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
493 } |
3336
a3a72d5bdfce
o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents:
3241
diff
changeset
|
494 |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
495 o_stream_unref(&ostream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
496 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
497 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
498 static size_t o_stream_add(struct file_ostream *fstream, |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
499 const void *data, size_t size) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
500 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
501 size_t unused, sent; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
502 int i; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
503 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
504 unused = get_unused_space(fstream); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
505 if (unused < size) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
506 o_stream_grow_buffer(fstream, size-unused); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
507 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
508 sent = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
509 for (i = 0; i < 2 && sent < size && !fstream->full; i++) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
510 unused = fstream->tail >= fstream->head ? |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
511 fstream->buffer_size - fstream->tail : |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
512 fstream->head - fstream->tail; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
513 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
514 if (unused > size-sent) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
515 unused = size-sent; |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
516 memcpy(fstream->buffer + fstream->tail, |
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
517 CONST_PTR_OFFSET(data, sent), unused); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
518 sent += unused; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
519 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
520 fstream->tail += unused; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
521 if (fstream->tail == fstream->buffer_size) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
522 fstream->tail = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
523 |
14915
23e9660f0473
ostream-file: Fixed writing with zero buffer size.
Timo Sirainen <tss@iki.fi>
parents:
14851
diff
changeset
|
524 if (fstream->head == fstream->tail && |
23e9660f0473
ostream-file: Fixed writing with zero buffer size.
Timo Sirainen <tss@iki.fi>
parents:
14851
diff
changeset
|
525 fstream->buffer_size > 0) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
526 fstream->full = TRUE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
527 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
528 |
1478
ce6521e4a191
Automatically set file streams to blocking and don't try to io_add() them.
Timo Sirainen <tss@iki.fi>
parents:
1476
diff
changeset
|
529 if (sent != 0 && fstream->io == NULL && |
10708
3b544841d5d7
ostream: If cork method isn't implemented, keep track of corking state internally.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
530 !fstream->ostream.corked && !fstream->file) { |
1499
e850252cdc7e
Removed I/O priorities. They were pretty much useless and were just getting
Timo Sirainen <tss@iki.fi>
parents:
1487
diff
changeset
|
531 fstream->io = io_add(fstream->fd, IO_WRITE, stream_send_io, |
e850252cdc7e
Removed I/O priorities. They were pretty much useless and were just getting
Timo Sirainen <tss@iki.fi>
parents:
1487
diff
changeset
|
532 fstream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
533 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
534 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
535 return sent; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
536 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
537 |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
538 ssize_t o_stream_file_sendv(struct ostream_private *stream, |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
539 const struct const_iovec *iov, |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
540 unsigned int iov_count) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
541 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
542 struct file_ostream *fstream = (struct file_ostream *)stream; |
6254
28b9873da2cc
If we do multiple writev() calls and the last one fails, we shouldn't treat
Timo Sirainen <tss@iki.fi>
parents:
6164
diff
changeset
|
543 size_t size, total_size, added, optimal_size; |
3618
a16f27ce2eda
Changed iov_count to be unsigned int, it's large enough. Added overflow-flag
Timo Sirainen <tss@iki.fi>
parents:
3401
diff
changeset
|
544 unsigned int i; |
1305 | 545 ssize_t ret = 0; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
546 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
547 for (i = 0, size = 0; i < iov_count; i++) |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
548 size += iov[i].iov_len; |
6254
28b9873da2cc
If we do multiple writev() calls and the last one fails, we shouldn't treat
Timo Sirainen <tss@iki.fi>
parents:
6164
diff
changeset
|
549 total_size = size; |
1305 | 550 |
3618
a16f27ce2eda
Changed iov_count to be unsigned int, it's large enough. Added overflow-flag
Timo Sirainen <tss@iki.fi>
parents:
3401
diff
changeset
|
551 if (size > get_unused_space(fstream) && !IS_STREAM_EMPTY(fstream)) { |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
552 if (o_stream_file_flush(stream) < 0) |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
553 return -1; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
554 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
555 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
556 optimal_size = I_MIN(fstream->optimal_block_size, |
10083
bad043de6a7a
ostream: Simplified implementing ostreams.
Timo Sirainen <tss@iki.fi>
parents:
9557
diff
changeset
|
557 fstream->ostream.max_buffer_size); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
558 if (IS_STREAM_EMPTY(fstream) && |
10708
3b544841d5d7
ostream: If cork method isn't implemented, keep track of corking state internally.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
559 (!stream->corked || size >= optimal_size)) { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
560 /* send immediately */ |
20857
45e7b2203260
lib: ostream-file: Renamed o_stream_writev() to o_stream_file_writev_full().
Stephan Bosch <stephan@rename-it.nl>
parents:
20856
diff
changeset
|
561 ret = o_stream_file_writev_full(fstream, iov, iov_count); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
562 if (ret < 0) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
563 return -1; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
564 |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
565 size = ret; |
6254
28b9873da2cc
If we do multiple writev() calls and the last one fails, we shouldn't treat
Timo Sirainen <tss@iki.fi>
parents:
6164
diff
changeset
|
566 while (size > 0 && iov_count > 0 && size >= iov[0].iov_len) { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
567 size -= iov[0].iov_len; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
568 iov++; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
569 iov_count--; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
570 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
571 |
6254
28b9873da2cc
If we do multiple writev() calls and the last one fails, we shouldn't treat
Timo Sirainen <tss@iki.fi>
parents:
6164
diff
changeset
|
572 if (iov_count == 0) |
28b9873da2cc
If we do multiple writev() calls and the last one fails, we shouldn't treat
Timo Sirainen <tss@iki.fi>
parents:
6164
diff
changeset
|
573 i_assert(size == 0); |
28b9873da2cc
If we do multiple writev() calls and the last one fails, we shouldn't treat
Timo Sirainen <tss@iki.fi>
parents:
6164
diff
changeset
|
574 else { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
575 added = o_stream_add(fstream, |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
576 CONST_PTR_OFFSET(iov[0].iov_base, size), |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
577 iov[0].iov_len - size); |
2484
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
578 ret += added; |
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
579 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
580 if (added != iov[0].iov_len - size) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
581 /* buffer full */ |
2484
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
582 stream->ostream.offset += ret; |
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
583 return ret; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
584 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
585 |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
586 iov++; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
587 iov_count--; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
588 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
589 } |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
590 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
591 /* buffer it, at least partly */ |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
592 for (i = 0; i < iov_count; i++) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
593 added = o_stream_add(fstream, iov[i].iov_base, iov[i].iov_len); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
594 ret += added; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
595 if (added != iov[i].iov_len) |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
596 break; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
597 } |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
598 stream->ostream.offset += ret; |
6848
b73cb35a8427
Assert: With files o_stream_send*() must either write everything or return
Timo Sirainen <tss@iki.fi>
parents:
6723
diff
changeset
|
599 i_assert((size_t)ret <= total_size); |
b73cb35a8427
Assert: With files o_stream_send*() must either write everything or return
Timo Sirainen <tss@iki.fi>
parents:
6723
diff
changeset
|
600 i_assert((size_t)ret == total_size || !fstream->file); |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
601 return ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
602 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
603 |
8923 | 604 static size_t |
605 o_stream_file_update_buffer(struct file_ostream *fstream, | |
606 const void *data, size_t size, size_t pos) | |
607 { | |
608 size_t avail, copy_size; | |
609 | |
610 if (fstream->head < fstream->tail) { | |
611 /* ...HXXXT... */ | |
612 i_assert(pos < fstream->tail); | |
613 avail = fstream->tail - pos; | |
614 } else { | |
615 /* XXXT...HXXX */ | |
616 avail = fstream->buffer_size - pos; | |
617 } | |
618 copy_size = I_MIN(size, avail); | |
619 memcpy(fstream->buffer + pos, data, copy_size); | |
620 data = CONST_PTR_OFFSET(data, copy_size); | |
621 size -= copy_size; | |
622 | |
623 if (size > 0 && fstream->head >= fstream->tail) { | |
624 /* wraps to beginning of the buffer */ | |
625 copy_size = I_MIN(size, fstream->tail); | |
626 memcpy(fstream->buffer, data, copy_size); | |
627 size -= copy_size; | |
628 } | |
629 return size; | |
630 } | |
631 | |
632 static int | |
633 o_stream_file_write_at(struct ostream_private *stream, | |
634 const void *data, size_t size, uoff_t offset) | |
635 { | |
636 struct file_ostream *fstream = (struct file_ostream *)stream; | |
637 size_t used, pos, skip, left; | |
638 | |
639 /* update buffer if the write overlaps it */ | |
640 used = file_buffer_get_used_size(fstream); | |
12301
17957b5082cd
ostream-file: Fixed potential crash in write_at() and also fixed attempted optimization.
Timo Sirainen <tss@iki.fi>
parents:
11309
diff
changeset
|
641 if (used > 0 && |
17957b5082cd
ostream-file: Fixed potential crash in write_at() and also fixed attempted optimization.
Timo Sirainen <tss@iki.fi>
parents:
11309
diff
changeset
|
642 fstream->buffer_offset < offset + size && |
8923 | 643 fstream->buffer_offset + used > offset) { |
644 if (fstream->buffer_offset <= offset) { | |
645 /* updating from the beginning */ | |
646 skip = 0; | |
647 } else { | |
648 skip = fstream->buffer_offset - offset; | |
649 } | |
650 pos = (fstream->head + offset + skip - fstream->buffer_offset) % | |
651 fstream->buffer_size; | |
652 left = o_stream_file_update_buffer(fstream, | |
653 CONST_PTR_OFFSET(data, skip), size - skip, pos); | |
654 if (left > 0) { | |
655 /* didn't write all of it */ | |
656 if (skip > 0) { | |
657 /* we also have to write a prefix. don't | |
658 bother with two syscalls, just write all | |
659 of it in one pwrite(). */ | |
660 } else { | |
661 /* write only the suffix */ | |
21322
5ab8dc1a4a6f
global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20860
diff
changeset
|
662 size_t update_count = size - left; |
12301
17957b5082cd
ostream-file: Fixed potential crash in write_at() and also fixed attempted optimization.
Timo Sirainen <tss@iki.fi>
parents:
11309
diff
changeset
|
663 |
17957b5082cd
ostream-file: Fixed potential crash in write_at() and also fixed attempted optimization.
Timo Sirainen <tss@iki.fi>
parents:
11309
diff
changeset
|
664 data = CONST_PTR_OFFSET(data, update_count); |
17957b5082cd
ostream-file: Fixed potential crash in write_at() and also fixed attempted optimization.
Timo Sirainen <tss@iki.fi>
parents:
11309
diff
changeset
|
665 size -= update_count; |
17957b5082cd
ostream-file: Fixed potential crash in write_at() and also fixed attempted optimization.
Timo Sirainen <tss@iki.fi>
parents:
11309
diff
changeset
|
666 offset += update_count; |
8923 | 667 } |
668 } else if (skip == 0) { | |
669 /* everything done */ | |
670 return 0; | |
671 } else { | |
672 /* still have to write prefix */ | |
673 size = skip; | |
674 } | |
675 } | |
676 | |
677 /* we couldn't write everything to the buffer. flush the buffer | |
678 and pwrite() the rest. */ | |
679 if (o_stream_file_flush(stream) < 0) | |
680 return -1; | |
681 | |
682 if (pwrite_full(fstream->fd, data, size, offset) < 0) { | |
683 stream->ostream.stream_errno = errno; | |
684 stream_closed(fstream); | |
685 return -1; | |
686 } | |
687 return 0; | |
688 } | |
689 | |
6415
b0096861c390
Renamed struct _[io]stream to struct [io]stream_private. Also removed _
Timo Sirainen <tss@iki.fi>
parents:
6255
diff
changeset
|
690 static off_t io_stream_sendfile(struct ostream_private *outstream, |
18079
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
691 struct istream *instream, int in_fd, |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
692 bool *sendfile_not_supported_r) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
693 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
694 struct file_ostream *foutstream = (struct file_ostream *)outstream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
695 uoff_t start_offset; |
6723
ba048bb01842
o_stream_send_istream(): Don't fstat() the stream unless we have to.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
696 uoff_t in_size, offset, send_size, v_offset; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
697 ssize_t ret; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
698 |
18079
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
699 *sendfile_not_supported_r = FALSE; |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
700 |
14963
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
701 if ((ret = i_stream_get_size(instream, TRUE, &in_size)) <= 0) { |
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
702 outstream->ostream.stream_errno = ret == 0 ? ESPIPE : |
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
703 instream->stream_errno; |
6723
ba048bb01842
o_stream_send_istream(): Don't fstat() the stream unless we have to.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
704 return -1; |
ba048bb01842
o_stream_send_istream(): Don't fstat() the stream unless we have to.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
705 } |
ba048bb01842
o_stream_send_istream(): Don't fstat() the stream unless we have to.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
706 |
4938
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
707 o_stream_socket_cork(foutstream); |
e3539fafe74f
Delay setting the TCP cork until something is actually sent to the
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
708 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
709 /* flush out any data in buffer */ |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
710 if ((ret = buffer_flush(foutstream)) <= 0) |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
711 return ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
712 |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
713 if (o_stream_lseek(foutstream) < 0) |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
714 return -1; |
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
715 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
716 start_offset = v_offset = instream->v_offset; |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
717 do { |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
718 offset = instream->real_stream->abs_start_offset + v_offset; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
719 send_size = in_size - v_offset; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
720 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
721 ret = safe_sendfile(foutstream->fd, in_fd, &offset, |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
722 MAX_SSIZE_T(send_size)); |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
723 if (ret <= 0) { |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
724 if (ret == 0) |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
725 break; |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
726 if (foutstream->file) { |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
727 if (errno == EINTR) { |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
728 /* automatically retry */ |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
729 continue; |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
730 } |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
731 } else { |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
732 if (errno == EINTR || errno == EAGAIN) { |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
733 ret = 0; |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
734 break; |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
735 } |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
736 } |
18079
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
737 if (errno == EINVAL) |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
738 *sendfile_not_supported_r = TRUE; |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
739 else { |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
740 outstream->ostream.stream_errno = errno; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
741 /* close only if error wasn't because |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
742 sendfile() isn't supported */ |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
743 stream_closed(foutstream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
744 } |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
745 break; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
746 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
747 |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
748 v_offset += ret; |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
749 foutstream->real_offset += ret; |
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
750 foutstream->buffer_offset += ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
751 outstream->ostream.offset += ret; |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
752 } while ((uoff_t)ret != send_size); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
753 |
1204 | 754 i_stream_seek(instream, v_offset); |
9326
a5bc58832be9
o_stream_send_istream(): Make sure istream->eof gets set after sending everything with sendfile().
Timo Sirainen <tss@iki.fi>
parents:
8923
diff
changeset
|
755 if (ret == 0) { |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
756 /* we should be at EOF. if not, write more. */ |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
757 i_assert(!foutstream->file || |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
758 instream->v_offset - start_offset == in_size); |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
759 if (i_stream_read(instream) > 0) { |
18079
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
760 if (io_stream_sendfile(outstream, instream, in_fd, |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
761 sendfile_not_supported_r) < 0) |
17922
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
762 return -1; |
00115d4930d4
lib: o_stream_send_istream() shouldn't ignore EINTRs for file ostreams.
Timo Sirainen <tss@iki.fi>
parents:
17700
diff
changeset
|
763 } |
9326
a5bc58832be9
o_stream_send_istream(): Make sure istream->eof gets set after sending everything with sendfile().
Timo Sirainen <tss@iki.fi>
parents:
8923
diff
changeset
|
764 } |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
765 return ret < 0 ? -1 : (off_t)(instream->v_offset - start_offset); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
766 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
767 |
6415
b0096861c390
Renamed struct _[io]stream to struct [io]stream_private. Also removed _
Timo Sirainen <tss@iki.fi>
parents:
6255
diff
changeset
|
768 static off_t io_stream_copy_backwards(struct ostream_private *outstream, |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
769 struct istream *instream, uoff_t in_size) |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
770 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
771 struct file_ostream *foutstream = (struct file_ostream *)outstream; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
772 uoff_t in_start_offset, in_offset, in_limit, out_offset; |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
773 const unsigned char *data; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
774 size_t buffer_size, size, read_size; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
775 ssize_t ret; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
776 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
777 i_assert(IS_STREAM_EMPTY(foutstream)); |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
778 |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
779 /* figure out optimal buffer size */ |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
780 buffer_size = instream->real_stream->buffer_size; |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
781 if (buffer_size == 0 || buffer_size > foutstream->buffer_size) { |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
782 if (foutstream->optimal_block_size > foutstream->buffer_size) { |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
783 o_stream_grow_buffer(foutstream, |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
784 foutstream->optimal_block_size - |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
785 foutstream->buffer_size); |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
786 } |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
787 |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
788 buffer_size = foutstream->buffer_size; |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
789 } |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
790 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
791 in_start_offset = instream->v_offset; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
792 in_offset = in_limit = in_size; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
793 out_offset = outstream->ostream.offset + (in_offset - in_start_offset); |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
794 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
795 while (in_offset > in_start_offset) { |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
796 if (in_offset - in_start_offset <= buffer_size) |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
797 read_size = in_offset - in_start_offset; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
798 else |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
799 read_size = buffer_size; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
800 in_offset -= read_size; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
801 out_offset -= read_size; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
802 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
803 for (;;) { |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
804 i_assert(in_offset <= in_limit); |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
805 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
806 i_stream_seek(instream, in_offset); |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
807 read_size = in_limit - in_offset; |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
808 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
809 (void)i_stream_read_data(instream, &data, &size, |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
810 read_size-1); |
2040 | 811 if (size >= read_size) { |
812 size = read_size; | |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
813 if (instream->mmaped) { |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
814 /* we'll have to write it through |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
815 buffer or the file gets corrupted */ |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
816 i_assert(size <= |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
817 foutstream->buffer_size); |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
818 memcpy(foutstream->buffer, data, size); |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
819 data = foutstream->buffer; |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
820 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
821 break; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
822 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
823 |
2040 | 824 /* buffer too large probably, try with smaller */ |
825 read_size -= size; | |
826 in_offset += read_size; | |
827 out_offset += read_size; | |
828 buffer_size -= read_size; | |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
829 } |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
830 in_limit -= size; |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
831 |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
832 ret = pwrite_full(foutstream->fd, data, size, out_offset); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
833 if (ret < 0) { |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
834 /* error */ |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
835 outstream->ostream.stream_errno = errno; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
836 return -1; |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
837 } |
8778
52e0b40146b1
ostream: When copying backwards within a file, update in/outstream offsets.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
838 i_stream_skip(instream, size); |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
839 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
840 |
8778
52e0b40146b1
ostream: When copying backwards within a file, update in/outstream offsets.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
841 outstream->ostream.offset += in_size - in_start_offset; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
842 return (off_t) (in_size - in_start_offset); |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
843 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
844 |
9557
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
845 static off_t io_stream_copy_stream(struct ostream_private *outstream, |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
846 struct istream *instream, bool same_stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
847 { |
14963
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
848 uoff_t in_size; |
15610
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
849 off_t in_abs_offset, ret = 0; |
3241
b79853b4b005
Replaced i_stream_get_size() with i_stream_stat(). Added i_stream_sync().
Timo Sirainen <tss@iki.fi>
parents:
3234
diff
changeset
|
850 |
9557
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
851 if (same_stream) { |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
852 /* copying data within same fd. we'll have to be careful with |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
853 seeks and overlapping writes. */ |
15610
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
854 if ((ret = i_stream_get_size(instream, TRUE, &in_size)) < 0) { |
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
855 outstream->ostream.stream_errno = |
14963
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
856 instream->stream_errno; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
857 return -1; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
858 } |
15610
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
859 /* if we couldn't find out the size, it means that instream |
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
860 isn't a regular file_istream. we can be reasonably sure that |
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
861 we can copy it safely the regular way. (there's really no |
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
862 other possibility, other than failing completely.) */ |
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
863 } |
3d3625d18231
o_stream_send_istream(): Fixed copying within same file, when istream's size is unknown.
Timo Sirainen <tss@iki.fi>
parents:
15187
diff
changeset
|
864 if (ret > 0) { |
14963
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
865 i_assert(instream->v_offset <= in_size); |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
866 |
8919
334d29caa084
o_stream_send_istream(): Don't do backwards copying if the area doesn't really overlap.
Timo Sirainen <tss@iki.fi>
parents:
8778
diff
changeset
|
867 in_abs_offset = instream->real_stream->abs_start_offset + |
334d29caa084
o_stream_send_istream(): Don't do backwards copying if the area doesn't really overlap.
Timo Sirainen <tss@iki.fi>
parents:
8778
diff
changeset
|
868 instream->v_offset; |
334d29caa084
o_stream_send_istream(): Don't do backwards copying if the area doesn't really overlap.
Timo Sirainen <tss@iki.fi>
parents:
8778
diff
changeset
|
869 ret = (off_t)outstream->ostream.offset - in_abs_offset; |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
870 if (ret == 0) { |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
871 /* copying data over itself. we don't really |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
872 need to do that, just fake it. */ |
14963
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
873 return in_size - instream->v_offset; |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
874 } |
14963
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
875 if (ret > 0 && in_size > (uoff_t)ret) { |
6723
ba048bb01842
o_stream_send_istream(): Don't fstat() the stream unless we have to.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
876 /* overlapping */ |
8919
334d29caa084
o_stream_send_istream(): Don't do backwards copying if the area doesn't really overlap.
Timo Sirainen <tss@iki.fi>
parents:
8778
diff
changeset
|
877 i_assert(instream->seekable); |
6723
ba048bb01842
o_stream_send_istream(): Don't fstat() the stream unless we have to.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
878 return io_stream_copy_backwards(outstream, instream, |
14963
3cba27563159
o_stream_send_istream(): Get input stream size with i_stream_get_size() instead of _stat().
Timo Sirainen <tss@iki.fi>
parents:
14915
diff
changeset
|
879 in_size); |
6723
ba048bb01842
o_stream_send_istream(): Don't fstat() the stream unless we have to.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
880 } |
1197
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
881 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
882 |
17698
e593dce9468d
lib: io_stream_copy() no longer attempts to read full block sizes from input.
Timo Sirainen <tss@iki.fi>
parents:
17479
diff
changeset
|
883 return io_stream_copy(&outstream->ostream, instream); |
9557
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
884 } |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
885 |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
886 static off_t o_stream_file_send_istream(struct ostream_private *outstream, |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
887 struct istream *instream) |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
888 { |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
889 struct file_ostream *foutstream = (struct file_ostream *)outstream; |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
890 bool same_stream; |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
891 int in_fd; |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
892 off_t ret; |
18079
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
893 bool sendfile_not_supported; |
9557
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
894 |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
895 in_fd = !instream->readable_fd ? -1 : i_stream_get_fd(instream); |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
896 if (!foutstream->no_sendfile && in_fd != -1 && |
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
897 in_fd != foutstream->fd && instream->seekable) { |
18079
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
898 ret = io_stream_sendfile(outstream, instream, in_fd, |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
899 &sendfile_not_supported); |
24d2d52d5355
lib: ostream-file checks "sendfile() not supported" a bit better.
Timo Sirainen <tss@iki.fi>
parents:
17922
diff
changeset
|
900 if (ret >= 0 || !sendfile_not_supported) |
1115
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
901 return ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
902 |
1115
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
903 /* sendfile() not supported (with this fd), fallback to |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
904 regular sending. */ |
1115
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
905 foutstream->no_sendfile = TRUE; |
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
906 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
907 |
15913
2747055fc91b
o_stream_send_istream(): Fixed copying when [io]streams neither have usable fds.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
908 same_stream = i_stream_get_fd(instream) == foutstream->fd && |
2747055fc91b
o_stream_send_istream(): Fixed copying when [io]streams neither have usable fds.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
909 foutstream->fd != -1; |
9557
e41c648a2f4c
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
Timo Sirainen <tss@iki.fi>
parents:
9540
diff
changeset
|
910 return io_stream_copy_stream(outstream, instream, same_stream); |
1861
e42d97a85653
Added istream->eof. istream->v_size is now set to 0 with files.
Timo Sirainen <tss@iki.fi>
parents:
1834
diff
changeset
|
911 } |
e42d97a85653
Added istream->eof. istream->v_size is now set to 0 with files.
Timo Sirainen <tss@iki.fi>
parents:
1834
diff
changeset
|
912 |
13417
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
913 static void o_stream_file_switch_ioloop(struct ostream_private *stream) |
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
914 { |
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
915 struct file_ostream *fstream = (struct file_ostream *)stream; |
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
916 |
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
917 if (fstream->io != NULL) |
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
918 fstream->io = io_loop_move_io(&fstream->io); |
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
919 } |
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
920 |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
921 struct ostream * |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
922 o_stream_create_file_common(struct file_ostream *fstream, |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
923 int fd, size_t max_buffer_size, bool autoclose_fd) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
924 { |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
925 struct ostream *ostream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
926 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
927 fstream->fd = fd; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
928 fstream->autoclose_fd = autoclose_fd; |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
929 fstream->optimal_block_size = DEFAULT_OPTIMAL_BLOCK_SIZE; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
930 |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
931 fstream->ostream.iostream.close = o_stream_file_close; |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
932 fstream->ostream.iostream.destroy = o_stream_file_destroy; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
933 |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
934 fstream->ostream.cork = o_stream_file_cork; |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
935 fstream->ostream.flush = o_stream_file_flush; |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
936 fstream->ostream.flush_pending = o_stream_file_flush_pending; |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
937 fstream->ostream.get_used_size = o_stream_file_get_used_size; |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
938 fstream->ostream.seek = o_stream_file_seek; |
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
939 fstream->ostream.sendv = o_stream_file_sendv; |
8923 | 940 fstream->ostream.write_at = o_stream_file_write_at; |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6415
diff
changeset
|
941 fstream->ostream.send_istream = o_stream_file_send_istream; |
13417
977dcd541f69
Added o_stream_switch_ioloop() and implemented it to all ostreams.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
942 fstream->ostream.switch_ioloop = o_stream_file_switch_ioloop; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
943 |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
944 fstream->writev = o_stream_file_writev; |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
945 |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
946 fstream->ostream.max_buffer_size = max_buffer_size; |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
947 ostream = o_stream_create(&fstream->ostream, NULL, fd); |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
948 |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
949 if (max_buffer_size == 0) |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
950 fstream->ostream.max_buffer_size = fstream->optimal_block_size; |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
951 |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
952 return ostream; |
6161
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
953 } |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
954 |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
955 static void fstream_init_file(struct file_ostream *fstream) |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
956 { |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
957 struct stat st; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
958 |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
959 fstream->no_sendfile = TRUE; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
960 if (fstat(fstream->fd, &st) < 0) |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
961 return; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
962 |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
963 if ((uoff_t)st.st_blksize > fstream->optimal_block_size) { |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
964 /* use the optimal block size, but with a reasonable limit */ |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
965 fstream->optimal_block_size = |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
966 I_MIN(st.st_blksize, MAX_OPTIMAL_BLOCK_SIZE); |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
967 } |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
968 |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
969 if (S_ISREG(st.st_mode)) { |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
970 fstream->no_socket_cork = TRUE; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
971 fstream->file = TRUE; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
972 } |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
973 } |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
974 |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
975 struct ostream * |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
976 o_stream_create_fd(int fd, size_t max_buffer_size, bool autoclose_fd) |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
977 { |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
978 struct file_ostream *fstream; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
979 struct ostream *ostream; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
980 off_t offset; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
981 |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
982 fstream = i_new(struct file_ostream, 1); |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
983 ostream = o_stream_create_file_common |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
984 (fstream, fd, max_buffer_size, autoclose_fd); |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
985 |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
986 offset = lseek(fd, 0, SEEK_CUR); |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
987 if (offset >= 0) { |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
988 ostream->offset = offset; |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
989 fstream->real_offset = offset; |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
990 fstream->buffer_offset = offset; |
6161
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
991 fstream_init_file(fstream); |
1345
04b81672c3a3
Call safe_sendfile() only with sockets, and also with files under Linux.
Timo Sirainen <tss@iki.fi>
parents:
1305
diff
changeset
|
992 } else { |
1476 | 993 if (net_getsockname(fd, NULL, NULL) < 0) { |
1345
04b81672c3a3
Call safe_sendfile() only with sockets, and also with files under Linux.
Timo Sirainen <tss@iki.fi>
parents:
1305
diff
changeset
|
994 fstream->no_sendfile = TRUE; |
1487 | 995 fstream->no_socket_cork = TRUE; |
1476 | 996 } |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
997 } |
2245
95fe82bbda7a
Allow giving 0 max_buffer_size, in which case "optimal" size is used.
Timo Sirainen <tss@iki.fi>
parents:
2072
diff
changeset
|
998 |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
999 return ostream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1000 } |
6161
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1001 |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1002 struct ostream * |
17479
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1003 o_stream_create_fd_autoclose(int *fd, size_t max_buffer_size) |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1004 { |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1005 struct ostream *output; |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1006 |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1007 output = o_stream_create_fd(*fd, max_buffer_size, TRUE); |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1008 *fd = -1; |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1009 return output; |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1010 } |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1011 |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1012 struct ostream * |
6161
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1013 o_stream_create_fd_file(int fd, uoff_t offset, bool autoclose_fd) |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1014 { |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1015 struct file_ostream *fstream; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1016 struct ostream *ostream; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1017 |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1018 if (offset == (uoff_t)-1) |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1019 offset = lseek(fd, 0, SEEK_CUR); |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1020 |
20859
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
1021 fstream = i_new(struct file_ostream, 1); |
d2d89eae7828
lib: ostream-file: Allow creating derived file output streams.
Stephan Bosch <stephan@rename-it.nl>
parents:
20858
diff
changeset
|
1022 ostream = o_stream_create_file_common(fstream, fd, 0, autoclose_fd); |
6161
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1023 fstream_init_file(fstream); |
6163
48dbfdba4e24
Delay lseek()s and use pwrite() whenever possible.
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
1024 fstream->real_offset = offset; |
6164
22398d619cac
Delayed lseek()/pwrite() fixes.
Timo Sirainen <tss@iki.fi>
parents:
6163
diff
changeset
|
1025 fstream->buffer_offset = offset; |
20860
668274a98b48
lib: Added ostream.blocking boolean
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20859
diff
changeset
|
1026 ostream->blocking = fstream->file; |
6161
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1027 ostream->offset = offset; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1028 return ostream; |
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
1029 } |
17479
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1030 |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1031 struct ostream *o_stream_create_fd_file_autoclose(int *fd, uoff_t offset) |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1032 { |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1033 struct ostream *output; |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1034 |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1035 output = o_stream_create_fd_file(*fd, offset, TRUE); |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1036 *fd = -1; |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1037 return output; |
0bcb43692d91
lib: Added [io]_stream_create_fd_*autoclose()
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
1038 } |