daily update
[binutils.git] / bfd / cache.c
blobb3091659984c4c91d31ded8a49443b97f1fe76f1
1 /* BFD library -- caching of file descriptors.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 SECTION
24 File caching
26 The file caching mechanism is embedded within BFD and allows
27 the application to open as many BFDs as it wants without
28 regard to the underlying operating system's file descriptor
29 limit (often as low as 20 open files). The module in
30 <<cache.c>> maintains a least recently used list of
31 <<BFD_CACHE_MAX_OPEN>> files, and exports the name
32 <<bfd_cache_lookup>>, which runs around and makes sure that
33 the required BFD is open. If not, then it chooses a file to
34 close, closes it and opens the one wanted, returning its file
35 handle.
39 #include "bfd.h"
40 #include "sysdep.h"
41 #include "libbfd.h"
43 static bfd_boolean bfd_cache_delete (bfd *);
46 INTERNAL_FUNCTION
47 BFD_CACHE_MAX_OPEN macro
49 DESCRIPTION
50 The maximum number of files which the cache will keep open at
51 one time.
53 .#define BFD_CACHE_MAX_OPEN 10
57 /* The number of BFD files we have open. */
59 static int open_files;
62 INTERNAL_FUNCTION
63 bfd_last_cache
65 SYNOPSIS
66 extern bfd *bfd_last_cache;
68 DESCRIPTION
69 Zero, or a pointer to the topmost BFD on the chain. This is
70 used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
71 determine when it can avoid a function call.
74 bfd *bfd_last_cache;
77 INTERNAL_FUNCTION
78 bfd_cache_lookup
80 DESCRIPTION
81 Check to see if the required BFD is the same as the last one
82 looked up. If so, then it can use the stream in the BFD with
83 impunity, since it can't have changed since the last lookup;
84 otherwise, it has to perform the complicated lookup function.
86 .#define bfd_cache_lookup(x) \
87 . ((x)==bfd_last_cache? \
88 . (FILE*) (bfd_last_cache->iostream): \
89 . bfd_cache_lookup_worker(x))
93 /* Insert a BFD into the cache. */
95 static void
96 insert (bfd *abfd)
98 if (bfd_last_cache == NULL)
100 abfd->lru_next = abfd;
101 abfd->lru_prev = abfd;
103 else
105 abfd->lru_next = bfd_last_cache;
106 abfd->lru_prev = bfd_last_cache->lru_prev;
107 abfd->lru_prev->lru_next = abfd;
108 abfd->lru_next->lru_prev = abfd;
110 bfd_last_cache = abfd;
113 /* Remove a BFD from the cache. */
115 static void
116 snip (bfd *abfd)
118 abfd->lru_prev->lru_next = abfd->lru_next;
119 abfd->lru_next->lru_prev = abfd->lru_prev;
120 if (abfd == bfd_last_cache)
122 bfd_last_cache = abfd->lru_next;
123 if (abfd == bfd_last_cache)
124 bfd_last_cache = NULL;
128 /* We need to open a new file, and the cache is full. Find the least
129 recently used cacheable BFD and close it. */
131 static bfd_boolean
132 close_one (void)
134 register bfd *kill;
136 if (bfd_last_cache == NULL)
137 kill = NULL;
138 else
140 for (kill = bfd_last_cache->lru_prev;
141 ! kill->cacheable;
142 kill = kill->lru_prev)
144 if (kill == bfd_last_cache)
146 kill = NULL;
147 break;
152 if (kill == NULL)
154 /* There are no open cacheable BFD's. */
155 return TRUE;
158 kill->where = ftell ((FILE *) kill->iostream);
160 return bfd_cache_delete (kill);
163 /* Close a BFD and remove it from the cache. */
165 static bfd_boolean
166 bfd_cache_delete (bfd *abfd)
168 bfd_boolean ret;
170 if (fclose ((FILE *) abfd->iostream) == 0)
171 ret = TRUE;
172 else
174 ret = FALSE;
175 bfd_set_error (bfd_error_system_call);
178 snip (abfd);
180 abfd->iostream = NULL;
181 --open_files;
183 return ret;
187 INTERNAL_FUNCTION
188 bfd_cache_init
190 SYNOPSIS
191 bfd_boolean bfd_cache_init (bfd *abfd);
193 DESCRIPTION
194 Add a newly opened BFD to the cache.
197 bfd_boolean
198 bfd_cache_init (bfd *abfd)
200 BFD_ASSERT (abfd->iostream != NULL);
201 if (open_files >= BFD_CACHE_MAX_OPEN)
203 if (! close_one ())
204 return FALSE;
206 insert (abfd);
207 ++open_files;
208 return TRUE;
212 INTERNAL_FUNCTION
213 bfd_cache_close
215 SYNOPSIS
216 bfd_boolean bfd_cache_close (bfd *abfd);
218 DESCRIPTION
219 Remove the BFD @var{abfd} from the cache. If the attached file is open,
220 then close it too.
222 RETURNS
223 <<FALSE>> is returned if closing the file fails, <<TRUE>> is
224 returned if all is well.
227 bfd_boolean
228 bfd_cache_close (bfd *abfd)
230 if (abfd->iostream == NULL
231 || (abfd->flags & BFD_IN_MEMORY) != 0)
232 return TRUE;
234 return bfd_cache_delete (abfd);
238 INTERNAL_FUNCTION
239 bfd_open_file
241 SYNOPSIS
242 FILE* bfd_open_file (bfd *abfd);
244 DESCRIPTION
245 Call the OS to open a file for @var{abfd}. Return the <<FILE *>>
246 (possibly <<NULL>>) that results from this operation. Set up the
247 BFD so that future accesses know the file is open. If the <<FILE *>>
248 returned is <<NULL>>, then it won't have been put in the
249 cache, so it won't have to be removed from it.
252 FILE *
253 bfd_open_file (bfd *abfd)
255 abfd->cacheable = TRUE; /* Allow it to be closed later. */
257 if (open_files >= BFD_CACHE_MAX_OPEN)
259 if (! close_one ())
260 return NULL;
263 switch (abfd->direction)
265 case read_direction:
266 case no_direction:
267 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB);
268 break;
269 case both_direction:
270 case write_direction:
271 if (abfd->opened_once)
273 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB);
274 if (abfd->iostream == NULL)
275 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
277 else
279 /* Create the file.
281 Some operating systems won't let us overwrite a running
282 binary. For them, we want to unlink the file first.
284 However, gcc 2.95 will create temporary files using
285 O_EXCL and tight permissions to prevent other users from
286 substituting other .o files during the compilation. gcc
287 will then tell the assembler to use the newly created
288 file as an output file. If we unlink the file here, we
289 open a brief window when another user could still
290 substitute a file.
292 So we unlink the output file if and only if it has
293 non-zero size. */
294 #ifndef __MSDOS__
295 /* Don't do this for MSDOS: it doesn't care about overwriting
296 a running binary, but if this file is already open by
297 another BFD, we will be in deep trouble if we delete an
298 open file. In fact, objdump does just that if invoked with
299 the --info option. */
300 struct stat s;
302 if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
303 unlink (abfd->filename);
304 #endif
305 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
306 abfd->opened_once = TRUE;
308 break;
311 if (abfd->iostream != NULL)
313 if (! bfd_cache_init (abfd))
314 return NULL;
317 return (FILE *) abfd->iostream;
321 INTERNAL_FUNCTION
322 bfd_cache_lookup_worker
324 SYNOPSIS
325 FILE *bfd_cache_lookup_worker (bfd *abfd);
327 DESCRIPTION
328 Called when the macro <<bfd_cache_lookup>> fails to find a
329 quick answer. Find a file descriptor for @var{abfd}. If
330 necessary, it open it. If there are already more than
331 <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
332 avoid running out of file descriptors.
335 FILE *
336 bfd_cache_lookup_worker (bfd *abfd)
338 if ((abfd->flags & BFD_IN_MEMORY) != 0)
339 abort ();
341 if (abfd->my_archive)
342 abfd = abfd->my_archive;
344 if (abfd->iostream != NULL)
346 /* Move the file to the start of the cache. */
347 if (abfd != bfd_last_cache)
349 snip (abfd);
350 insert (abfd);
353 else
355 if (bfd_open_file (abfd) == NULL)
356 return NULL;
357 if (abfd->where != (unsigned long) abfd->where)
358 return NULL;
359 if (fseek ((FILE *) abfd->iostream, (long) abfd->where, SEEK_SET) != 0)
360 return NULL;
363 return (FILE *) abfd->iostream;