1 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
3 This file is part of BFD, the Binary File Diddler.
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)
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.
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. */
21 /*** opncls.c -- open and close a bfd. */
29 extern void bfd_cache_init();
30 FILE *bfd_open_file();
32 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
33 if we do that we can't use fcntl. */
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.
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.
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.
53 Perhaps, since unix has so many different kinds of locking anyway,
54 we should use the emacs lock scheme?... */
57 #define obstack_chunk_alloc malloc
58 #define obstack_chunk_free free
66 nbfd = (bfd *)obstack_alloc(&tmp,sizeof(bfd));
69 nbfd->direction = no_direction;
70 nbfd->iostream = NULL;
72 nbfd->sections = (asection *)NULL;
73 nbfd->format = bfd_unknown;
74 nbfd->my_archive = (bfd *)NULL;
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;
85 bfd *new_bfd_contained_in(obfd)
88 bfd *nbfd = new_bfd();
89 nbfd->xvec = obfd->xvec;
90 nbfd->my_archive = obfd;
91 nbfd->direction = read_direction;
95 /** bfd_openr, bfd_fdopenr -- open for reading.
96 Returns a pointer to a freshly-allocated bfd on success, or NULL. */
99 DEFUN(bfd_openr, (filename, target),
100 CONST char *filename AND
104 bfd_target *target_vec;
106 target_vec = bfd_find_target (target);
107 if (target_vec == NULL) {
108 bfd_error = invalid_target;
112 bfd_error = system_call_error;
115 bfd_error = no_memory;
119 nbfd->filename = filename;
120 nbfd->xvec = target_vec;
121 nbfd->direction = read_direction;
123 if (bfd_open_file (nbfd) == NULL) {
124 bfd_error = system_call_error; /* File didn't exist, or some such */
132 /* Don't try to `optimize' this function:
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.
142 DEFUN(bfd_fdopenr,(filename, target, fd),
143 CONST char *filename AND
144 CONST char *target AND
148 bfd_target *target_vec;
151 struct flock lock, *lockp = &lock;
154 target_vec = bfd_find_target (target);
155 if (target_vec == NULL) {
156 bfd_error = invalid_target;
160 bfd_error = system_call_error;
162 fdflags = fcntl (fd, F_GETFL);
163 if (fdflags == -1) return NULL;
166 lockp->l_type = F_RDLCK;
167 if (fcntl (fd, F_SETLKW, lockp) == -1) return NULL;
173 bfd_error = no_memory;
177 nbfd->lock = (struct flock *) (nbfd + 1);
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) {
186 /* OK, put everything where it belongs */
188 nbfd->filename = filename;
189 nbfd->xvec = target_vec;
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;
202 memcpy (nbfd->lock, lockp, sizeof (struct flock))
205 bfd_cache_init (nbfd);
210 /** bfd_openw -- open for writing.
211 Returns a pointer to a freshly-allocated bfd on success, or NULL.
213 See comment by bfd_fdopenr before you try to modify this function. */
216 DEFUN(bfd_openw,(filename, target),
217 CONST char *filename AND
221 bfd_target *target_vec;
223 target_vec = bfd_find_target (target);
224 if (target_vec == NULL) return NULL;
226 bfd_error = system_call_error;
228 /* nbfd has to point to head of malloc'ed block so that bfd_close may
229 reclaim it correctly. */
233 bfd_error = no_memory;
237 nbfd->filename = filename;
238 nbfd->xvec = target_vec;
239 nbfd->direction = write_direction;
241 if (bfd_open_file (nbfd) == NULL) {
242 bfd_error = system_call_error; /* File not writeable, etc */
251 /** Close up shop, get your deposit back. */
256 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
258 bfd_cache_close(abfd);
259 /* If the file was open for writing and is now executable
261 if (abfd->direction == write_direction
262 && abfd->flags & EXEC_P) {
264 stat(abfd->filename, &buf);
265 chmod(abfd->filename,buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH);
267 obstack_free(&abfd->memory, (PTR)0);
271 called to create a bfd with no ascociated file or target
274 DEFUN(bfd_create,(filename, template),
275 CONST char *filename AND
278 bfd *nbfd = new_bfd();
279 if (nbfd == (bfd *)NULL) {
280 bfd_error = no_memory;
283 nbfd->filename = filename;
285 nbfd->xvec = template->xvec;
287 nbfd->direction = no_direction;
288 bfd_set_format(nbfd, bfd_object);
295 DEFUN(PTR bfd_alloc, (abfd, size),
299 PTR *res = obstack_alloc(&(abfd->memory),size);
303 DEFUN(PTR bfd_zalloc,(abfd, size),
307 PTR res = bfd_alloc(abfd, size);
308 memset(res, 0, size);
312 DEFUN(PTR bfd_realloc,(abfd, old, size),
317 PTR res = bfd_alloc(abfd, size);
318 memcpy(res, old, size);
323 DEFUN(size_t bfd_alloc_size,(abfd),
326 struct _obstack_chunk *chunk = abfd->memory.chunk;
329 size += chunk->limit - &(chunk->contents[0]);