Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/ostream-file.c @ 2988:76d0e16d45e6 HEAD
Go back to the version before recent changes. It was correct all the time.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 17 Dec 2004 15:31:19 +0200 |
parents | f1e67917a669 |
children | 06f9da4ff7a5 |
rev | line source |
---|---|
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
1 /* Copyright (c) 2002-2003 Timo Sirainen */ |
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" |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include "network.h" |
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" |
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
|
11 #include "istream-internal.h" |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 #include "ostream-internal.h" |
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 |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
20 #ifndef UIO_MAXIOV |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
21 # define UIO_MAXIOV 16 |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
22 #endif |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
23 |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
24 /* 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
|
25 128k as optimal size. */ |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
26 #define DEFAULT_OPTIMAL_BLOCK_SIZE 4096 |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
27 #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
|
28 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 #define IS_STREAM_EMPTY(fstream) \ |
920 | 30 ((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
|
31 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 #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
|
33 ((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
|
34 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
35 struct file_ostream { |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
36 struct _ostream ostream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 int fd; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
39 struct io *io; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 unsigned char *buffer; /* ring-buffer */ |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
42 size_t buffer_size, max_buffer_size, optimal_block_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 size_t head, tail; /* first unsent/unused byte */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 unsigned int full:1; /* if head == tail, is buffer empty or full? */ |
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
|
46 unsigned int file:1; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 unsigned int corked:1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 unsigned int no_socket_cork:1; |
1115
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
49 unsigned int no_sendfile:1; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 unsigned int autoclose_fd:1; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
51 }; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
53 static void stream_send_io(void *context); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
54 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
55 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
|
56 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 if (fstream->autoclose_fd && fstream->fd != -1) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 if (close(fstream->fd) < 0) |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
59 i_error("file_ostream.close() failed: %m"); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 fstream->fd = -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 if (fstream->io != NULL) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 io_remove(fstream->io); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 fstream->io = NULL; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 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
|
69 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
71 static void _close(struct _iostream *stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
73 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
|
74 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 /* flush output before really closing it */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 o_stream_flush(&fstream->ostream.ostream); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 stream_closed(fstream); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
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 _destroy(struct _iostream *stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
83 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
|
84 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 p_free(fstream->ostream.iostream.pool, fstream->buffer); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
88 static void _set_max_buffer_size(struct _iostream *stream, size_t max_size) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
90 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
|
91 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 fstream->max_buffer_size = max_size; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
95 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
|
96 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 size_t used; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 |
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
|
99 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
|
100 return; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 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
|
103 /* ...HXXXT... */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 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
|
105 i_assert(size <= used); |
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
106 fstream->head += size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 } else { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 /* XXXT...HXXX */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 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
|
110 if (size > used) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 size -= used; |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
112 i_assert(size <= fstream->tail); |
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
113 fstream->head = size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 } else { |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
115 fstream->head += size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 fstream->full = FALSE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 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
|
122 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
|
123 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 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
|
125 fstream->head = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
128 static ssize_t o_stream_writev(struct file_ostream *fstream, |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
129 const struct const_iovec *iov, int iov_size) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 ssize_t ret; |
2471
4fa0f02369b1
o_stream_sendv() returned wrong value if sending more than UIO_MAXIOV
Timo Sirainen <tss@iki.fi>
parents:
2432
diff
changeset
|
132 size_t size, sent; |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
133 int i; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
135 if (iov_size == 1) |
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
136 ret = write(fstream->fd, iov->iov_base, iov->iov_len); |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
137 else { |
2471
4fa0f02369b1
o_stream_sendv() returned wrong value if sending more than UIO_MAXIOV
Timo Sirainen <tss@iki.fi>
parents:
2432
diff
changeset
|
138 sent = 0; |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
139 while (iov_size > UIO_MAXIOV) { |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
140 size = 0; |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
141 for (i = 0; i < UIO_MAXIOV; i++) |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
142 size += iov[i].iov_len; |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
143 |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
144 ret = writev(fstream->fd, (const struct iovec *)iov, |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
145 UIO_MAXIOV); |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
146 if (ret != (ssize_t)size) |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
147 break; |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
148 |
2471
4fa0f02369b1
o_stream_sendv() returned wrong value if sending more than UIO_MAXIOV
Timo Sirainen <tss@iki.fi>
parents:
2432
diff
changeset
|
149 sent += ret; |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
150 iov += UIO_MAXIOV; |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
151 iov_size -= UIO_MAXIOV; |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
152 } |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
153 |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
154 if (iov_size <= UIO_MAXIOV) { |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
155 ret = writev(fstream->fd, (const struct iovec *)iov, |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
156 iov_size); |
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
157 } |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
158 if (ret > 0) |
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
159 ret += sent; |
2432
b8d2a5575fe9
Limit iovec count to UIO_MAXIOV for writev() calls.
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
160 } |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
161 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
162 if (ret < 0) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
163 if (errno == EAGAIN || errno == EINTR) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 return 0; |
1224
b661eb87bd26
if connection was closed while trying to write data to client, we sometimes
Timo Sirainen <tss@iki.fi>
parents:
1207
diff
changeset
|
165 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
|
166 stream_closed(fstream); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 return -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 return ret; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
171 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
172 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
173 /* 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
|
174 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
|
175 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
|
176 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
177 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
|
178 return 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
179 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
180 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
|
181 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
|
182 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
|
183 return 1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 } 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
|
185 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
|
186 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
|
187 if (fstream->tail == 0) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
188 return 1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 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
|
190 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
|
191 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
|
192 return 2; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
193 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
194 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
195 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
196 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
197 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
|
198 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
199 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
|
200 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
|
201 ssize_t ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
202 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
203 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
|
204 if (iov_len > 0) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
205 ret = o_stream_writev(fstream, iov, 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
|
206 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
|
207 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
|
208 |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
209 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
|
210 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
212 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
|
213 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
215 static void _cork(struct _ostream *stream, int set) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
217 struct file_ostream *fstream = (struct file_ostream *)stream; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
218 |
2710
ebc72e393388
Don't do anything in cork() if stream is closed.
Timo Sirainen <tss@iki.fi>
parents:
2657
diff
changeset
|
219 if (fstream->corked != set && !stream->ostream.closed) { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
220 if (!fstream->no_socket_cork) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
221 if (net_set_cork(fstream->fd, set) < 0) |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
222 fstream->no_socket_cork = TRUE; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
223 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
224 fstream->corked = set; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
225 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
226 if (set && fstream->io != NULL) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
227 io_remove(fstream->io); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
228 fstream->io = NULL; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
229 } else if (!set && fstream->io == NULL) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
230 if (fstream->file) |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
231 buffer_flush(fstream); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
232 else { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
233 fstream->io = io_add(fstream->fd, IO_WRITE, |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
234 stream_send_io, fstream); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
235 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
236 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
237 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
238 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
240 static int _flush(struct _ostream *stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
242 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
|
243 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
244 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
|
245 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
246 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
247 static size_t get_unused_space(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
|
248 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
249 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
|
250 /* XXXT...HXXX */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
251 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
|
252 } 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
|
253 /* ...HXXXT... */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
254 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
|
255 } else { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
256 /* 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
|
257 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
|
258 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
259 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
260 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
261 static size_t _get_used_size(struct _ostream *stream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
262 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
263 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
|
264 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
265 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
|
266 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
268 static int _seek(struct _ostream *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
|
269 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
270 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
|
271 off_t ret; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
272 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
273 if (offset > OFF_T_MAX) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 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
|
275 return -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
277 |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
278 if (buffer_flush(fstream) < 0) |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
279 return -1; |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
280 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
281 ret = lseek(fstream->fd, (off_t)offset, SEEK_SET); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
282 if (ret < 0) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
283 stream->ostream.stream_errno = errno; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
284 return -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
285 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
287 if (ret != (off_t)offset) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
288 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
|
289 return -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 } |
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 stream->ostream.stream_errno = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
293 stream->ostream.offset = offset; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
294 return 1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
295 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
297 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
|
298 { |
2756
9cd5d91509bb
Growing output buffer size broke the data inside it.
Timo Sirainen <tss@iki.fi>
parents:
2750
diff
changeset
|
299 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
|
300 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 size = nearest_power(fstream->buffer_size + bytes); |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
302 if (size > fstream->max_buffer_size) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
303 /* limit the size */ |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
304 size = fstream->max_buffer_size; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
305 } else if (fstream->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
|
306 /* 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
|
307 new_size = I_MIN(fstream->optimal_block_size, |
b89f471a0e04
When corked, don't limit buffer size to optimal_block_size. Fixes problems
Timo Sirainen <tss@iki.fi>
parents:
2647
diff
changeset
|
308 fstream->max_buffer_size); |
b89f471a0e04
When corked, don't limit buffer size to optimal_block_size. Fixes problems
Timo Sirainen <tss@iki.fi>
parents:
2647
diff
changeset
|
309 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
|
310 size = new_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
313 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
|
314 return; |
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 fstream->buffer = p_realloc(fstream->ostream.iostream.pool, |
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
|
317 fstream->buffer, |
4d6b69558add
Added old_size parameter to p_realloc() - we rarely need it and this way
Timo Sirainen <tss@iki.fi>
parents:
920
diff
changeset
|
318 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
|
319 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
320 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
|
321 /* 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
|
322 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
|
323 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
|
324 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
|
325 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
|
326 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
327 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
328 fstream->full = FALSE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
329 fstream->buffer_size = size; |
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 |
1036
f782b3319553
Removed useless parameters from io_callback_t and timeout_callback_t.
Timo Sirainen <tss@iki.fi>
parents:
953
diff
changeset
|
332 static void stream_send_io(void *context) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
333 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
334 struct file_ostream *fstream = context; |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
335 int ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
336 |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
337 o_stream_ref(&fstream->ostream.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
|
338 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
|
339 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
|
340 else |
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
341 ret = _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
|
342 |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
343 if (ret > 0 && IS_STREAM_EMPTY(fstream) && fstream->io != NULL) { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
344 /* all sent */ |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
345 io_remove(fstream->io); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
346 fstream->io = NULL; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
347 } |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2756
diff
changeset
|
348 o_stream_unref(&fstream->ostream.ostream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
349 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
350 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
351 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
|
352 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
|
353 { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
354 size_t unused, sent; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
355 int i; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
356 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
357 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
|
358 if (unused < size) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
359 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
|
360 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
361 sent = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
362 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
|
363 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
|
364 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
|
365 fstream->head - fstream->tail; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
366 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
367 if (unused > size-sent) |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
368 unused = size-sent; |
2521
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
369 memcpy(fstream->buffer + fstream->tail, |
3418a7f233ff
Output stream sometimes duplicated data and sometimes lost data.
Timo Sirainen <tss@iki.fi>
parents:
2484
diff
changeset
|
370 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
|
371 sent += unused; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
372 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
373 fstream->tail += unused; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
374 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
|
375 fstream->tail = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
376 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
377 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
|
378 fstream->full = TRUE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
379 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
380 |
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
|
381 if (sent != 0 && fstream->io == NULL && |
ce6521e4a191
Automatically set file streams to blocking and don't try to io_add() them.
Timo Sirainen <tss@iki.fi>
parents:
1476
diff
changeset
|
382 !fstream->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
|
383 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
|
384 fstream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
385 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
386 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
387 return sent; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
388 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
389 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
390 static ssize_t _sendv(struct _ostream *stream, const struct const_iovec *iov, |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
391 size_t iov_count) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
392 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
393 struct file_ostream *fstream = (struct file_ostream *)stream; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
394 size_t i, size, added, optimal_size; |
1305 | 395 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
|
396 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
397 stream->ostream.stream_errno = 0; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
398 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
399 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
|
400 size += iov[i].iov_len; |
1305 | 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 if (size > get_unused_space(fstream)) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
403 if (_flush(stream) < 0) |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
404 return -1; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
405 } |
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 optimal_size = I_MIN(fstream->optimal_block_size, |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
408 fstream->max_buffer_size); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
409 if (IS_STREAM_EMPTY(fstream) && |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
410 (!fstream->corked || size >= optimal_size)) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
411 /* send immediately */ |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
412 ret = o_stream_writev(fstream, iov, 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
|
413 if (ret < 0) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
414 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
|
415 |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
416 size = ret; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
417 while (size > 0 && 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
|
418 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
|
419 iov++; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
420 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
|
421 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
422 |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
423 if (iov_count > 0) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
424 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
|
425 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
|
426 iov[0].iov_len - size); |
2484
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
427 ret += added; |
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
428 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
429 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
|
430 /* buffer full */ |
2484
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
431 stream->ostream.offset += ret; |
c8b12c26a040
o_stream_send*() might have returned wrong value
Timo Sirainen <tss@iki.fi>
parents:
2471
diff
changeset
|
432 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
|
433 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
434 |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
435 iov++; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
436 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
|
437 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
438 } |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
439 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
440 /* 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
|
441 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
|
442 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
|
443 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
|
444 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
|
445 break; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
446 } |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
447 stream->ostream.offset += ret; |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
448 return ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
449 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
450 |
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
|
451 static off_t io_stream_sendfile(struct _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
|
452 struct istream *instream, |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
453 int in_fd, uoff_t in_size) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
454 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
455 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
|
456 uoff_t start_offset; |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
457 uoff_t 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
|
458 ssize_t ret; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
459 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
460 /* 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
|
461 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
|
462 return ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
463 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
464 start_offset = v_offset = instream->v_offset; |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
465 do { |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
466 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
|
467 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
|
468 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
469 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
|
470 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
|
471 if (ret <= 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
|
472 if (ret == 0 || errno == EINTR || errno == EAGAIN) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
473 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
|
474 break; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
475 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
476 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
477 outstream->ostream.stream_errno = errno; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
478 if (errno != EINVAL) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
479 /* 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
|
480 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
|
481 stream_closed(foutstream); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
482 } |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
483 break; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
484 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
485 |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
486 v_offset += ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
487 outstream->ostream.offset += ret; |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
488 } 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
|
489 |
1204 | 490 i_stream_seek(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
|
491 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
|
492 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
493 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
494 static off_t io_stream_copy(struct _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
|
495 struct istream *instream, uoff_t in_size) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
496 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
497 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
|
498 uoff_t start_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
|
499 struct const_iovec iov[3]; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
500 int iov_len; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
501 const unsigned char *data; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
502 size_t size, skip_size, block_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
503 ssize_t ret; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
504 int pos; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
505 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
506 iov_len = o_stream_fill_iovec(foutstream, iov); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
507 |
1305 | 508 skip_size = 0; |
509 for (pos = 0; pos < iov_len; pos++) | |
510 skip_size += iov[pos].iov_len; | |
511 | |
2634
b847d8650282
o_stream_send_istream() was buggy if input stream's offset wasn't 0 or if
Timo Sirainen <tss@iki.fi>
parents:
2554
diff
changeset
|
512 start_offset = instream->v_offset; |
b847d8650282
o_stream_send_istream() was buggy if input stream's offset wasn't 0 or if
Timo Sirainen <tss@iki.fi>
parents:
2554
diff
changeset
|
513 in_size -= 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
|
514 while (in_size > 0) { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
515 block_size = I_MIN(foutstream->optimal_block_size, in_size); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
516 (void)i_stream_read_data(instream, &data, &size, block_size-1); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
517 in_size -= size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
518 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
519 if (size == 0) { |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
520 /* all sent */ |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
521 break; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
522 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
523 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
524 pos = iov_len++; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
525 iov[pos].iov_base = (void *) data; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
526 iov[pos].iov_len = size; |
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 ret = o_stream_writev(foutstream, 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
|
529 if (ret < 0) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
530 return -1; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
531 |
1305 | 532 if (skip_size > 0) { |
533 if ((size_t)ret < skip_size) { | |
2536
0d2c47d85a3a
_send_istream() might have crashed.
Timo Sirainen <tss@iki.fi>
parents:
2521
diff
changeset
|
534 update_buffer(foutstream, ret); |
1305 | 535 skip_size -= ret; |
536 ret = 0; | |
537 } else { | |
2536
0d2c47d85a3a
_send_istream() might have crashed.
Timo Sirainen <tss@iki.fi>
parents:
2521
diff
changeset
|
538 update_buffer(foutstream, skip_size); |
1305 | 539 ret -= skip_size; |
540 skip_size = 0; | |
541 } | |
542 } | |
543 outstream->ostream.offset += ret; | |
2988
76d0e16d45e6
Go back to the version before recent changes. It was correct all the time.
Timo Sirainen <tss@iki.fi>
parents:
2985
diff
changeset
|
544 i_stream_skip(instream, ret); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
545 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
546 if ((size_t)ret != iov[pos].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
|
547 break; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
548 |
2554 | 549 i_assert(skip_size == 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
|
550 iov_len = 0; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
551 } |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
552 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
553 return (off_t) (instream->v_offset - start_offset); |
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 |
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
|
556 static off_t io_stream_copy_backwards(struct _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
|
557 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
|
558 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
559 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
|
560 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
|
561 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
|
562 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
|
563 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
|
564 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
565 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
|
566 |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
567 /* 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
|
568 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
|
569 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
|
570 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
|
571 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
|
572 foutstream->optimal_block_size - |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
573 foutstream->buffer_size); |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
574 } |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
575 |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
576 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
|
577 } |
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
|
578 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
579 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
|
580 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
|
581 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
|
582 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
583 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
|
584 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
|
585 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
|
586 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
|
587 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
|
588 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
|
589 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
|
590 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
591 for (;;) { |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
592 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
|
593 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
594 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
|
595 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
|
596 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
597 (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
|
598 read_size-1); |
2040 | 599 if (size >= read_size) { |
600 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
|
601 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
|
602 /* 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
|
603 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
|
604 i_assert(size <= |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
605 foutstream->buffer_size); |
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
606 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
|
607 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
|
608 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
609 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
|
610 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
611 |
2040 | 612 /* buffer too large probably, try with smaller */ |
613 read_size -= size; | |
614 in_offset += read_size; | |
615 out_offset += read_size; | |
616 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
|
617 } |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
618 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
|
619 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
620 if (o_stream_seek(&outstream->ostream, out_offset) < 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
|
621 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
|
622 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
623 ret = write_full(foutstream->fd, data, 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
|
624 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
|
625 /* 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
|
626 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
|
627 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
|
628 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
629 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
630 |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
631 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
|
632 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
633 |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
634 static off_t _send_istream(struct _ostream *outstream, struct istream *instream) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
635 { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
636 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
|
637 uoff_t in_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
638 off_t ret; |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
639 int in_fd, overlapping; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
640 |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
641 in_fd = i_stream_get_fd(instream); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
642 in_size = i_stream_get_size(instream); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
643 i_assert(instream->v_offset <= in_size); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
644 |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
645 outstream->ostream.stream_errno = 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
|
646 if (in_fd != foutstream->fd) |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
647 overlapping = 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
|
648 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
|
649 /* 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
|
650 seeks and overlapping writes. */ |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
651 if (in_size == (uoff_t)-1) { |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
652 outstream->ostream.stream_errno = EINVAL; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
653 return -1; |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
654 } |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
655 |
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
|
656 ret = (off_t)outstream->ostream.offset - |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
657 (off_t)(instream->real_stream->abs_start_offset + |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
658 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
|
659 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
|
660 /* 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
|
661 need to do that, just fake it. */ |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
662 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
|
663 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
664 overlapping = ret < 0 ? -1 : 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
|
665 } |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
666 |
e86f259048cf
o_stream_send_istream() is now safe to use for moving data within file.
Timo Sirainen <tss@iki.fi>
parents:
1146
diff
changeset
|
667 if (!foutstream->no_sendfile && in_fd != -1 && overlapping <= 0) { |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
668 ret = io_stream_sendfile(outstream, instream, in_fd, in_size); |
1115
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
669 if (ret >= 0 || outstream->ostream.stream_errno != EINVAL) |
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
670 return ret; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
671 |
1115
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
672 /* sendfile() not supported (with this fd), fallback to |
1146
ee4bdf40ec10
Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents:
1115
diff
changeset
|
673 regular sending. */ |
1115
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
674 outstream->ostream.stream_errno = 0; |
6a233fbb02a5
Don't bother trying sendfile() more than once with the stream.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
675 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
|
676 } |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
677 |
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
|
678 if (overlapping <= 0) |
1870
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
679 return io_stream_copy(outstream, instream, in_size); |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
680 else |
c972ea085643
istream rewrite. instead of directly setting any limits to stream, you now
Timo Sirainen <tss@iki.fi>
parents:
1861
diff
changeset
|
681 return io_stream_copy_backwards(outstream, instream, in_size); |
1861
e42d97a85653
Added istream->eof. istream->v_size is now set to 0 with files.
Timo Sirainen <tss@iki.fi>
parents:
1834
diff
changeset
|
682 } |
e42d97a85653
Added istream->eof. istream->v_size is now set to 0 with files.
Timo Sirainen <tss@iki.fi>
parents:
1834
diff
changeset
|
683 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
684 struct ostream * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
685 o_stream_create_file(int fd, pool_t pool, size_t max_buffer_size, |
1499
e850252cdc7e
Removed I/O priorities. They were pretty much useless and were just getting
Timo Sirainen <tss@iki.fi>
parents:
1487
diff
changeset
|
686 int autoclose_fd) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
687 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
688 struct file_ostream *fstream; |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
689 struct ostream *ostream; |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
690 struct stat st; |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
691 off_t offset; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
692 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
693 fstream = p_new(pool, struct file_ostream, 1); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
694 fstream->fd = fd; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
695 fstream->max_buffer_size = max_buffer_size; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
696 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
|
697 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
|
698 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
699 fstream->ostream.iostream.close = _close; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
700 fstream->ostream.iostream.destroy = _destroy; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
701 fstream->ostream.iostream.set_max_buffer_size = _set_max_buffer_size; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
702 |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
703 fstream->ostream.cork = _cork; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
704 fstream->ostream.flush = _flush; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
705 fstream->ostream.get_used_size = _get_used_size; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
706 fstream->ostream.seek = _seek; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2245
diff
changeset
|
707 fstream->ostream.sendv = _sendv; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
708 fstream->ostream.send_istream = _send_istream; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
709 |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
710 ostream = _o_stream_create(&fstream->ostream, pool); |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
711 |
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
712 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
|
713 if (offset >= 0) { |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
714 ostream->offset = offset; |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
715 |
1487 | 716 if (fstat(fd, &st) == 0) { |
717 if ((uoff_t)st.st_blksize > | |
718 fstream->optimal_block_size) { | |
719 /* use the optimal block size, but with a | |
720 reasonable limit */ | |
721 fstream->optimal_block_size = | |
722 I_MIN(st.st_blksize, | |
723 MAX_OPTIMAL_BLOCK_SIZE); | |
724 } | |
725 | |
726 if (S_ISREG(st.st_mode)) { | |
727 fstream->no_socket_cork = TRUE; | |
728 fstream->file = TRUE; | |
729 } | |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
730 } |
1345
04b81672c3a3
Call safe_sendfile() only with sockets, and also with files under Linux.
Timo Sirainen <tss@iki.fi>
parents:
1305
diff
changeset
|
731 fstream->no_sendfile = TRUE; |
04b81672c3a3
Call safe_sendfile() only with sockets, and also with files under Linux.
Timo Sirainen <tss@iki.fi>
parents:
1305
diff
changeset
|
732 } else { |
1476 | 733 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
|
734 fstream->no_sendfile = TRUE; |
1487 | 735 fstream->no_socket_cork = TRUE; |
1476 | 736 } |
1245
06b1b95ae756
Try to use optimal block sizes when writing to files.
Timo Sirainen <tss@iki.fi>
parents:
1224
diff
changeset
|
737 } |
2245
95fe82bbda7a
Allow giving 0 max_buffer_size, in which case "optimal" size is used.
Timo Sirainen <tss@iki.fi>
parents:
2072
diff
changeset
|
738 |
95fe82bbda7a
Allow giving 0 max_buffer_size, in which case "optimal" size is used.
Timo Sirainen <tss@iki.fi>
parents:
2072
diff
changeset
|
739 if (max_buffer_size == 0) |
95fe82bbda7a
Allow giving 0 max_buffer_size, in which case "optimal" size is used.
Timo Sirainen <tss@iki.fi>
parents:
2072
diff
changeset
|
740 fstream->max_buffer_size = fstream->optimal_block_size; |
95fe82bbda7a
Allow giving 0 max_buffer_size, in which case "optimal" size is used.
Timo Sirainen <tss@iki.fi>
parents:
2072
diff
changeset
|
741 |
1207
cf9558657ded
ostream: get initial offset. flush buffer before seeking.
Timo Sirainen <tss@iki.fi>
parents:
1204
diff
changeset
|
742 return ostream; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
743 } |