Don't fclose() the output in the backend
authorH. Peter Anvin <hpa@zytor.com>
Sun, 12 Jul 2009 19:11:52 +0000 (12:11 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Sun, 12 Jul 2009 19:15:35 +0000 (12:15 -0700)
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>
13 files changed:
nasm.c
output/outaout.c
output/outas86.c
output/outbin.c
output/outcoff.c
output/outdbg.c
output/outelf32.c
output/outelf64.c
output/outieee.c
output/outmacho32.c
output/outmacho64.c
output/outrdf.c
output/outrdf2.c

diff --git a/nasm.c b/nasm.c
index d1cd465..53e1c72 100644 (file)
--- a/nasm.c
+++ b/nasm.c
@@ -431,6 +431,7 @@ int main(int argc, char **argv)
                 fclose(ofile);
             if (ofile && terminate_after_phase)
                 remove(outname);
+           ofile = NULL;
         }
         break;
 
@@ -466,16 +467,17 @@ 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);
+               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();
index 4d38cdf..8d8966b 100644 (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;
index 2fa4efc..f21bd2e 100644 (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;
index 8942acf..5dc8e97 100644 (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. */
 
index 5a03bec..4c1213d 100644 (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);
index 1ee16ea..497a48e 100644 (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)
index 7159a1f..99e53ef 100644 (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);
index d049894..b797eb8 100644 (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);
index d587d4c..003e4d0 100644 (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;
index c9e4365..0203f0d 100644 (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;
index cad399d..659cbc4 100644 (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;
index fef18fb..6649c16 100644 (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)
index 578c923..84a565d 100644 (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)