2 * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
3 * All rights reserved. See COPYRIGHT.
5 * NOTE: the following uses the fact that sendfile() only exists on
6 * machines with SA_RESTART behaviour. this is all very machine specific.
8 * sendfile chainsaw from samba.
9 Unix SMB/Netbios implementation.
11 sendfile implementations.
12 Copyright (C) Jeremy Allison 2002.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 #endif /* HAVE_CONFIG_H */
34 #include <sys/socket.h>
38 #include <atalk/adouble.h>
39 #include <atalk/logger.h>
43 #if defined(SENDFILE_FLAVOR_LINUX)
44 #include <sys/sendfile.h>
46 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
48 return sendfile(tofd, fromfd, offset, count);
51 #elif defined(SENDFILE_FLAVOR_SOLARIS)
52 #include <sys/sendfile.h>
54 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
56 return sendfile(tofd, fromfd, offset, count);
59 #elif defined(SENDFILE_FLAVOR_BSD )
60 #include <sys/sendfile.h>
61 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
70 ret = sendfile(fromfd, tofd, offset, count, NULL, &nwritten, 0);
71 while (ret == -1 && errno == EINTR);
82 ssize_t sys_sendfile(int out_fd, int in_fd, off_t *_offset, size_t count)
84 /* No sendfile syscall. */
90 /* ------------------------------- */
91 int ad_readfile_init(const struct adouble *ad,
92 const int eid, off_t *off,
98 *off = ad_size(ad, eid) - *off;
100 if (eid == ADEID_DFORK) {
101 fd = ad_data_fileno(ad);
103 *off += ad_getentryoff(ad, eid);
104 fd = ad_reso_fileno(ad);
111 /* ------------------------ */
113 #ifdef HAVE_SENDFILE_WRITE
114 /* read from a socket and write to an adouble file */
115 ssize_t ad_writefile(struct adouble *ad, const int eid,
116 const int sock, off_t off, const int end,
123 fd = ad_sendfile_init(ad, eid, &off, end);
124 if ((cc = sys_sendfile(fd, sock, &off, len)) < 0)
127 if ((eid != ADEID_DFORK) && (off > ad_getentrylen(ad, eid)))
128 ad_setentrylen(ad, eid, off);
131 #endif /* __linux__ */
133 #endif /* HAVE_SENDFILE_WRITE */