1 /* opncls.c -- open and close a BFD.
2 Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
3 Free Software Foundation, Inc.
5 Written by Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 #define S_IXUSR 0100 /* Execute by owner. */
32 #define S_IXGRP 0010 /* Execute by group. */
35 #define S_IXOTH 0001 /* Execute by others. */
38 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
39 if we do that we can't use fcntl. */
41 /* FIXME: This is no longer used. */
42 long _bfd_chunksize = -1;
44 /* Return a new BFD. All BFD's are allocated through this routine. */
51 nbfd = (bfd *) bfd_zmalloc (sizeof (bfd));
55 nbfd->memory = (PTR) objalloc_create ();
56 if (nbfd->memory == NULL)
58 bfd_set_error (bfd_error_no_memory);
62 nbfd->arch_info = &bfd_default_arch_struct;
64 nbfd->direction = no_direction;
65 nbfd->iostream = NULL;
67 nbfd->sections = (asection *) NULL;
68 nbfd->format = bfd_unknown;
69 nbfd->my_archive = (bfd *) NULL;
71 nbfd->opened_once = false;
72 nbfd->output_has_begun = false;
73 nbfd->section_count = 0;
74 nbfd->usrdata = (PTR) NULL;
75 nbfd->cacheable = false;
76 nbfd->flags = BFD_NO_FLAGS;
77 nbfd->mtime_set = false;
82 /* Allocate a new BFD as a member of archive OBFD. */
85 _bfd_new_bfd_contained_in (obfd)
90 nbfd = _bfd_new_bfd ();
91 nbfd->xvec = obfd->xvec;
92 nbfd->my_archive = obfd;
93 nbfd->direction = read_direction;
94 nbfd->target_defaulted = obfd->target_defaulted;
100 Opening and closing BFDs
109 bfd *bfd_openr(CONST char *filename, CONST char *target);
112 Open the file @var{filename} (using <<fopen>>) with the target
113 @var{target}. Return a pointer to the created BFD.
115 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
118 If <<NULL>> is returned then an error has occured. Possible errors
119 are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
123 bfd_openr (filename, target)
124 CONST char *filename;
128 const bfd_target *target_vec;
130 nbfd = _bfd_new_bfd ();
134 target_vec = bfd_find_target (target, nbfd);
135 if (target_vec == NULL)
137 objalloc_free ((struct objalloc *) nbfd->memory);
139 bfd_set_error (bfd_error_invalid_target);
143 nbfd->filename = filename;
144 nbfd->direction = read_direction;
146 if (bfd_open_file (nbfd) == NULL)
148 /* File didn't exist, or some such */
149 bfd_set_error (bfd_error_system_call);
150 objalloc_free ((struct objalloc *) nbfd->memory);
158 /* Don't try to `optimize' this function:
160 o - We lock using stack space so that interrupting the locking
161 won't cause a storage leak.
162 o - We open the file stream last, since we don't want to have to
163 close it if anything goes wrong. Closing the stream means closing
164 the file descriptor too, even though we didn't open it.
171 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
174 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
175 It opens a BFD on a file already described by the @var{fd}
178 When the file is later <<bfd_close>>d, the file descriptor will be closed.
180 If the caller desires that this file descriptor be cached by BFD
181 (opened as needed, closed as needed to free descriptors for
182 other opens), with the supplied @var{fd} used as an initial
183 file descriptor (but subject to closure at any time), call
184 bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
185 assume no cacheing; the file descriptor will remain open until
186 <<bfd_close>>, and will not be affected by BFD operations on other
189 Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
193 bfd_fdopenr (filename, target, fd)
194 CONST char *filename;
199 const bfd_target *target_vec;
202 bfd_set_error (bfd_error_system_call);
203 #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
204 fdflags = O_RDWR; /* Assume full access */
206 fdflags = fcntl (fd, F_GETFL, NULL);
208 if (fdflags == -1) return NULL;
210 nbfd = _bfd_new_bfd ();
214 target_vec = bfd_find_target (target, nbfd);
215 if (target_vec == NULL)
217 bfd_set_error (bfd_error_invalid_target);
218 objalloc_free ((struct objalloc *) nbfd->memory);
223 #if defined(VMS) || defined(__GO32__)
224 nbfd->iostream = (PTR)fopen(filename, FOPEN_RB);
226 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
227 switch (fdflags & (O_ACCMODE)) {
228 case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
229 case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
230 case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
235 if (nbfd->iostream == NULL)
237 objalloc_free ((struct objalloc *) nbfd->memory);
242 /* OK, put everything where it belongs */
244 nbfd->filename = filename;
246 /* As a special case we allow a FD open for read/write to
247 be written through, although doing so requires that we end
248 the previous clause with a preposition. */
249 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
250 switch (fdflags & O_ACCMODE)
252 case O_RDONLY: nbfd->direction = read_direction; break;
253 case O_WRONLY: nbfd->direction = write_direction; break;
254 case O_RDWR: nbfd->direction = both_direction; break;
258 if (! bfd_cache_init (nbfd))
260 objalloc_free ((struct objalloc *) nbfd->memory);
264 nbfd->opened_once = true;
274 bfd *bfd_openstreamr();
278 Open a BFD for read access on an existing stdio stream. When
279 the BFD is passed to <<bfd_close>>, the stream will be closed.
283 bfd_openstreamr (filename, target, stream)
284 const char *filename;
289 const bfd_target *target_vec;
291 nbfd = _bfd_new_bfd ();
295 target_vec = bfd_find_target (target, nbfd);
296 if (target_vec == NULL)
298 bfd_set_error (bfd_error_invalid_target);
299 objalloc_free ((struct objalloc *) nbfd->memory);
304 nbfd->iostream = (PTR) stream;
305 nbfd->filename = filename;
306 nbfd->direction = read_direction;
308 if (! bfd_cache_init (nbfd))
310 objalloc_free ((struct objalloc *) nbfd->memory);
318 /** bfd_openw -- open for writing.
319 Returns a pointer to a freshly-allocated BFD on success, or NULL.
321 See comment by bfd_fdopenr before you try to modify this function. */
328 bfd *bfd_openw(CONST char *filename, CONST char *target);
331 Create a BFD, associated with file @var{filename}, using the
332 file format @var{target}, and return a pointer to it.
334 Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
335 <<bfd_error_invalid_target>>.
339 bfd_openw (filename, target)
340 CONST char *filename;
344 const bfd_target *target_vec;
346 bfd_set_error (bfd_error_system_call);
348 /* nbfd has to point to head of malloc'ed block so that bfd_close may
349 reclaim it correctly. */
351 nbfd = _bfd_new_bfd ();
355 target_vec = bfd_find_target (target, nbfd);
356 if (target_vec == NULL)
358 objalloc_free ((struct objalloc *) nbfd->memory);
363 nbfd->filename = filename;
364 nbfd->direction = write_direction;
366 if (bfd_open_file (nbfd) == NULL)
368 bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
369 objalloc_free ((struct objalloc *) nbfd->memory);
383 boolean bfd_close(bfd *abfd);
387 Close a BFD. If the BFD was open for writing,
388 then pending operations are completed and the file written out
389 and closed. If the created file is executable, then
390 <<chmod>> is called to mark it as such.
392 All memory attached to the BFD is released.
394 The file descriptor associated with the BFD is closed (even
395 if it was passed in to BFD by <<bfd_fdopenr>>).
398 <<true>> is returned if all is ok, otherwise <<false>>.
408 if (!bfd_read_p (abfd))
410 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
414 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
417 ret = bfd_cache_close (abfd);
419 /* If the file was open for writing and is now executable,
422 && abfd->direction == write_direction
423 && abfd->flags & EXEC_P)
427 if (stat (abfd->filename, &buf) == 0)
429 int mask = umask (0);
431 chmod (abfd->filename,
433 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
437 objalloc_free ((struct objalloc *) abfd->memory);
448 boolean bfd_close_all_done(bfd *);
451 Close a BFD. Differs from <<bfd_close>>
452 since it does not complete any pending operations. This
453 routine would be used if the application had just used BFD for
454 swapping and didn't want to use any of the writing code.
456 If the created file is executable, then <<chmod>> is called
459 All memory attached to the BFD is released.
462 <<true>> is returned if all is ok, otherwise <<false>>.
467 bfd_close_all_done (abfd)
472 ret = bfd_cache_close (abfd);
474 /* If the file was open for writing and is now executable,
477 && abfd->direction == write_direction
478 && abfd->flags & EXEC_P)
482 if (stat (abfd->filename, &buf) == 0)
484 int mask = umask (0);
486 chmod (abfd->filename,
488 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
492 objalloc_free ((struct objalloc *) abfd->memory);
503 bfd *bfd_create(CONST char *filename, bfd *templ);
506 Create a new BFD in the manner of
507 <<bfd_openw>>, but without opening a file. The new BFD
508 takes the target from the target used by @var{template}. The
509 format is always set to <<bfd_object>>.
514 bfd_create (filename, templ)
515 CONST char *filename;
520 nbfd = _bfd_new_bfd ();
523 nbfd->filename = filename;
525 nbfd->xvec = templ->xvec;
526 nbfd->direction = no_direction;
527 bfd_set_format (nbfd, bfd_object);
536 PTR bfd_alloc (bfd *abfd, size_t wanted);
539 Allocate a block of @var{wanted} bytes of memory attached to
540 <<abfd>> and return a pointer to it.
545 bfd_alloc (abfd, size)
551 ret = objalloc_alloc (abfd->memory, (unsigned long) size);
553 bfd_set_error (bfd_error_no_memory);
558 bfd_zalloc (abfd, size)
564 res = bfd_alloc (abfd, size);
566 memset (res, 0, size);
570 /* Free a block allocated for a BFD. */
573 bfd_release (abfd, block)
577 objalloc_free_block ((struct objalloc *) abfd->memory, block);