diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index f733fcea..a7846d5e 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,9 @@
+2009-02-19  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	(Partially) submitted by John Voltz:
+	bug #20004: AVRDUDE update (-U) operations do not close files
+	* fileio.c (fmt_autodetect, fileio): fclose() files.
+
 2009-02-18  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* usbtiny.c: Replace all but one (very unlikely to trigger) exit(1)
diff --git a/avrdude/fileio.c b/avrdude/fileio.c
index 4bad9734..60975c02 100644
--- a/avrdude/fileio.c
+++ b/avrdude/fileio.c
@@ -969,8 +969,10 @@ static int fmt_autodetect(char * fname)
         break;
       }
     }
-    if (found)
+    if (found) {
+      fclose(f);
       return FMT_RBIN;
+    }
 
     /* check for lines that look like intel hex */
     if ((buf[0] == ':') && (len >= 11)) {
@@ -981,8 +983,10 @@ static int fmt_autodetect(char * fname)
           break;
         }
       }
-      if (found)
+      if (found) {
+        fclose(f);
         return FMT_IHEX;
+      }
     }
 
     /* check for lines that look like motorola s-record */
@@ -994,11 +998,14 @@ static int fmt_autodetect(char * fname)
           break;
         }
       }
-      if (found)
+      if (found) {
+        fclose(f);
         return FMT_SREC;
+      }
     }
   }
 
+  fclose(f);
   return -1;
 }
 
@@ -1143,7 +1150,9 @@ int fileio(int op, char * filename, FILEFMT format,
       rc = avr_mem_hiaddr(mem);
     }
   }
-
+  if (format != FMT_IMM) {
+    fclose(f);
+  }
   return rc;
 }