]>
git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/mach/hurd/mmap.c
1 /* Copyright (C) 1994, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
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
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
19 #include <sys/types.h>
25 /* Map addresses starting near ADDR and extending for LEN bytes. from
26 OFFSET into the file FD describes according to PROT and FLAGS. If ADDR
27 is nonzero, it is the desired mapping address. If the MAP_FIXED bit is
28 set in FLAGS, the mapping will be at ADDR exactly (which must be
29 page-aligned); otherwise the system chooses a convenient nearby address.
30 The return value is the actual mapping address chosen or (caddr_t) -1
31 for errors (in which case `errno' is set). A successful `mmap' call
32 deallocates any previous mapping for the affected region. */
35 __mmap (caddr_t addr
, size_t len
, int prot
, int flags
, int fd
, off_t offset
)
39 memory_object_t memobj
;
43 pageoff
= offset
& (vm_page_size
- 1);
44 offset
&= ~(vm_page_size
- 1);
46 mapaddr
= (vm_address_t
) addr
;
47 if (flags
& MAP_FIXED
)
49 /* A specific address is requested. It need not be page-aligned;
50 it just needs to be congruent with the object offset. */
51 if ((mapaddr
& (vm_page_size
- 1)) != pageoff
)
52 return (caddr_t
) (long int) __hurd_fail (EINVAL
);
54 /* We will add back PAGEOFF after mapping. */
58 vmprot
= VM_PROT_NONE
;
60 vmprot
|= VM_PROT_READ
;
61 if (prot
& PROT_WRITE
)
62 vmprot
|= VM_PROT_WRITE
;
64 vmprot
|= VM_PROT_EXECUTE
;
66 switch (flags
& MAP_TYPE
)
69 return (caddr_t
) (long int) __hurd_fail (EINVAL
);
72 memobj
= MACH_PORT_NULL
;
76 case 0: /* Allow, e.g., just MAP_SHARED. */
78 mach_port_t robj
, wobj
;
79 if (err
= HURD_DPORT_USE (fd
, __io_map (port
, &robj
, &wobj
)))
80 return (caddr_t
) (long int) __hurd_dfail (fd
, err
);
81 switch (prot
& (PROT_READ
|PROT_WRITE
))
85 if (wobj
!= MACH_PORT_NULL
)
86 __mach_port_deallocate (__mach_task_self (), wobj
);
90 if (robj
!= MACH_PORT_NULL
)
91 __mach_port_deallocate (__mach_task_self (), robj
);
93 case PROT_READ
|PROT_WRITE
:
97 /* Remove extra reference. */
98 __mach_port_deallocate (__mach_task_self (), memobj
);
100 else if (wobj
== MACH_PORT_NULL
&& /* Not writable by mapping. */
101 (flags
& (MAP_COPY
|MAP_PRIVATE
)))
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. */
108 __mach_port_deallocate (__mach_task_self (), wobj
);
109 return ((caddr_t
) (long int)
110 __hurd_fail (EGRATUITOUS
)); /* XXX */
115 /* XXX handle MAP_NOEXTEND */
119 /* XXX handle MAP_INHERIT */
121 err
= __vm_map (__mach_task_self (),
122 &mapaddr
, (vm_size_t
) len
, (vm_address_t
) 0,
123 ! (flags
& MAP_FIXED
),
124 memobj
, (vm_offset_t
) offset
,
125 ! (flags
& MAP_SHARED
),
127 (flags
& MAP_SHARED
) ? VM_INHERIT_SHARE
: VM_INHERIT_COPY
);
129 if (err
== KERN_NO_SPACE
&& (flags
& MAP_FIXED
))
131 /* XXX this is not atomic as it is in unix! */
132 /* The region is already allocated; deallocate it first. */
133 err
= __vm_deallocate (__mach_task_self (), mapaddr
, len
);
135 err
= __vm_map (__mach_task_self (),
136 &mapaddr
, (vm_size_t
) len
, (vm_address_t
) 0,
137 0, memobj
, (vm_offset_t
) offset
,
138 flags
& (MAP_COPY
|MAP_PRIVATE
),
140 (flags
& MAP_INHERIT
) == 0 ? VM_INHERIT_NONE
:
141 (flags
& (MAP_COPY
|MAP_PRIVATE
)) ? VM_INHERIT_COPY
:
145 if (memobj
!= MACH_PORT_NULL
)
146 __mach_port_deallocate (__mach_task_self (), memobj
);
149 return (caddr_t
) (long int) __hurd_fail (err
);
151 /* Adjust the mapping address for the offset-within-page. */
154 return (caddr_t
) mapaddr
;
157 weak_alias (__mmap
, mmap
)