1 /* opncls.c -- open and close a BFD.
2 Copyright (C) 1990 91, 92, 93, 94 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 extern void bfd_cache_init PARAMS ((bfd *));
26 FILE *bfd_open_file PARAMS ((bfd *));
28 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
29 if we do that we can't use fcntl. */
32 #define obstack_chunk_alloc malloc
33 #define obstack_chunk_free free
35 /* Return a new BFD. All BFD's are allocated through this routine. */
42 nbfd = (bfd *)bfd_zmalloc (sizeof (bfd));
45 bfd_error = no_memory;
50 if (!obstack_begin(&nbfd->memory, 128))
52 bfd_error = no_memory;
56 nbfd->arch_info = &bfd_default_arch_struct;
58 nbfd->direction = no_direction;
59 nbfd->iostream = NULL;
61 nbfd->sections = (asection *)NULL;
62 nbfd->format = bfd_unknown;
63 nbfd->my_archive = (bfd *)NULL;
65 nbfd->opened_once = false;
66 nbfd->output_has_begun = false;
67 nbfd->section_count = 0;
68 nbfd->usrdata = (PTR)NULL;
69 nbfd->cacheable = false;
70 nbfd->flags = NO_FLAGS;
71 nbfd->mtime_set = false;
76 /* Allocate a new BFD as a member of archive OBFD. */
79 _bfd_new_bfd_contained_in (obfd)
84 nbfd = _bfd_new_bfd();
85 nbfd->xvec = obfd->xvec;
86 nbfd->my_archive = obfd;
87 nbfd->direction = read_direction;
88 nbfd->target_defaulted = obfd->target_defaulted;
94 Opening and closing BFDs
103 bfd *bfd_openr(CONST char *filename, CONST char *target);
106 Open the file @var{filename} (using <<fopen>>) with the target
107 @var{target}. Return a pointer to the created BFD.
109 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
112 If <<NULL>> is returned then an error has occured. Possible errors
113 are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
117 bfd_openr (filename, target)
118 CONST char *filename;
122 bfd_target *target_vec;
124 nbfd = _bfd_new_bfd();
126 bfd_error = no_memory;
130 target_vec = bfd_find_target (target, nbfd);
131 if (target_vec == NULL) {
132 bfd_error = invalid_target;
136 nbfd->filename = filename;
137 nbfd->direction = read_direction;
139 if (bfd_open_file (nbfd) == NULL) {
140 bfd_error = system_call_error; /* File didn't exist, or some such */
148 /* Don't try to `optimize' this function:
150 o - We lock using stack space so that interrupting the locking
151 won't cause a storage leak.
152 o - We open the file stream last, since we don't want to have to
153 close it if anything goes wrong. Closing the stream means closing
154 the file descriptor too, even though we didn't open it.
161 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
164 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
165 It opens a BFD on a file already described by the @var{fd}
168 When the file is later <<bfd_close>>d, the file descriptor will be closed.
170 If the caller desires that this file descriptor be cached by BFD
171 (opened as needed, closed as needed to free descriptors for
172 other opens), with the supplied @var{fd} used as an initial
173 file descriptor (but subject to closure at any time), call
174 bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
175 assume no cacheing; the file descriptor will remain open until
176 <<bfd_close>>, and will not be affected by BFD operations on other
179 Possible errors are <<no_memory>>, <<invalid_target>> and <<system_call_error>>.
183 bfd_fdopenr (filename, target, fd)
184 CONST char *filename;
189 bfd_target *target_vec;
192 bfd_error = system_call_error;
195 fdflags = O_RDWR; /* Assume full access */
197 fdflags = fcntl (fd, F_GETFL, NULL);
199 if (fdflags == -1) return NULL;
201 nbfd = _bfd_new_bfd();
204 bfd_error = no_memory;
208 target_vec = bfd_find_target (target, nbfd);
209 if (target_vec == NULL) {
210 bfd_error = invalid_target;
213 #if defined(VMS) || defined(__GO32__)
214 nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
216 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
217 switch (fdflags & (O_ACCMODE)) {
218 case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break;
219 case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
220 case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
224 if (nbfd->iostream == NULL) {
225 (void) obstack_free (&nbfd->memory, (PTR)0);
229 /* OK, put everything where it belongs */
231 nbfd->filename = filename;
233 /* As a special case we allow a FD open for read/write to
234 be written through, although doing so requires that we end
235 the previous clause with a preposition. */
236 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
237 switch (fdflags & (O_ACCMODE)) {
238 case O_RDONLY: nbfd->direction = read_direction; break;
239 case O_WRONLY: nbfd->direction = write_direction; break;
240 case O_RDWR: nbfd->direction = both_direction; break;
244 bfd_cache_init (nbfd);
249 /** bfd_openw -- open for writing.
250 Returns a pointer to a freshly-allocated BFD on success, or NULL.
252 See comment by bfd_fdopenr before you try to modify this function. */
259 bfd *bfd_openw(CONST char *filename, CONST char *target);
262 Create a BFD, associated with file @var{filename}, using the
263 file format @var{target}, and return a pointer to it.
265 Possible errors are <<system_call_error>>, <<no_memory>>,
270 bfd_openw (filename, target)
271 CONST char *filename;
275 bfd_target *target_vec;
277 bfd_error = system_call_error;
279 /* nbfd has to point to head of malloc'ed block so that bfd_close may
280 reclaim it correctly. */
282 nbfd = _bfd_new_bfd();
284 bfd_error = no_memory;
288 target_vec = bfd_find_target (target, nbfd);
289 if (target_vec == NULL) return NULL;
291 nbfd->filename = filename;
292 nbfd->direction = write_direction;
294 if (bfd_open_file (nbfd) == NULL) {
295 bfd_error = system_call_error; /* File not writeable, etc */
296 (void) obstack_free (&nbfd->memory, (PTR)0);
308 boolean bfd_close(bfd *abfd);
312 Close a BFD. If the BFD was open for writing,
313 then pending operations are completed and the file written out
314 and closed. If the created file is executable, then
315 <<chmod>> is called to mark it as such.
317 All memory attached to the BFD's obstacks is released.
319 The file descriptor associated with the BFD is closed (even
320 if it was passed in to BFD by <<bfd_fdopenr>>).
323 <<true>> is returned if all is ok, otherwise <<false>>.
333 if (!bfd_read_p(abfd))
334 if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
337 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
339 ret = bfd_cache_close(abfd);
341 /* If the file was open for writing and is now executable,
344 && abfd->direction == write_direction
345 && abfd->flags & EXEC_P) {
347 stat(abfd->filename, &buf);
349 #define S_IXUSR 0100 /* Execute by owner. */
352 #define S_IXGRP 0010 /* Execute by group. */
355 #define S_IXOTH 0001 /* Execute by others. */
358 chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
360 (void) obstack_free (&abfd->memory, (PTR)0);
370 boolean bfd_close_all_done(bfd *);
373 Close a BFD. Differs from <<bfd_close>>
374 since it does not complete any pending operations. This
375 routine would be used if the application had just used BFD for
376 swapping and didn't want to use any of the writing code.
378 If the created file is executable, then <<chmod>> is called
381 All memory attached to the BFD's obstacks is released.
384 <<true>> is returned if all is ok, otherwise <<false>>.
389 bfd_close_all_done (abfd)
394 ret = bfd_cache_close(abfd);
396 /* If the file was open for writing and is now executable,
399 && abfd->direction == write_direction
400 && abfd->flags & EXEC_P) {
402 stat(abfd->filename, &buf);
404 #define S_IXUSR 0100 /* Execute by owner. */
407 #define S_IXGRP 0010 /* Execute by group. */
410 #define S_IXOTH 0001 /* Execute by others. */
413 chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
415 (void) obstack_free (&abfd->memory, (PTR)0);
426 bfd_size_type bfd_alloc_size(bfd *abfd);
429 Return the number of bytes in the obstacks connected to @var{abfd}.
434 bfd_alloc_size (abfd)
437 struct _obstack_chunk *chunk = abfd->memory.chunk;
440 size += chunk->limit - &(chunk->contents[0]);
453 bfd *bfd_create(CONST char *filename, bfd *templ);
456 Create a new BFD in the manner of
457 <<bfd_openw>>, but without opening a file. The new BFD
458 takes the target from the target used by @var{template}. The
459 format is always set to <<bfd_object>>.
464 bfd_create (filename, templ)
465 CONST char *filename;
468 bfd *nbfd = _bfd_new_bfd();
469 if (nbfd == (bfd *)NULL) {
470 bfd_error = no_memory;
473 nbfd->filename = filename;
475 nbfd->xvec = templ->xvec;
477 nbfd->direction = no_direction;
478 bfd_set_format(nbfd, bfd_object);
487 PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
490 Allocate a block of @var{wanted} bytes of memory in the obstack
491 attatched to <<abfd>> and return a pointer to it.
496 bfd_alloc_by_size_t (abfd, size)
500 return obstack_alloc(&(abfd->memory), size);
504 bfd_alloc_grow (abfd, ptr, size)
509 (void) obstack_grow(&(abfd->memory), ptr, size);
513 bfd_alloc_finish (abfd)
516 return obstack_finish(&(abfd->memory));
520 bfd_alloc (abfd, size)
524 return bfd_alloc_by_size_t(abfd, (size_t)size);
528 bfd_zalloc (abfd, size)
533 res = bfd_alloc(abfd, size);
535 memset(res, 0, (size_t)size);
540 bfd_realloc (abfd, old, size)
545 PTR res = bfd_alloc(abfd, size);
547 memcpy(res, old, (size_t)size);