]> arthur.barton.de Git - netatalk.git/blob - libatalk/adouble/ad_sendfile.c
- added a cache for directories offspring count.
[netatalk.git] / libatalk / adouble / ad_sendfile.c
1 /*
2  * $Id: ad_sendfile.c,v 1.5 2002-10-11 14:18:38 didg Exp $
3  *
4  * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
5  * All rights reserved. See COPYRIGHT.
6  *
7  * NOTE: the following uses the fact that sendfile() only exists on
8  * machines with SA_RESTART behaviour. this is all very machine specific. 
9  *
10  * 
11  */
12
13 #ifdef HAVE_CONFIG_H
14 #include "config.h"
15 #endif /* HAVE_CONFIG_H */
16
17 #include <stdio.h>
18 #ifdef HAVE_UNISTD_H
19 #include <unistd.h>
20 #endif /* HAVE_UNISTD_H */
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <sys/socket.h>
24 #include <sys/uio.h>
25
26 #include <atalk/adouble.h>
27
28 #include <atalk/logger.h>
29
30 #include "ad_private.h"
31
32 static int _ad_sendfile_dummy;
33
34 #ifdef ATACC
35
36 #if defined(HAVE_SENDFILE_READ)
37 #ifdef __NR_sendfile
38 int sendfile(int fdout, int fdin, off_t *off, size_t count)
39 {
40 #if _FILE_OFFSET_BITS == 64 
41 #error sendfile
42   return syscall(__NR_sendfile64, fdout, fdin, off, count);
43 #else
44   return syscall(__NR_sendfile, fdout, fdin, off, count);
45 #endif
46 }
47 #endif
48 #endif
49 #endif
50
51 #if defined(HAVE_SENDFILE_READ) || defined(HAVE_SENDFILE_WRITE)
52 static __inline__ int ad_sendfile_init(const struct adouble *ad, 
53                                        const int eid, off_t *off,
54                                        const int end)
55 {
56   int fd;
57
58   if (end) 
59     *off = ad_size(ad, eid) - *off;
60
61   if (eid == ADEID_DFORK) {
62     fd = ad_dfileno(ad);
63   } else {
64     *off += ad_getentryoff(ad, eid);
65     fd = ad_hfileno(ad);
66   }
67
68   return fd;
69 }
70 #endif
71
72
73 /* read from adouble file and write to socket. sendfile doesn't change
74  * the file pointer position. */
75 #ifdef HAVE_SENDFILE_READ
76 ssize_t ad_readfile(const struct adouble *ad, const int eid, 
77                     const int sock, off_t off, const size_t len)
78 {
79   off_t cc;
80   int fd;
81
82   fd = ad_sendfile_init(ad, eid, &off, 0);
83 #ifdef __linux__
84   cc = sendfile(sock, fd, &off, len);
85 #endif /* __linux__ */
86
87 #ifdef BSD4_4
88   if (sendfile(fd, sock, off, len, NULL, &cc, 0) < 0)
89     return -1;
90 #endif /* BSD4_4 */
91
92   return cc;
93 }
94 #endif /* HAVE_SENDFILE_READ */
95
96 #if 0
97 #ifdef HAVE_SENDFILE_WRITE
98 /* read from a socket and write to an adouble file */
99 ssize_t ad_writefile(struct adouble *ad, const int eid, 
100                      const int sock, off_t off, const int end,
101                      const size_t len)
102 {
103 #ifdef __linux__
104   ssize_t cc;
105   int fd;
106
107   fd = ad_sendfile_init(ad, eid, &off, end);
108   if ((cc = sendfile(fd, sock, &off, len)) < 0)
109     return -1;
110
111   if ((eid != ADEID_DFORK) && (off > ad_getentrylen(ad, eid))) 
112     ad_setentrylen(ad, eid, off);
113
114   return cc;
115 #endif /* __linux__ */
116 }
117 #endif /* HAVE_SENDFILE_WRITE */
118 #endif /* 0 */