Don't fclose() the output in the backend

We fopen() the output file in common code but fclose() it in the
backend.  This is bad for a variety of reasons:

1. it is generally an awkward interface to change ownership.
2. we should use ferror() to test for write errors, and that is
   better done in common code.
3. it requires more code.
4. we still need to fclose() in common code during error handing.

Thus, move the fclose() of the output out of the backends, and add
fflush() so we can test ferror() on output.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2009-07-12 12:11:52 -07:00
parent 323fcff32b
commit d0fbb7f0ab
13 changed files with 11 additions and 25 deletions

21
nasm.c
View File

@ -431,6 +431,7 @@ int main(int argc, char **argv)
fclose(ofile);
if (ofile && terminate_after_phase)
remove(outname);
ofile = NULL;
}
break;
@ -466,17 +467,18 @@ int main(int argc, char **argv)
if (!terminate_after_phase) {
ofmt->cleanup(using_debug_info);
cleanup_labels();
} else {
/*
* Despite earlier comments, we need this fclose.
* The object output drivers only fclose on cleanup,
* and we just skipped that.
*/
fclose (ofile);
remove(outname);
fflush(ofile);
if (ferror(ofile)) {
report_error(ERR_NONFATAL|ERR_NOFILE,
"write error on output file `%s'", outname);
}
}
fclose(ofile);
if (ofile && terminate_after_phase)
remove(outname);
ofile = NULL;
}
break;
}
@ -1961,6 +1963,7 @@ static void report_error_common(int severity, const char *fmt,
if (ofile) {
fclose(ofile);
remove(outname);
ofile = NULL;
}
if (want_usage)
usage();

View File

@ -235,7 +235,6 @@ static void aout_cleanup(int debuginfo)
aout_fixup_relocs(&stext);
aout_fixup_relocs(&sdata);
aout_write();
fclose(aoutfp);
saa_free(stext.data);
while (stext.head) {
r = stext.head;

View File

@ -152,7 +152,6 @@ static void as86_cleanup(int debuginfo)
(void)debuginfo;
as86_write();
fclose(as86fp);
saa_free(stext.data);
while (stext.head) {
p = stext.head;

View File

@ -593,7 +593,6 @@ static void bin_cleanup(int debuginfo)
/* Step 6: Write the section data to the output file. */
do_output();
fclose(fp); /* Done with the output file */
/* Step 7: Generate the map file. */

View File

@ -236,7 +236,6 @@ static void coff_cleanup(int debuginfo)
(void)debuginfo;
coff_write();
fclose(coffp);
for (i = 0; i < nsects; i++) {
if (sects[i]->data)
saa_free(sects[i]->data);

View File

@ -81,7 +81,6 @@ static void dbg_cleanup(int debuginfo)
nasm_free(tmp->name);
nasm_free(tmp);
}
fclose(dbgf);
}
static int32_t dbg_section_names(char *name, int pass, int *bits)

View File

@ -296,7 +296,6 @@ static void elf_cleanup(int debuginfo)
(void)debuginfo;
elf_write();
fclose(elffp);
for (i = 0; i < nsects; i++) {
if (sects[i]->type != SHT_NOBITS)
saa_free(sects[i]->data);

View File

@ -300,7 +300,6 @@ static void elf_cleanup(int debuginfo)
(void)debuginfo;
elf_write();
fclose(elffp);
for (i = 0; i < nsects; i++) {
if (sects[i]->type != SHT_NOBITS)
saa_free(sects[i]->data);

View File

@ -243,7 +243,6 @@ static void ieee_cleanup(int debuginfo)
{
ieee_write_file(debuginfo);
of_ieee.current_dfmt->cleanup();
fclose(ofp);
while (seghead) {
struct ieeeSection *segtmp = seghead;
seghead = seghead->next;

View File

@ -1280,9 +1280,6 @@ static void macho_cleanup(int debuginfo)
macho_calculate_sizes();
macho_write();
/* done - yay! */
fclose(machofp);
/* free up everything */
while (sects->next) {
s = sects;

View File

@ -1449,9 +1449,6 @@ static void macho_cleanup(int debuginfo)
macho_calculate_sizes();
macho_write();
/* done - yay! */
fclose(machofp);
/* free up everything */
while (sects->next) {
s = sects;

View File

@ -509,7 +509,6 @@ static void rdf_cleanup(int debuginfo)
freemembuf(header);
freemembuf(seg[0]);
freemembuf(seg[1]);
fclose(ofile);
}
static int32_t rdf_segbase(int32_t segment)

View File

@ -723,8 +723,6 @@ static void rdf2_cleanup(int debuginfo)
fwriteint32_t(0, ofile);
fwriteint32_t(0, ofile);
fwriteint16_t(0, ofile);
fclose(ofile);
}
static int32_t rdf2_segbase(int32_t segment)