annotate src/lib/sendfile-util.c @ 1329:ae229b7acb4c HEAD

Mailbox names are now sent through imap-quoter instead of just escaping it. This means that mailbox names that would require escapes are instead sent as literals now.
author Timo Sirainen <tss@iki.fi>
date Wed, 02 Apr 2003 05:05:38 +0300
parents 69d922a1d051
children 04b81672c3a3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* kludge a bit to remove _FILE_OFFSET_BITS definition from config.h.
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2 It's required to be able to include sys/sendfile.h with Linux. */
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "../../config.h"
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #undef HAVE_CONFIG_H
528
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
5
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
6 #ifdef HAVE_LINUX_SENDFILE
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
7 # undef _FILE_OFFSET_BITS
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
8 #endif
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include "lib.h"
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include "sendfile-util.h"
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
528
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
13 #ifdef HAVE_LINUX_SENDFILE
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 #include <sys/sendfile.h>
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 ssize_t safe_sendfile(int out_fd, int in_fd, uoff_t *offset, size_t count)
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 {
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 /* REMEBER: uoff_t and off_t may not be of same size. */
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 off_t safe_offset;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 ssize_t ret;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 /* make sure given offset fits into off_t */
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 if (sizeof(off_t) * CHAR_BIT == 32) {
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 /* 32bit off_t */
1146
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
26 if (*offset >= 2147483647L) {
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
27 errno = EINVAL;
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 return -1;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 }
1146
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
30 if (count > 2147483647L - *offset)
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
31 count = 2147483647L - *offset;
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 } else {
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 /* they're most likely the same size. if not, fix this
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 code later */
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 i_assert(sizeof(off_t) == sizeof(uoff_t));
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36
1146
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
37 if (*offset >= OFF_T_MAX) {
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
38 errno = EINVAL;
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 return -1;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 }
1146
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
41 if (count > OFF_T_MAX - *offset)
ee4bdf40ec10 Bugfixes to handling >2GB files.
Timo Sirainen <tss@iki.fi>
parents: 1114
diff changeset
42 count = OFF_T_MAX - *offset;
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 }
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 safe_offset = (off_t)*offset;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 ret = sendfile(out_fd, in_fd, &safe_offset, count);
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 *offset = (uoff_t)safe_offset;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 return ret;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 }
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51
528
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
52 #elif defined(HAVE_FREEBSD_SENDFILE)
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
53
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
54 #include <sys/socket.h>
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
55 #include <sys/uio.h>
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
56
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
57 ssize_t safe_sendfile(int out_fd, int in_fd, uoff_t *offset, size_t count)
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
58 {
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
59 struct sf_hdtr hdtr;
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
60 off_t sbytes;
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
61 int ret;
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
62
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
63 i_assert(count <= SSIZE_T_MAX);
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
64
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
65 memset(&hdtr, 0, sizeof(hdtr));
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
66 ret = sendfile(in_fd, out_fd, *offset, count, &hdtr, &sbytes, 0);
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
67
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
68 *offset += sbytes;
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
69
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
70 if (ret == 0 || (ret == 0 && errno == EAGAIN && sbytes > 0))
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
71 return (ssize_t)sbytes;
1114
44b531fbb32a FreeBSD's sendfile() works only with sockets. Replace errno with EINVAL to
Timo Sirainen <tss@iki.fi>
parents: 976
diff changeset
72 else {
44b531fbb32a FreeBSD's sendfile() works only with sockets. Replace errno with EINVAL to
Timo Sirainen <tss@iki.fi>
parents: 976
diff changeset
73 if (errno == ENOTSOCK) {
44b531fbb32a FreeBSD's sendfile() works only with sockets. Replace errno with EINVAL to
Timo Sirainen <tss@iki.fi>
parents: 976
diff changeset
74 /* out_fd wasn't a socket. behave as if sendfile()
44b531fbb32a FreeBSD's sendfile() works only with sockets. Replace errno with EINVAL to
Timo Sirainen <tss@iki.fi>
parents: 976
diff changeset
75 wasn't supported at all. */
44b531fbb32a FreeBSD's sendfile() works only with sockets. Replace errno with EINVAL to
Timo Sirainen <tss@iki.fi>
parents: 976
diff changeset
76 errno = EINVAL;
44b531fbb32a FreeBSD's sendfile() works only with sockets. Replace errno with EINVAL to
Timo Sirainen <tss@iki.fi>
parents: 976
diff changeset
77 }
528
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
78 return -1;
1114
44b531fbb32a FreeBSD's sendfile() works only with sockets. Replace errno with EINVAL to
Timo Sirainen <tss@iki.fi>
parents: 976
diff changeset
79 }
528
a95b1ccff82e Support FreeBSD-compatible sendfile(). Completely untested.
Timo Sirainen <tss@iki.fi>
parents: 58
diff changeset
80 }
976
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
81
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
82 #elif defined (HAVE_SOLARIS_SENDFILEV)
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
83
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
84 #include <sys/sendfile.h>
1165
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
85 #include "network.h"
976
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
86
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
87 ssize_t safe_sendfile(int out_fd, int in_fd, uoff_t *offset, size_t count)
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
88 {
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
89 struct sendfilevec vec;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
90 size_t sbytes;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
91 ssize_t ret;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
92
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
93 i_assert(count <= SSIZE_T_MAX);
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
94
1165
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
95 /* outfd must be socket, or at least some Solaris versions will
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
96 kernel panic */
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
97 if (net_getsockname(out_fd, NULL, NULL) < 0) {
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
98 errno = EINVAL;
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
99 return -1;
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
100 }
69d922a1d051 Solaris 9 seems to kernel panic if sendfilev() is used with non-socket.
Timo Sirainen <tss@iki.fi>
parents: 1146
diff changeset
101
976
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
102 vec.sfv_fd = in_fd;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
103 vec.sfv_flag = 0;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
104 vec.sfv_off = *offset;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
105 vec.sfv_len = count;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
106
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
107 ret = sendfilev(out_fd, &vec, 1, &sbytes);
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
108
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
109 *offset += sbytes;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
110
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
111 if (ret >= 0 || (ret < 0 && errno == EAGAIN && sbytes > 0))
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
112 return (ssize_t)sbytes;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
113 else
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
114 return -1;
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
115 }
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
116
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 #else
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 ssize_t safe_sendfile(int out_fd __attr_unused__, int in_fd __attr_unused__,
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 uoff_t *offset __attr_unused__,
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 size_t count __attr_unused__)
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 {
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122 errno = EINVAL;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 return -1;
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124 }
976
b3e0f857981c Support for Solaris sendfilev(). Entirely untested, hope it works.
Timo Sirainen <tss@iki.fi>
parents: 528
diff changeset
125
58
8aaa39e7aec8 sendfile() works now properly with 64bit off_t
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126 #endif