~vcs-imports/eglibc/trunk

« back to all changes in this revision

Viewing changes to libc/locale/programs/locarchive.c

  • Committer: joseph
  • Date: 2013-07-02 00:11:45 UTC
  • Revision ID: svn-v4:7b3dc134-2b1b-0410-93df-9e9f96275f8d:trunk:23422
Merge changes between r23363 and r23421 from /fsf/trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include <stdint.h>
38
38
#include <sys/mman.h>
39
39
#include <sys/param.h>
 
40
#include <sys/shm.h>
40
41
#include <sys/stat.h>
41
42
 
 
43
#include <libc-internal.h>
 
44
#include <libc-mmap.h>
42
45
#include "../../crypt/md5.h"
43
46
#include "../localeinfo.h"
44
47
#include "../locarchive.h"
79
82
   mapping affects the address selection.  So do this mapping from the
80
83
   actual file, even though it's only a dummy to reserve address space.  */
81
84
static void *
82
 
prepare_address_space (int fd, size_t total, size_t *reserved, int *xflags)
 
85
prepare_address_space (int fd, size_t total, size_t *reserved, int *xflags,
 
86
                       void **mmap_base, size_t *mmap_len)
83
87
{
84
88
  if (total < RESERVE_MMAP_SIZE)
85
89
    {
86
90
      void *p = mmap64 (NULL, RESERVE_MMAP_SIZE, PROT_NONE, MAP_SHARED, fd, 0);
87
91
      if (p != MAP_FAILED)
88
 
        {
89
 
          *reserved = RESERVE_MMAP_SIZE;
90
 
          *xflags = MAP_FIXED;
91
 
          return p;
92
 
        }
 
92
        {
 
93
          void *aligned_p = PTR_ALIGN_UP (p, MAP_FIXED_ALIGNMENT);
 
94
          size_t align_adjust = aligned_p - p;
 
95
          *mmap_base = p;
 
96
          *mmap_len = RESERVE_MMAP_SIZE;
 
97
          assert (align_adjust < RESERVE_MMAP_SIZE);
 
98
          *reserved = RESERVE_MMAP_SIZE - align_adjust;
 
99
          *xflags = MAP_FIXED;
 
100
          return aligned_p;
 
101
        }
93
102
    }
94
103
 
95
104
  *reserved = total;
96
105
  *xflags = 0;
 
106
  *mmap_base = NULL;
 
107
  *mmap_len = 0;
97
108
  return NULL;
98
109
}
99
110
 
151
162
      error (EXIT_FAILURE, errval, _("cannot resize archive file"));
152
163
    }
153
164
 
154
 
  size_t reserved;
 
165
  size_t reserved, mmap_len;
155
166
  int xflags;
156
 
  void *p = prepare_address_space (fd, total, &reserved, &xflags);
 
167
  void *mmap_base;
 
168
  void *p = prepare_address_space (fd, total, &reserved, &xflags, &mmap_base,
 
169
                                   &mmap_len);
157
170
 
158
171
  /* Map the header and all the administration data structures.  */
159
172
  p = mmap64 (p, total, PROT_READ | PROT_WRITE, MAP_SHARED | xflags, fd, 0);
199
212
    }
200
213
 
201
214
  ah->fd = fd;
 
215
  ah->mmap_base = mmap_base;
 
216
  ah->mmap_len = mmap_len;
202
217
  ah->addr = p;
203
218
  ah->mmaped = total;
204
219
  ah->reserved = reserved;
271
286
  if (st.st_size > ah->reserved)
272
287
    return false;
273
288
 
274
 
  const size_t pagesz = getpagesize ();
275
 
  size_t start = ah->mmaped & ~(pagesz - 1);
 
289
  size_t start = ALIGN_DOWN (ah->mmaped, MAP_FIXED_ALIGNMENT);
276
290
  void *p = mmap64 (ah->addr + start, st.st_size - start,
277
291
                    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
278
292
                    ah->fd, start);
333
347
                       MAP_SHARED | MAP_FIXED, ah->fd, 0);
334
348
  else
335
349
    {
336
 
      munmap (ah->addr, ah->reserved);
 
350
      if (ah->mmap_base)
 
351
        munmap (ah->mmap_base, ah->mmap_len);
 
352
      else
 
353
        munmap (ah->addr, ah->reserved);
337
354
      ah->addr = mmap64 (NULL, st.st_size, PROT_READ | PROT_WRITE,
338
355
                         MAP_SHARED, ah->fd, 0);
339
356
      ah->reserved = st.st_size;
 
357
      ah->mmap_base = NULL;
 
358
      ah->mmap_len = 0;
340
359
      head = ah->addr;
341
360
    }
342
361
  if (ah->addr == MAP_FAILED)
402
421
      error (EXIT_FAILURE, errval, _("cannot resize archive file"));
403
422
    }
404
423
 
405
 
  size_t reserved;
 
424
  size_t reserved, mmap_len;
406
425
  int xflags;
407
 
  void *p = prepare_address_space (fd, total, &reserved, &xflags);
 
426
  void *mmap_base;
 
427
  void *p = prepare_address_space (fd, total, &reserved, &xflags, &mmap_base,
 
428
                                   &mmap_len);
408
429
 
409
430
  /* Map the header and all the administration data structures.  */
410
431
  p = mmap64 (p, total, PROT_READ | PROT_WRITE, MAP_SHARED | xflags, fd, 0);
424
445
    }
425
446
 
426
447
  new_ah.mmaped = total;
 
448
  new_ah.mmap_base = mmap_base;
 
449
  new_ah.mmap_len = mmap_len;
427
450
  new_ah.addr = p;
428
451
  new_ah.fd = fd;
429
452
  new_ah.reserved = reserved;
607
630
  ah->fd = fd;
608
631
  ah->mmaped = st.st_size;
609
632
 
610
 
  size_t reserved;
 
633
  size_t reserved, mmap_len;
611
634
  int xflags;
612
 
  void *p = prepare_address_space (fd, st.st_size, &reserved, &xflags);
 
635
  void *mmap_base;
 
636
  void *p = prepare_address_space (fd, st.st_size, &reserved, &xflags,
 
637
                                   &mmap_base, &mmap_len);
613
638
 
614
639
  /* Map the entire file.  We might need to compare the category data
615
640
     in the file with the newly added data.  */
621
646
      error (EXIT_FAILURE, errno, _("cannot map archive header"));
622
647
    }
623
648
  ah->reserved = reserved;
 
649
  ah->mmap_base = mmap_base;
 
650
  ah->mmap_len = mmap_len;
624
651
}
625
652
 
626
653
 
629
656
{
630
657
  if (ah->fd != -1)
631
658
    {
632
 
      munmap (ah->addr, ah->reserved);
 
659
      if (ah->mmap_base)
 
660
        munmap (ah->mmap_base, ah->mmap_len);
 
661
      else
 
662
        munmap (ah->addr, ah->reserved);
633
663
      close (ah->fd);
634
664
    }
635
665
}