*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / opncls.c
1 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
2
3 This file is part of BFD, the Binary File Diddler.
4
5 BFD is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
8 any later version.
9
10 BFD is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with BFD; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 /* $Id$ */
20
21 /*** opncls.c -- open and close a bfd. */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26
27
28
29 extern void bfd_cache_init();
30 FILE *bfd_open_file();
31
32 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
33 if we do that we can't use fcntl. */
34 \f
35 /** Locking
36
37 Locking is loosely controlled by the preprocessor variable
38 BFD_LOCKS. I say loosely because Unix barely understands locking
39 -- at least in BSD it doesn't affect programs which don't
40 explicitly use it! That is to say it's practically useless, though
41 if everyone uses this library you'll be OK.
42
43 From among the many and varied lock facilities available, (none of
44 which, of course, knows about any other) we use the fcntl locks,
45 because they're Posix.
46
47 The reason that bfd_openr and bfd_fdopenr exist, yet only bfd_openw
48 exists is because of locking. When we do output, we lock the
49 filename file for output, then open a temporary file which does not
50 actually get its correct filename until closing time. This is
51 safest, but requires the asymmetry in read and write entry points.
52
53 Perhaps, since unix has so many different kinds of locking anyway,
54 we should use the emacs lock scheme?... */
55 \f
56
57 #define obstack_chunk_alloc malloc
58 #define obstack_chunk_free free
59
60 bfd *new_bfd()
61 {
62 struct obstack tmp;
63 bfd *nbfd;
64 obstack_begin(&tmp,128);
65
66 nbfd = (bfd *)obstack_alloc(&tmp,sizeof(bfd));
67 nbfd->memory = tmp;
68
69 nbfd->direction = no_direction;
70 nbfd->iostream = NULL;
71 nbfd->where = 0;
72 nbfd->sections = (asection *)NULL;
73 nbfd->format = bfd_unknown;
74 nbfd->my_archive = (bfd *)NULL;
75 nbfd->origin = 0;
76 nbfd->opened_once = false;
77 nbfd->output_has_begun = false;
78 nbfd->section_count = 0;
79 nbfd->usrdata = (PTR)NULL;
80 nbfd->sections = (asection *)NULL;
81 nbfd->cacheable = false;
82 nbfd->flags = NO_FLAGS;
83 return nbfd;
84 }
85 bfd *new_bfd_contained_in(obfd)
86 bfd *obfd;
87 {
88 bfd *nbfd = new_bfd();
89 nbfd->xvec = obfd->xvec;
90 nbfd->my_archive = obfd;
91 nbfd->direction = read_direction;
92 return nbfd;
93 }
94
95 /** bfd_openr, bfd_fdopenr -- open for reading.
96 Returns a pointer to a freshly-allocated bfd on success, or NULL. */
97
98 bfd *
99 DEFUN(bfd_openr, (filename, target),
100 CONST char *filename AND
101 CONST char *target)
102 {
103 bfd *nbfd;
104 bfd_target *target_vec;
105
106 target_vec = bfd_find_target (target);
107 if (target_vec == NULL) {
108 bfd_error = invalid_target;
109 return NULL;
110 }
111
112 bfd_error = system_call_error;
113 nbfd = new_bfd();
114 if (nbfd == NULL) {
115 bfd_error = no_memory;
116 return NULL;
117 }
118
119 nbfd->filename = filename;
120 nbfd->xvec = target_vec;
121 nbfd->direction = read_direction;
122
123 if (bfd_open_file (nbfd) == NULL) {
124 bfd_error = system_call_error; /* File didn't exist, or some such */
125 bfd_release(nbfd,0);
126 return NULL;
127 }
128 return nbfd;
129 }
130
131
132 /* Don't try to `optimize' this function:
133
134 o - We lock using stack space so that interrupting the locking
135 won't cause a storage leak.
136 o - We open the file stream last, since we don't want to have to
137 close it if anything goes wrong. Closing the stream means closing
138 the file descriptor too, even though we didn't open it.
139 */
140
141 bfd *
142 DEFUN(bfd_fdopenr,(filename, target, fd),
143 CONST char *filename AND
144 CONST char *target AND
145 int fd)
146 {
147 bfd *nbfd;
148 bfd_target *target_vec;
149 int fdflags;
150 #ifdef BFD_LOCKS
151 struct flock lock, *lockp = &lock;
152 #endif
153
154 target_vec = bfd_find_target (target);
155 if (target_vec == NULL) {
156 bfd_error = invalid_target;
157 return NULL;
158 }
159
160 bfd_error = system_call_error;
161
162 fdflags = fcntl (fd, F_GETFL);
163 if (fdflags == -1) return NULL;
164
165 #ifdef BFD_LOCKS
166 lockp->l_type = F_RDLCK;
167 if (fcntl (fd, F_SETLKW, lockp) == -1) return NULL;
168 #endif
169
170 nbfd = new_bfd();
171
172 if (nbfd == NULL) {
173 bfd_error = no_memory;
174 return NULL;
175 }
176 #ifdef BFD_LOCKS
177 nbfd->lock = (struct flock *) (nbfd + 1);
178 #endif
179 /* if the fd were open for read only, this still would not hurt: */
180 nbfd->iostream = (char *) fdopen (fd, "r+");
181 if (nbfd->iostream == NULL) {
182 free (nbfd);
183 return NULL;
184 }
185
186 /* OK, put everything where it belongs */
187
188 nbfd->filename = filename;
189 nbfd->xvec = target_vec;
190
191 /* As a special case we allow a FD open for read/write to
192 be written through, although doing so requires that we end
193 the previous clause with a preposition. */
194 switch (fdflags & O_ACCMODE) {
195 case O_RDONLY: nbfd->direction = read_direction; break;
196 case O_WRONLY: nbfd->direction = write_direction; break;
197 case O_RDWR: nbfd->direction = both_direction; break;
198 default: abort ();
199 }
200
201 #ifdef BFD_LOCKS
202 memcpy (nbfd->lock, lockp, sizeof (struct flock))
203 #endif
204
205 bfd_cache_init (nbfd);
206
207 return nbfd;
208 }
209 \f
210 /** bfd_openw -- open for writing.
211 Returns a pointer to a freshly-allocated bfd on success, or NULL.
212
213 See comment by bfd_fdopenr before you try to modify this function. */
214
215 bfd *
216 DEFUN(bfd_openw,(filename, target),
217 CONST char *filename AND
218 CONST char *target)
219 {
220 bfd *nbfd;
221 bfd_target *target_vec;
222
223 target_vec = bfd_find_target (target);
224 if (target_vec == NULL) return NULL;
225
226 bfd_error = system_call_error;
227
228 /* nbfd has to point to head of malloc'ed block so that bfd_close may
229 reclaim it correctly. */
230
231 nbfd = new_bfd();
232 if (nbfd == NULL) {
233 bfd_error = no_memory;
234 return NULL;
235 }
236
237 nbfd->filename = filename;
238 nbfd->xvec = target_vec;
239 nbfd->direction = write_direction;
240
241 if (bfd_open_file (nbfd) == NULL) {
242 bfd_error = system_call_error; /* File not writeable, etc */
243 free (nbfd);
244 return NULL;
245 }
246 return nbfd;
247 }
248
249
250 \f
251 /** Close up shop, get your deposit back. */
252 boolean
253 bfd_close (abfd)
254 bfd *abfd;
255 {
256 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
257
258 bfd_cache_close(abfd);
259 /* If the file was open for writing and is now executable
260 make it so */
261 if (abfd->direction == write_direction
262 && abfd->flags & EXEC_P) {
263 struct stat buf;
264 stat(abfd->filename, &buf);
265 chmod(abfd->filename,buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH);
266 }
267 obstack_free(&abfd->memory, (PTR)0);
268 return true;
269 }
270 /*
271 called to create a bfd with no ascociated file or target
272 */
273 bfd *
274 DEFUN(bfd_create,(filename, template),
275 CONST char *filename AND
276 CONST bfd *template)
277 {
278 bfd *nbfd = new_bfd();
279 if (nbfd == (bfd *)NULL) {
280 bfd_error = no_memory;
281 return (bfd *)NULL;
282 }
283 nbfd->filename = filename;
284 if(template) {
285 nbfd->xvec = template->xvec;
286 }
287 nbfd->direction = no_direction;
288 bfd_set_format(nbfd, bfd_object);
289 return nbfd;
290
291
292
293 }
294
295 DEFUN(PTR bfd_alloc, (abfd, size),
296 bfd *abfd AND
297 size_t size)
298 {
299 PTR *res = obstack_alloc(&(abfd->memory),size);
300 return res;
301 }
302
303 DEFUN(PTR bfd_zalloc,(abfd, size),
304 bfd *abfd AND
305 size_t size)
306 {
307 PTR res = bfd_alloc(abfd, size);
308 memset(res, 0, size);
309 return res;
310 }
311
312 DEFUN(PTR bfd_realloc,(abfd, old, size),
313 bfd *abfd AND
314 PTR old AND
315 size_t size)
316 {
317 PTR res = bfd_alloc(abfd, size);
318 memcpy(res, old, size);
319 return res;
320 }
321
322
323 DEFUN(size_t bfd_alloc_size,(abfd),
324 bfd *abfd)
325 {
326 struct _obstack_chunk *chunk = abfd->memory.chunk;
327 size_t size = 0;
328 while (chunk) {
329 size += chunk->limit - &(chunk->contents[0]);
330 chunk = chunk->prev;
331 }
332 return size;
333 }
This page took 0.036169 seconds and 5 git commands to generate.