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