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. */
28 extern void bfd_cache_init();
29 FILE *bfd_open_file();
31 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
32 if we do that we can't use fcntl. */
36 Locking is loosely controlled by the preprocessor variable
37 BFD_LOCKS. I say loosely because Unix barely understands locking
38 -- at least in BSD it doesn't affect programs which don't
39 explicitly use it! That is to say it's practically useless, though
40 if everyone uses this library you'll be OK.
42 From among the many and varied lock facilities available, (none of
43 which, of course, knows about any other) we use the fcntl locks,
44 because they're Posix.
46 The reason that bfd_openr and bfd_fdopenr exist, yet only bfd_openw
47 exists is because of locking. When we do output, we lock the
48 filename file for output, then open a temporary file which does not
49 actually get its correct filename until closing time. This is
50 safest, but requires the asymmetry in read and write entry points.
52 Perhaps, since unix has so many different kinds of locking anyway,
53 we should use the emacs lock scheme?... */
58 bfd
*nbfd
= (bfd
*)zalloc(sizeof(bfd
));
60 nbfd
->direction
= no_direction
;
61 nbfd
->iostream
= NULL
;
63 nbfd
->sections
= (asection
*)NULL
;
64 nbfd
->format
= bfd_unknown
;
65 nbfd
->my_archive
= (bfd
*)NULL
;
67 nbfd
->opened_once
= false;
68 nbfd
->output_has_begun
= false;
69 nbfd
->section_count
= 0;
70 nbfd
->usrdata
= (void *)NULL
;
71 nbfd
->sections
= (asection
*)NULL
;
72 nbfd
->cacheable
= false;
73 nbfd
->flags
= NO_FLAGS
;
76 bfd
*new_bfd_contained_in(obfd
)
79 bfd
*nbfd
= new_bfd(obfd
);
80 nbfd
->xvec
= obfd
->xvec
;
81 nbfd
->my_archive
= obfd
;
82 nbfd
->direction
= read_direction
;
86 /** bfd_openr, bfd_fdopenr -- open for reading.
87 Returns a pointer to a freshly-allocated bfd on success, or NULL. */
90 bfd_openr (filename
, target
)
95 bfd_target
*target_vec
;
97 target_vec
= bfd_find_target (target
);
98 if (target_vec
== NULL
) {
99 bfd_error
= invalid_target
;
103 bfd_error
= system_call_error
;
106 bfd_error
= no_memory
;
110 nbfd
->filename
= filename
;
111 nbfd
->xvec
= target_vec
;
112 nbfd
->direction
= read_direction
;
114 if (bfd_open_file (nbfd
) == NULL
) {
115 bfd_error
= system_call_error
; /* File didn't exist, or some such */
123 /* Don't try to `optimize' this function:
125 o - We lock using stack space so that interrupting the locking
126 won't cause a storage leak.
127 o - We open the file stream last, since we don't want to have to
128 close it if anything goes wrong. Closing the stream means closing
129 the file descriptor too, even though we didn't open it.
133 bfd_fdopenr (filename
, target
, fd
)
139 bfd_target
*target_vec
;
142 struct flock lock
, *lockp
= &lock
;
145 target_vec
= bfd_find_target (target
);
146 if (target_vec
== NULL
) {
147 bfd_error
= invalid_target
;
151 bfd_error
= system_call_error
;
153 fdflags
= fcntl (fd
, F_GETFL
);
154 if (fdflags
== -1) return NULL
;
157 lockp
->l_type
= F_RDLCK
;
158 if (fcntl (fd
, F_SETLKW
, lockp
) == -1) return NULL
;
164 bfd_error
= no_memory
;
168 nbfd
->lock
= (struct flock
*) (nbfd
+ 1);
170 /* if the fd were open for read only, this still would not hurt: */
171 nbfd
->iostream
= (char *) fdopen (fd
, "r+");
172 if (nbfd
->iostream
== NULL
) {
177 /* OK, put everything where it belongs */
179 nbfd
->filename
= filename
;
180 nbfd
->xvec
= target_vec
;
182 /* As a special case we allow a FD open for read/write to
183 be written through, although doing so requires that we end
184 the previous clause with a preposition. */
185 switch (fdflags
& O_ACCMODE
) {
186 case O_RDONLY
: nbfd
->direction
= read_direction
; break;
187 case O_WRONLY
: nbfd
->direction
= write_direction
; break;
188 case O_RDWR
: nbfd
->direction
= both_direction
; break;
193 memcpy (nbfd
->lock
, lockp
, sizeof (struct flock
))
196 bfd_cache_init (nbfd
);
201 /** bfd_openw -- open for writing.
202 Returns a pointer to a freshly-allocated bfd on success, or NULL.
204 See comment by bfd_fdopenr before you try to modify this function. */
207 bfd_openw (filename
, target
)
212 bfd_target
*target_vec
;
214 target_vec
= bfd_find_target (target
);
215 if (target_vec
== NULL
) return NULL
;
217 bfd_error
= system_call_error
;
219 /* nbfd has to point to head of malloc'ed block so that bfd_close may
220 reclaim it correctly. */
224 bfd_error
= no_memory
;
228 nbfd
->filename
= filename
;
229 nbfd
->xvec
= target_vec
;
230 nbfd
->direction
= write_direction
;
232 if (bfd_open_file (nbfd
) == NULL
) {
233 bfd_error
= system_call_error
; /* File not writeable, etc */
242 /** Close up shop, get your deposit back. */
247 if (BFD_SEND (abfd
, _close_and_cleanup
, (abfd
)) != true) return false;
249 bfd_cache_close(abfd
);
250 /* If the file was open for writing and is now executable
252 if (abfd
->direction
== write_direction
253 && abfd
->flags
& EXEC_P
) {
255 stat(abfd
->filename
, &buf
);
256 chmod(abfd
->filename
,buf
.st_mode
| S_IXUSR
| S_IXGRP
| S_IXOTH
);
262 called to create a bfd with no ascociated file or target
265 bfd_create(filename
, template)
269 bfd
*nbfd
= new_bfd();
270 if (nbfd
== (bfd
*)NULL
) {
271 bfd_error
= no_memory
;
274 nbfd
->filename
= filename
;
275 nbfd
->xvec
= template->xvec
;
276 nbfd
->direction
= no_direction
;
This page took 0.055861 seconds and 5 git commands to generate.