annotate src/lib/ostream-file.c @ 22955:812e5c961328

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