annotate osdep/mmap-os2.c @ 36532:2398517e5bda

film: Fix memory leaks in error cases.
author reimar
date Sun, 19 Jan 2014 11:30:05 +0000
parents c70109fc98b2
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
26076
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
1 /*
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
2 * very simple implementation of mmap() for OS/2
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
3 *
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
4 * Copyright (c) 2008 KO Myung-Hun (komh@chollian.net)
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
5 *
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
6 * This file is part of MPlayer.
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
7 *
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
8 * MPlayer is free software; you can redistribute it and/or modify
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
9 * it under the terms of the GNU General Public License as published by
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
10 * the Free Software Foundation; either version 2 of the License, or
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
11 * (at your option) any later version.
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
12 *
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
13 * MPlayer is distributed in the hope that it will be useful,
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
16 * GNU General Public License for more details.
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
17 *
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
18 * You should have received a copy of the GNU General Public License along
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
21 */
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
22
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
23 #define INCL_DOS
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
24 #include <os2.h>
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
25
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
26 #include <stdio.h>
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
27 #include <stdlib.h>
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
28 #include <io.h>
32675
c70109fc98b2 Add/remove a few standard header #includes in our libc function replacements.
diego
parents: 30702
diff changeset
29 #include <unistd.h>
26076
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
30 #include <sys/types.h>
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
31
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
32 #include "config.h"
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
33 #include "mmap.h"
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
34 #include "mmap_anon.h"
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
35
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
36 typedef struct os2_mmap_s
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
37 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
38 void *addr;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
39 size_t len;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
40 int flags;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
41 struct os2_mmap_s *prev;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
42 struct os2_mmap_s *next;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
43 } os2_mmap;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
44 static os2_mmap *m_mmap = NULL;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
45
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
46 void *mmap( void *addr, size_t len, int prot, int flags, int fildes, off_t off )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
47 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
48 os2_mmap *new_mmap;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
49
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
50 ULONG fl;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
51 ULONG rc;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
52
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
53 void *ret;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
54
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
55 if( prot & PROT_WRITE )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
56 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
57 if( flags & MAP_SHARED )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
58 return MAP_FAILED;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
59
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
60 if( !( flags & MAP_PRIVATE ))
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
61 return MAP_FAILED;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
62 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
63
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
64 if( flags & MAP_FIXED )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
65 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
66 ULONG cb;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
67
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
68 cb = len;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
69 rc = DosQueryMem( addr, &cb, &fl );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
70 if( rc || ( cb < len ))
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
71 return MAP_FAILED;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
72
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
73 rc = DosSetMem( addr, len, fPERM );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
74 if( rc )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
75 return MAP_FAILED;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
76
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
77 ret = addr;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
78 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
79 else
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
80 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
81 // Allocate tiled memory compatible with 16-bit selectors
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
82 // 'fs_seg' in 'ldt_keeper.c' need this attribute
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
83 rc = DosAllocMem( &ret, len, fALLOC );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
84 if( rc )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
85 return MAP_FAILED;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
86 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
87
30702
9fc9d1e788aa Do not cast the results of malloc/calloc/realloc.
diego
parents: 26076
diff changeset
88 new_mmap = malloc( sizeof( os2_mmap ));
26076
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
89 new_mmap->addr = ret;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
90 new_mmap->len = len;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
91 new_mmap->flags = flags;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
92 new_mmap->prev = m_mmap;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
93 new_mmap->next = NULL;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
94
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
95 if( m_mmap )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
96 m_mmap->next = new_mmap;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
97 m_mmap = new_mmap;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
98
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
99 if( !( flags & MAP_ANON ))
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
100 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
101 int pos;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
102
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
103 /* Now read in the file */
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
104 if(( pos = lseek( fildes, off, SEEK_SET )) == -1)
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
105 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
106 munmap( ret, len );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
107
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
108 return MAP_FAILED;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
109 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
110
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
111 read( fildes, ret, len );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
112 lseek( fildes, pos, SEEK_SET ); /* Restore the file pointer */
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
113 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
114
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
115 fl = 0;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
116
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
117 if( prot & PROT_READ )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
118 fl |= PAG_READ;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
119
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
120 if( prot & PROT_WRITE )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
121 fl |= PAG_WRITE;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
122
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
123 if( prot & PROT_EXEC )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
124 fl |= PAG_EXECUTE;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
125
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
126 if( prot & PROT_NONE )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
127 fl |= PAG_GUARD;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
128
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
129 rc = DosSetMem( ret, len, fl );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
130 if( rc )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
131 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
132 munmap( ret, len );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
133
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
134 return MAP_FAILED;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
135 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
136
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
137 return ret;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
138 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
139
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
140 int munmap( void *addr, size_t len )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
141 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
142 os2_mmap *mm;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
143
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
144 for( mm = m_mmap; mm; mm = mm->prev )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
145 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
146 if( mm->addr == addr )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
147 break;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
148 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
149
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
150 if( mm )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
151 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
152
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
153 if( !( mm->flags & MAP_FIXED ))
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
154 DosFreeMem( addr );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
155
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
156 if( mm->next )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
157 mm->next->prev = mm->prev;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
158
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
159 if( mm->prev )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
160 mm->prev->next = mm->next;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
161
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
162 if( m_mmap == mm )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
163 m_mmap = mm->prev;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
164
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
165 free( mm );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
166
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
167 return 0;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
168 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
169
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
170 return -1;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
171 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
172
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
173 int mprotect( void *addr, size_t len, int prot )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
174 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
175 os2_mmap *mm;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
176
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
177 for( mm = m_mmap; mm; mm = mm->prev )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
178 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
179 if( mm->addr == addr )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
180 break;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
181 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
182
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
183 if( mm )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
184 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
185 ULONG fl;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
186
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
187 fl = 0;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
188
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
189 if( prot & PROT_READ )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
190 fl |= PAG_READ;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
191
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
192 if( prot & PROT_WRITE )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
193 fl |= PAG_WRITE;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
194
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
195 if( prot & PROT_EXEC )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
196 fl |= PAG_EXECUTE;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
197
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
198 if( prot & PROT_NONE )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
199 fl |= PAG_GUARD;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
200
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
201 if( DosSetMem( addr, len, fl ) == 0 )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
202 return 0;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
203 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
204
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
205 return -1;
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
206 }
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
207
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
208 void *mmap_anon( void *addr, size_t len, int prot, int flags, off_t off )
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
209 {
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
210 return mmap( addr, len, prot, flags | MAP_ANON, -1, off );
c4d1f32ca1a4 mmap() support for OS/2
diego
parents:
diff changeset
211 }