2 * $Id: ad_mmap.c,v 1.4 2002-10-05 13:20:14 didg Exp $
4 * ad_mmap provides interfaces to memory mapped files. as this is the
5 * case, we don't have to deal w/ temporary buffers such as
6 * ad_data. the ad_mmap routines are designed to not interact w/ the
7 * ad_read/ad_write routines to avoid confusion.
12 #endif /* HAVE_CONFIG_H */
14 #ifdef USE_MMAPPED_HEADERS
16 #include <sys/types.h>
20 #endif /* HAVE_UNISTD_H */
23 #endif /* HAVE_FCNTL_H */
26 #include <atalk/adouble.h>
28 #include "ad_private.h"
30 static __inline__ void *ad_mmap(const size_t length, const int prot,
31 const int flags, const int fd,
34 return mmap(0, length, prot, flags, fd, offset);
37 /* this just sets things up for mmap. as mmap can handle offsets,
38 * we need to reset the file position before handing it off */
39 void *ad_mmapread(struct adouble *ad, const u_int32_t eid,
40 const off_t off, const size_t buflen)
43 if ( eid == ADEID_DFORK ) {
44 if ( lseek( ad->ad_df.adf_fd, 0, SEEK_SET ) < 0 ) {
48 ad->ad_df.adf_off = 0;
49 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_PRIVATE,
50 ad->ad_df.adf_fd, off);
55 if ( lseek( ad->ad_hf.adf_fd, 0, SEEK_SET ) < 0 ) {
59 ad->ad_hf.adf_off = 0;
60 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_PRIVATE,
61 ad->ad_hf.adf_fd, ad->ad_eid[eid].ade_off + off);
65 /* to do writeable mmaps correctly, we actually need to make sure that
66 * the file to be mapped is large enough. that's what all the initial
68 void *ad_mmapwrite(struct adouble *ad, const u_int32_t eid,
69 off_t off, const int end, const size_t buflen)
74 if ( eid == ADEID_DFORK ) {
75 if ( fstat( ad->ad_df.adf_fd, &st ) < 0 ) {
80 off = st.st_size - off;
83 /* make sure the file is large enough */
84 if (st.st_size < buflen + off)
85 ftruncate(ad->ad_df.adf_fd, buflen + off);
87 if ( lseek( ad->ad_df.adf_fd, 0, SEEK_SET ) < 0 ) {
90 ad->ad_df.adf_off = 0;
91 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_SHARED,
92 ad->ad_df.adf_fd, off);
96 if ( fstat( ad->ad_hf.adf_fd, &st ) < 0 ) {
101 off = ad->ad_eid[ eid ].ade_len - off;
104 off += ad->ad_eid[eid].ade_off;
106 /* make sure the file is large enough */
107 if (st.st_size < buflen + off)
108 ftruncate(ad->ad_hf.adf_fd, buflen + off);
110 if ( lseek( ad->ad_hf.adf_fd, 0, SEEK_SET ) < 0 ) {
113 ad->ad_hf.adf_off = 0;
114 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_SHARED,
115 ad->ad_hf.adf_fd, off);