2 * $Id: ad_sendfile.c,v 1.6 2003-02-17 01:51:07 srittau Exp $
4 * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
5 * All rights reserved. See COPYRIGHT.
7 * NOTE: the following uses the fact that sendfile() only exists on
8 * machines with SA_RESTART behaviour. this is all very machine specific.
15 #endif /* HAVE_CONFIG_H */
20 #endif /* HAVE_UNISTD_H */
21 #include <sys/types.h>
23 #include <sys/socket.h>
26 #include <atalk/adouble.h>
28 #include <atalk/logger.h>
30 #include "ad_private.h"
34 #if defined(HAVE_SENDFILE_READ)
36 int sendfile(int fdout, int fdin, off_t *off, size_t count)
38 #if _FILE_OFFSET_BITS == 64
40 return syscall(__NR_sendfile64, fdout, fdin, off, count);
42 return syscall(__NR_sendfile, fdout, fdin, off, count);
49 #if defined(HAVE_SENDFILE_READ) || defined(HAVE_SENDFILE_WRITE)
50 static __inline__ int ad_sendfile_init(const struct adouble *ad,
51 const int eid, off_t *off,
57 *off = ad_size(ad, eid) - *off;
59 if (eid == ADEID_DFORK) {
62 *off += ad_getentryoff(ad, eid);
71 /* read from adouble file and write to socket. sendfile doesn't change
72 * the file pointer position. */
73 #ifdef HAVE_SENDFILE_READ
74 ssize_t ad_readfile(const struct adouble *ad, const int eid,
75 const int sock, off_t off, const size_t len)
80 fd = ad_sendfile_init(ad, eid, &off, 0);
82 cc = sendfile(sock, fd, &off, len);
83 #endif /* __linux__ */
86 if (sendfile(fd, sock, off, len, NULL, &cc, 0) < 0)
92 #endif /* HAVE_SENDFILE_READ */
95 #ifdef HAVE_SENDFILE_WRITE
96 /* read from a socket and write to an adouble file */
97 ssize_t ad_writefile(struct adouble *ad, const int eid,
98 const int sock, off_t off, const int end,
105 fd = ad_sendfile_init(ad, eid, &off, end);
106 if ((cc = sendfile(fd, sock, &off, len)) < 0)
109 if ((eid != ADEID_DFORK) && (off > ad_getentrylen(ad, eid)))
110 ad_setentrylen(ad, eid, off);
113 #endif /* __linux__ */
115 #endif /* HAVE_SENDFILE_WRITE */