]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/mach/hurd/mmap.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / mach / hurd / mmap.c
CommitLineData
04277e02 1/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
478b92f0 2 This file is part of the GNU C Library.
28f540f4 3
478b92f0 4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
28f540f4 8
478b92f0
UD
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
28f540f4 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
28f540f4
RM
17
18#include <sys/types.h>
19#include <sys/mman.h>
20#include <errno.h>
21#include <hurd.h>
22#include <hurd/fd.h>
23
24/* Map addresses starting near ADDR and extending for LEN bytes. from
25 OFFSET into the file FD describes according to PROT and FLAGS. If ADDR
26 is nonzero, it is the desired mapping address. If the MAP_FIXED bit is
27 set in FLAGS, the mapping will be at ADDR exactly (which must be
28 page-aligned); otherwise the system chooses a convenient nearby address.
f17a4233 29 The return value is the actual mapping address chosen or (void *) -1
28f540f4
RM
30 for errors (in which case `errno' is set). A successful `mmap' call
31 deallocates any previous mapping for the affected region. */
32
f17a4233
JM
33void *
34__mmap (void *addr, size_t len, int prot, int flags, int fd, off_t offset)
28f540f4
RM
35{
36 error_t err;
37 vm_prot_t vmprot;
38 memory_object_t memobj;
39 vm_address_t mapaddr;
65bf5fa3 40
57a491d1
RM
41 mapaddr = (vm_address_t) addr;
42
fbf86dda 43 /* ADDR and OFFSET must be page-aligned. */
51a3985d 44 if ((mapaddr & (__vm_page_size - 1)) || (offset & (__vm_page_size - 1)))
f17a4233 45 return (void *) (long int) __hurd_fail (EINVAL);
fbf86dda 46
28f540f4
RM
47 vmprot = VM_PROT_NONE;
48 if (prot & PROT_READ)
49 vmprot |= VM_PROT_READ;
50 if (prot & PROT_WRITE)
51 vmprot |= VM_PROT_WRITE;
52 if (prot & PROT_EXEC)
53 vmprot |= VM_PROT_EXECUTE;
54
55 switch (flags & MAP_TYPE)
56 {
57 default:
f17a4233 58 return (void *) (long int) __hurd_fail (EINVAL);
28f540f4
RM
59
60 case MAP_ANON:
61 memobj = MACH_PORT_NULL;
62 break;
63
64 case MAP_FILE:
7752137a 65 case 0: /* Allow, e.g., just MAP_SHARED. */
28f540f4
RM
66 {
67 mach_port_t robj, wobj;
68 if (err = HURD_DPORT_USE (fd, __io_map (port, &robj, &wobj)))
edc7ae46
RM
69 {
70 if (err == MIG_BAD_ID || err == EOPNOTSUPP || err == ENOSYS)
71 err = ENODEV; /* File descriptor doesn't support mmap. */
f17a4233 72 return (void *) (long int) __hurd_dfail (fd, err);
edc7ae46 73 }
28f540f4
RM
74 switch (prot & (PROT_READ|PROT_WRITE))
75 {
e86c5b64
ST
76 /* Although it apparently doesn't make sense to map a file with
77 protection set to PROT_NONE, it is actually sometimes done.
78 In particular, that's how localedef reserves some space for
79 the locale archive file, the rationale being that some
80 implementations take into account whether the mapping is
81 anonymous or not when selecting addresses. */
82 case PROT_NONE:
28f540f4
RM
83 case PROT_READ:
84 memobj = robj;
1a3a58fd
RM
85 if (wobj != MACH_PORT_NULL)
86 __mach_port_deallocate (__mach_task_self (), wobj);
28f540f4
RM
87 break;
88 case PROT_WRITE:
89 memobj = wobj;
1a3a58fd
RM
90 if (robj != MACH_PORT_NULL)
91 __mach_port_deallocate (__mach_task_self (), robj);
28f540f4
RM
92 break;
93 case PROT_READ|PROT_WRITE:
28f540f4 94 if (robj == wobj)
1a3a58fd
RM
95 {
96 memobj = wobj;
97 /* Remove extra reference. */
98 __mach_port_deallocate (__mach_task_self (), memobj);
99 }
a04549c1
JM
100 else if (wobj == MACH_PORT_NULL /* Not writable by mapping. */
101 && !(flags & MAP_SHARED))
1a3a58fd
RM
102 /* The file can only be mapped for reading. Since we are
103 making a private mapping, we will never try to write the
104 object anyway, so we don't care. */
105 memobj = robj;
28f540f4
RM
106 else
107 {
108 __mach_port_deallocate (__mach_task_self (), wobj);
f17a4233 109 return (void *) (long int) __hurd_fail (EACCES);
28f540f4
RM
110 }
111 break;
e86c5b64
ST
112 default:
113 __builtin_unreachable ();
28f540f4
RM
114 }
115 break;
116 /* XXX handle MAP_NOEXTEND */
117 }
118 }
119
65bf5fa3
RM
120 /* XXX handle MAP_INHERIT */
121
28f540f4
RM
122 err = __vm_map (__mach_task_self (),
123 &mapaddr, (vm_size_t) len, (vm_address_t) 0,
868df0f9 124 mapaddr == 0,
28f540f4 125 memobj, (vm_offset_t) offset,
65bf5fa3 126 ! (flags & MAP_SHARED),
28f540f4 127 vmprot, VM_PROT_ALL,
65bf5fa3
RM
128 (flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
129
0ea698ae 130 if (err == KERN_NO_SPACE)
787e4db9 131 {
0ea698ae
ST
132 if (flags & MAP_FIXED)
133 {
134 /* XXX this is not atomic as it is in unix! */
135 /* The region is already allocated; deallocate it first. */
136 err = __vm_deallocate (__mach_task_self (), mapaddr, len);
137 if (! err)
138 err = __vm_map (__mach_task_self (),
139 &mapaddr, (vm_size_t) len, (vm_address_t) 0,
140 0, memobj, (vm_offset_t) offset,
141 ! (flags & MAP_SHARED),
142 vmprot, VM_PROT_ALL,
143 (flags & MAP_SHARED) ? VM_INHERIT_SHARE
144 : VM_INHERIT_COPY);
145 }
868df0f9 146 else if (mapaddr != 0)
787e4db9
RM
147 err = __vm_map (__mach_task_self (),
148 &mapaddr, (vm_size_t) len, (vm_address_t) 0,
0ea698ae 149 1, memobj, (vm_offset_t) offset,
f36f8dcf 150 ! (flags & MAP_SHARED),
787e4db9 151 vmprot, VM_PROT_ALL,
f36f8dcf
RM
152 (flags & MAP_SHARED) ? VM_INHERIT_SHARE
153 : VM_INHERIT_COPY);
787e4db9 154 }
28f540f4
RM
155
156 if (memobj != MACH_PORT_NULL)
157 __mach_port_deallocate (__mach_task_self (), memobj);
158
65bf5fa3 159 if (err)
f17a4233 160 return (void *) (long int) __hurd_fail (err);
65bf5fa3 161
f17a4233 162 return (void *) mapaddr;
28f540f4 163}
6408bdde 164
a166531f 165libc_hidden_def (__mmap)
6408bdde 166weak_alias (__mmap, mmap)