bfd * bfd_openstreamr (const char *filename, const char *target, void *streamarg) { FILE *stream = streamarg; bfd *nbfd; const bfd_target *target_vec; nbfd = _bfd_new_bfd (); if (nbfd == NULL) return NULL; target_vec = bfd_find_target (target, nbfd); if (target_vec == NULL) { _bfd_delete_bfd (nbfd); return NULL; } nbfd->iostream = stream; nbfd->filename = filename; nbfd->direction = read_direction; if (! bfd_cache_init (nbfd)) { _bfd_delete_bfd (nbfd); return NULL; } return nbfd; }
bfd * bfd_openstreamr (const char *filename, const char *target, void *streamarg) { FILE *stream = (FILE *) streamarg; bfd *nbfd; const bfd_target *target_vec; nbfd = _bfd_new_bfd (); if (nbfd == NULL) return NULL; target_vec = bfd_find_target (target, nbfd); if (target_vec == NULL) { _bfd_delete_bfd (nbfd); return NULL; } nbfd->iostream = stream; /* PR 11983: Do not cache the original filename, but rather make a copy - the original might go away. */ nbfd->filename = xstrdup (filename); nbfd->direction = read_direction; if (! bfd_cache_init (nbfd)) { _bfd_delete_bfd (nbfd); return NULL; } return nbfd; }
bfd * bfd_fopen (const char *filename, const char *target, const char *mode, int fd) { bfd *nbfd; const bfd_target *target_vec; nbfd = _bfd_new_bfd (); if (nbfd == NULL) return NULL; target_vec = bfd_find_target (target, nbfd); if (target_vec == NULL) { _bfd_delete_bfd (nbfd); return NULL; } #ifdef HAVE_FDOPEN if (fd != -1) nbfd->iostream = fdopen (fd, mode); else #endif nbfd->iostream = real_fopen (filename, mode); if (nbfd->iostream == NULL) { bfd_set_error (bfd_error_system_call); _bfd_delete_bfd (nbfd); return NULL; } /* OK, put everything where it belongs. */ nbfd->filename = filename; /* Figure out whether the user is opening the file for reading, writing, or both, by looking at the MODE argument. */ if ((mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a') && mode[1] == '+') nbfd->direction = both_direction; else if (mode[0] == 'r') nbfd->direction = read_direction; else nbfd->direction = write_direction; if (! bfd_cache_init (nbfd)) { _bfd_delete_bfd (nbfd); return NULL; } nbfd->opened_once = TRUE; /* If we opened the file by name, mark it cacheable; we can close it and reopen it later. However, if a file descriptor was provided, then it may have been opened with special flags that make it unsafe to close and reopen the file. */ if (fd == -1) bfd_set_cacheable (nbfd, TRUE); return nbfd; }
FILE * bfd_open_file (bfd *abfd) { abfd->cacheable = TRUE; /* Allow it to be closed later. */ if (open_files >= BFD_CACHE_MAX_OPEN) { if (! close_one ()) return NULL; } switch (abfd->direction) { case read_direction: case no_direction: abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RB); break; case both_direction: case write_direction: if (abfd->opened_once) { abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RUB); if (abfd->iostream == NULL) abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); } else { /* Create the file. Some operating systems won't let us overwrite a running binary. For them, we want to unlink the file first. However, gcc 2.95 will create temporary files using O_EXCL and tight permissions to prevent other users from substituting other .o files during the compilation. gcc will then tell the assembler to use the newly created file as an output file. If we unlink the file here, we open a brief window when another user could still substitute a file. So we unlink the output file if and only if it has non-zero size. */ #ifndef __MSDOS__ /* Don't do this for MSDOS: it doesn't care about overwriting a running binary, but if this file is already open by another BFD, we will be in deep trouble if we delete an open file. In fact, objdump does just that if invoked with the --info option. */ struct stat s; if (stat (abfd->filename, &s) == 0 && s.st_size != 0) unlink_if_ordinary (abfd->filename); #endif abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); abfd->opened_once = TRUE; } break; } if (abfd->iostream == NULL) bfd_set_error (bfd_error_system_call); else { if (! bfd_cache_init (abfd)) return NULL; } return (FILE *) abfd->iostream; }