record_unwind_protect error handling
[bpt/emacs.git] / src / fileio.c
index 3b4776c..cc3b4eb 100644 (file)
@@ -273,6 +273,14 @@ close_file_unwind (int fd)
   emacs_close (fd);
 }
 
+void
+close_file_ptr_unwind (void *fdp)
+{
+  int fd = *((int *) fdp);
+  if (fd >= 0)
+    emacs_close (fd);
+}
+
 void
 fclose_unwind (void *arg)
 {
@@ -280,6 +288,14 @@ fclose_unwind (void *arg)
   fclose (stream);
 }
 
+void
+fclose_ptr_unwind (void *arg)
+{
+  FILE *stream = *((void **) arg);
+  if (stream)
+    fclose (stream);
+}
+
 /* Restore point, having saved it as a marker.  */
 
 void
@@ -2015,7 +2031,7 @@ permissions.  */)
   if (ifd < 0)
     report_file_error ("Opening input file", file);
 
-  record_unwind_protect_int (close_file_unwind, ifd);
+  record_unwind_protect_int_1 (close_file_unwind, ifd, false);
 
   if (fstat (ifd, &st) != 0)
     report_file_error ("Input file status", file);
@@ -2056,7 +2072,7 @@ permissions.  */)
   if (ofd < 0)
     report_file_error ("Opening output file", newname);
 
-  record_unwind_protect_int (close_file_unwind, ofd);
+  record_unwind_protect_int_1 (close_file_unwind, ofd, false);
 
   if (already_exists)
     {
@@ -2160,8 +2176,7 @@ permissions.  */)
 #endif /* MSDOS */
 #endif /* not WINDOWSNT */
 
-  /* Discard the unwind protects.  */
-  specpdl_ptr = specpdl + count;
+  unbind_to (count, Qnil);
 
   UNGCPRO;
   return Qnil;
@@ -3494,7 +3509,7 @@ by calling `format-decode', which see.  */)
     }
 
   fd_index = SPECPDL_INDEX ();
-  record_unwind_protect_int (close_file_unwind, fd);
+  record_unwind_protect_ptr (close_file_ptr_unwind, &fd);
 
   /* Replacement should preserve point as it preserves markers.  */
   if (!NILP (replace))
@@ -3625,10 +3640,10 @@ by calling `format-decode', which see.  */)
                report_file_error ("Read error", orig_filename);
              else if (nread > 0)
                {
-                 struct buffer *prev = current_buffer;
                  Lisp_Object workbuf;
                  struct buffer *buf;
 
+                  ptrdiff_t count1 = SPECPDL_INDEX ();
                  record_unwind_current_buffer ();
 
                  workbuf = Fget_buffer_create (build_string (" *code-converting-work*"));
@@ -3650,11 +3665,8 @@ by calling `format-decode', which see.  */)
                  TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
                  coding_system = call2 (Vset_auto_coding_function,
                                         filename, make_number (nread));
-                 set_buffer_internal (prev);
 
-                 /* Discard the unwind protect for recovering the
-                     current buffer.  */
-                 specpdl_ptr--;
+                  unbind_to (count1, Qnil);
 
                  /* Rewind the file for the actual read done later.  */
                  if (lseek (fd, 0, SEEK_SET) < 0)
@@ -3772,7 +3784,7 @@ by calling `format-decode', which see.  */)
       if (same_at_start - BEGV_BYTE == end_offset - beg_offset)
        {
          emacs_close (fd);
-         clear_unwind_protect (fd_index);
+          fd = -1;
 
          /* Truncate the buffer to the size of the file.  */
          del_range_1 (same_at_start, same_at_end, 0, 0);
@@ -3951,7 +3963,7 @@ by calling `format-decode', which see.  */)
       if (this < 0)
        report_file_error ("Read error", orig_filename);
       emacs_close (fd);
-      clear_unwind_protect (fd_index);
+      fd = -1;
 
       if (unprocessed > 0)
        {
@@ -4195,7 +4207,7 @@ by calling `format-decode', which see.  */)
     Vdeactivate_mark = Qt;
 
   emacs_close (fd);
-  clear_unwind_protect (fd_index);
+  fd = -1;
 
   if (how_much < 0)
     report_file_error ("Read error", orig_filename);
@@ -4845,7 +4857,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
        }
 
       count1 = SPECPDL_INDEX ();
-      record_unwind_protect_int (close_file_unwind, desc);
+      record_unwind_protect_int_1 (close_file_unwind, desc, false);
     }
 
   if (NUMBERP (append))
@@ -4921,8 +4933,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
       if (emacs_close (desc) < 0)
        ok = 0, save_errno = errno;
 
-      /* Discard the unwind protect for close_file_unwind.  */
-      specpdl_ptr = specpdl + count1;
+      unbind_to (count1, Qnil);
     }
 
   /* Some file systems have a bug where st_mtime is not updated