blob: e6f65064449fd6b27e13f3c542f577954e73d177 [file] [log] [blame]
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -08001/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * System utilities.
5 */
6#include <stdlib.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <string.h>
10#include <sys/mman.h>
11#include <limits.h>
12#include <errno.h>
13#include <assert.h>
14
15#define LOG_TAG "minzip"
16#include "Log.h"
17#include "SysUtil.h"
18
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080019static int getFileStartAndLength(int fd, off_t *start_, size_t *length_)
20{
21 off_t start, end;
22 size_t length;
23
24 assert(start_ != NULL);
25 assert(length_ != NULL);
26
27 start = lseek(fd, 0L, SEEK_CUR);
28 end = lseek(fd, 0L, SEEK_END);
29 (void) lseek(fd, start, SEEK_SET);
30
31 if (start == (off_t) -1 || end == (off_t) -1) {
32 LOGE("could not determine length of file\n");
33 return -1;
34 }
35
36 length = end - start;
37 if (length == 0) {
38 LOGE("file is empty\n");
39 return -1;
40 }
41
42 *start_ = start;
43 *length_ = length;
44
45 return 0;
46}
47
48/*
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080049 * Map a file (from fd's current offset) into a shared, read-only memory
50 * segment. The file offset must be a multiple of the page size.
51 *
52 * On success, returns 0 and fills out "pMap". On failure, returns a nonzero
53 * value and does not disturb "pMap".
54 */
55int sysMapFileInShmem(int fd, MemMapping* pMap)
56{
57 off_t start;
58 size_t length;
59 void* memPtr;
60
61 assert(pMap != NULL);
62
63 if (getFileStartAndLength(fd, &start, &length) < 0)
64 return -1;
65
66 memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start);
67 if (memPtr == MAP_FAILED) {
68 LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", (int) length,
69 fd, (int) start, strerror(errno));
70 return -1;
71 }
72
73 pMap->baseAddr = pMap->addr = memPtr;
74 pMap->baseLength = pMap->length = length;
75
76 return 0;
77}
78
79/*
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080080 * Release a memory mapping.
81 */
82void sysReleaseShmem(MemMapping* pMap)
83{
84 if (pMap->baseAddr == NULL && pMap->baseLength == 0)
85 return;
86
87 if (munmap(pMap->baseAddr, pMap->baseLength) < 0) {
88 LOGW("munmap(%p, %d) failed: %s\n",
89 pMap->baseAddr, (int)pMap->baseLength, strerror(errno));
90 } else {
91 LOGV("munmap(%p, %d) succeeded\n", pMap->baseAddr, pMap->baseLength);
92 pMap->baseAddr = NULL;
93 pMap->baseLength = 0;
94 }
95}