2 * $Id: ad_mmap.c,v 1.3 2001-06-29 14:14:46 rufustfirefly 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 */
15 #include <sys/types.h>
19 #endif /* HAVE_UNISTD_H */
22 #endif /* HAVE_FCNTL_H */
25 #include <atalk/adouble.h>
27 #include "ad_private.h"
29 static __inline__ void *ad_mmap(const size_t length, const int prot,
30 const int flags, const int fd,
33 return mmap(0, length, prot, flags, fd, offset);
36 /* this just sets things up for mmap. as mmap can handle offsets,
37 * we need to reset the file position before handing it off */
38 void *ad_mmapread(struct adouble *ad, const u_int32_t eid,
39 const off_t off, const size_t buflen)
42 if ( eid == ADEID_DFORK ) {
43 if ( lseek( ad->ad_df.adf_fd, 0, SEEK_SET ) < 0 ) {
47 ad->ad_df.adf_off = 0;
48 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_PRIVATE,
49 ad->ad_df.adf_fd, off);
54 if ( lseek( ad->ad_hf.adf_fd, 0, SEEK_SET ) < 0 ) {
58 ad->ad_hf.adf_off = 0;
59 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_PRIVATE,
60 ad->ad_hf.adf_fd, ad->ad_eid[eid].ade_off + off);
64 /* to do writeable mmaps correctly, we actually need to make sure that
65 * the file to be mapped is large enough. that's what all the initial
67 void *ad_mmapwrite(struct adouble *ad, const u_int32_t eid,
68 off_t off, const int end, const size_t buflen)
73 if ( eid == ADEID_DFORK ) {
74 if ( fstat( ad->ad_df.adf_fd, &st ) < 0 ) {
79 off = st.st_size - off;
82 /* make sure the file is large enough */
83 if (st.st_size < buflen + off)
84 ftruncate(ad->ad_df.adf_fd, buflen + off);
86 if ( lseek( ad->ad_df.adf_fd, 0, SEEK_SET ) < 0 ) {
89 ad->ad_df.adf_off = 0;
90 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_SHARED,
91 ad->ad_df.adf_fd, off);
95 if ( fstat( ad->ad_hf.adf_fd, &st ) < 0 ) {
100 off = ad->ad_eid[ eid ].ade_len - off;
103 off += ad->ad_eid[eid].ade_off;
105 /* make sure the file is large enough */
106 if (st.st_size < buflen + off)
107 ftruncate(ad->ad_hf.adf_fd, buflen + off);
109 if ( lseek( ad->ad_hf.adf_fd, 0, SEEK_SET ) < 0 ) {
112 ad->ad_hf.adf_off = 0;
113 return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_SHARED,
114 ad->ad_hf.adf_fd, off);