• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.5/libatalk/adouble/
1/*
2 * $Id: ad_mmap.c,v 1.6 2008-12-03 18:35:44 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
22static 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 */
31void *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. */
60void *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
111