1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/proxy/file_mapping_resource.h"
6
7#include <stdio.h>
8#include <sys/mman.h>
9#include <unistd.h>
10
11#include "ppapi/c/pp_errors.h"
12
13namespace ppapi {
14namespace proxy {
15
16namespace {
17
18int32_t ErrnoToPPError(int error_code) {
19  switch (error_code) {
20    case EACCES:
21      return PP_ERROR_NOACCESS;
22    case EAGAIN:
23      return PP_ERROR_NOMEMORY;
24    case EINVAL:
25      return PP_ERROR_BADARGUMENT;
26    case ENFILE:
27    case ENOMEM:
28      return PP_ERROR_NOMEMORY;
29    default:
30      return PP_ERROR_FAILED;
31  }
32}
33
34}  // namespace
35
36// static
37FileMappingResource::MapResult FileMappingResource::DoMapBlocking(
38    scoped_refptr<FileIOResource::FileHolder> file_holder,
39    void* address_hint,
40    int64_t length,
41    uint32_t map_protection,
42    uint32_t map_flags,
43    int64_t offset) {
44  int prot_for_mmap = 0;
45  if (map_protection & PP_FILEMAPPROTECTION_READ)
46    prot_for_mmap |= PROT_READ;
47  if (map_protection & PP_FILEMAPPROTECTION_WRITE)
48    prot_for_mmap |= PROT_WRITE;
49  if (prot_for_mmap == 0)
50    prot_for_mmap = PROT_NONE;
51
52  int flags_for_mmap = 0;
53  if (map_flags & PP_FILEMAPFLAG_SHARED)
54    flags_for_mmap |= MAP_SHARED;
55  if (map_flags & PP_FILEMAPFLAG_PRIVATE)
56    flags_for_mmap |= MAP_PRIVATE;
57  if (map_flags & PP_FILEMAPFLAG_FIXED)
58    flags_for_mmap |= MAP_FIXED;
59
60  MapResult map_result;
61  map_result.address =
62      mmap(address_hint,
63           static_cast<size_t>(length),
64           prot_for_mmap,
65           flags_for_mmap,
66           file_holder->file()->GetPlatformFile(),
67           static_cast<off_t>(offset));
68  if (map_result.address != MAP_FAILED)
69    map_result.result = PP_OK;
70  else
71    map_result.result = ErrnoToPPError(errno);
72  return map_result;
73}
74
75// static
76int32_t FileMappingResource::DoUnmapBlocking(const void* address,
77                                             int64_t length) {
78  if (munmap(const_cast<void*>(address), static_cast<size_t>(length)))
79    return ErrnoToPPError(errno);
80  return PP_OK;
81}
82
83// static
84int64_t FileMappingResource::DoGetMapPageSize() {
85  return getpagesize();
86}
87
88}  // namespace proxy
89}  // namespace ppapi
90