]> arthur.barton.de Git - netatalk.git/blob - libatalk/adouble/ad_mmap.c
Spotlight: use async Tracker SPARQL API
[netatalk.git] / libatalk / adouble / ad_mmap.c
1 /*
2  * ad_mmap provides interfaces to memory mapped files. as this is the
3  * case, we don't have to deal w/ temporary buffers such as
4  * ad_data. the ad_mmap routines are designed to not interact w/ the
5  * ad_read/ad_write routines to avoid confusion.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #ifdef USE_MMAPPED_HEADERS
13 #include <stdio.h>
14
15 #include <atalk/adouble.h>
16 #include <string.h>
17
18 #include "ad_lock.h"
19
20 static void *ad_mmap(const size_t length, const int prot,
21                                 const int flags, const int fd, 
22                                 const off_t offset)
23 {
24   return mmap(0, length, prot, flags, fd, offset);
25 }
26
27 /* this just sets things up for mmap. as mmap can handle offsets,
28  * we need to reset the file position before handing it off */
29 void *ad_mmapread(struct adouble *ad, const u_int32_t eid, 
30                   const off_t off, const size_t buflen)
31 {
32     /* data fork */
33     if ( eid == ADEID_DFORK ) {
34       if ( lseek( ad->ad_df.adf_fd, 0, SEEK_SET ) < 0 ) {
35         perror( "df lseek" );
36         return (void *) -1;
37       }
38       ad->ad_df.adf_off = 0;
39       return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_PRIVATE, 
40                      ad->ad_df.adf_fd, off);
41
42     }
43
44     /* resource fork */
45     if ( lseek( ad->ad_hf.adf_fd, 0, SEEK_SET ) < 0 ) {
46       perror( "hf lseek" );
47       return (void *) -1;
48     }
49     ad->ad_hf.adf_off = 0;
50     return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_PRIVATE, 
51                    ad->ad_hf.adf_fd, ad->ad_eid[eid].ade_off + off);
52 }
53
54
55 /* to do writeable mmaps correctly, we actually need to make sure that
56  * the file to be mapped is large enough. that's what all the initial
57  * mess is for. */
58 void *ad_mmapwrite(struct adouble *ad, const u_int32_t eid,
59                    off_t off, const int end, const size_t buflen)
60 {
61     struct stat st;
62
63     /* data fork */
64     if ( eid == ADEID_DFORK ) {
65         if ( fstat( ad->ad_df.adf_fd, &st ) < 0 ) {
66             return (void *) -1;
67         }
68
69         if ( end ) {
70             off = st.st_size - off;
71         }
72
73         /* make sure the file is large enough */
74         if (st.st_size < buflen + off) 
75           ftruncate(ad->ad_df.adf_fd, buflen + off);
76
77         if ( lseek( ad->ad_df.adf_fd, 0, SEEK_SET ) < 0 ) {
78           return (void *) -1;
79         }
80         ad->ad_df.adf_off = 0;
81         return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_SHARED,
82                        ad->ad_df.adf_fd, off);
83     }
84
85     
86     if ( fstat( ad->ad_hf.adf_fd, &st ) < 0 ) {
87         return (void *) -1;
88     }
89     
90     if ( end ) {
91         off = ad->ad_eid[ eid ].ade_len - off;
92     }
93     
94     off += ad->ad_eid[eid].ade_off;
95
96     /* make sure the file is large enough */
97     if (st.st_size < buflen + off) 
98       ftruncate(ad->ad_hf.adf_fd, buflen + off);
99
100     if ( lseek( ad->ad_hf.adf_fd, 0, SEEK_SET ) < 0 ) {
101       return (void *) -1;
102     }
103     ad->ad_hf.adf_off = 0;
104     return ad_mmap(buflen, PROT_READ | PROT_WRITE, MAP_SHARED,
105                    ad->ad_hf.adf_fd, off);
106 }
107
108 #endif