use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / fileio.c
index 5659b65..e000890 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
@@ -990,7 +1006,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
        {
          unsigned char *p = SDATA (name);
 
-         while (*p && ASCII_BYTE_P (*p))
+         while (*p && ASCII_CHAR_P (*p))
            p++;
          if (*p == '\0')
            {
@@ -1943,7 +1959,7 @@ permissions.  */)
 {
   Lisp_Object handler;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   Lisp_Object encoded_file, encoded_newname;
 #if HAVE_LIBSELINUX
   security_context_t con;
@@ -1978,10 +1994,10 @@ permissions.  */)
   /* Likewise for output file name.  */
   if (NILP (handler))
     handler = Ffind_file_name_handler (newname, Qcopy_file);
-  if (!NILP (handler))
-    RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname,
-                          ok_if_already_exists, keep_time, preserve_uid_gid,
-                          preserve_permissions));
+  if (!NILP (handler)) {
+    dynwind_end ();
+    return call7 (handler, Qcopy_file, file, newname, ok_if_already_exists, keep_time, preserve_uid_gid, preserve_permissions);
+  }
 
   encoded_file = ENCODE_FILE (file);
   encoded_newname = ENCODE_FILE (newname);
@@ -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;
+  dynwind_end ();
 
   UNGCPRO;
   return Qnil;
@@ -2318,8 +2333,7 @@ This is what happens in interactive use with M-x.  */)
   if (NILP (handler))
     handler = Ffind_file_name_handler (newname, Qrename_file);
   if (!NILP (handler))
-    RETURN_UNGCPRO (call4 (handler, Qrename_file,
-                          file, newname, ok_if_already_exists));
+    return call4 (handler, Qrename_file, file, newname, ok_if_already_exists);
 
   encoded_file = ENCODE_FILE (file);
   encoded_newname = ENCODE_FILE (newname);
@@ -2353,14 +2367,14 @@ This is what happens in interactive use with M-x.  */)
                        NILP (ok_if_already_exists) ? Qnil : Qt,
                        Qt, Qt, Qt);
 
-         count = SPECPDL_INDEX ();
+         dynwind_begin ();
          specbind (Qdelete_by_moving_to_trash, Qnil);
 
          if (!NILP (Ffile_directory_p (file)) && NILP (symlink_target))
            call2 (Qdelete_directory, file, Qt);
          else
            Fdelete_file (file, Qnil);
-         unbind_to (count, Qnil);
+         dynwind_end ();
        }
       else
        report_file_errno ("Renaming", list2 (file, newname), rename_errno);
@@ -2397,15 +2411,13 @@ This is what happens in interactive use with M-x.  */)
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (file, Qadd_name_to_file);
   if (!NILP (handler))
-    RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
-                          newname, ok_if_already_exists));
+    return call4 (handler, Qadd_name_to_file, file, newname, ok_if_already_exists);
 
   /* If the new name has special constructs in it,
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
   if (!NILP (handler))
-    RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
-                          newname, ok_if_already_exists));
+    return call4 (handler, Qadd_name_to_file, file, newname, ok_if_already_exists);
 
   encoded_file = ENCODE_FILE (file);
   encoded_newname = ENCODE_FILE (newname);
@@ -2459,15 +2471,13 @@ This happens for interactive use with M-x.  */)
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
   if (!NILP (handler))
-    RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
-                          linkname, ok_if_already_exists));
+    return call4 (handler, Qmake_symbolic_link, filename, linkname, ok_if_already_exists);
 
   /* If the new link name has special constructs in it,
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
   if (!NILP (handler))
-    RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
-                          linkname, ok_if_already_exists));
+    return call4 (handler, Qmake_symbolic_link, filename, linkname, ok_if_already_exists);
 
   encoded_filename = ENCODE_FILE (filename);
   encoded_linkname = ENCODE_FILE (linkname);
@@ -2546,7 +2556,9 @@ Use `file-symlink-p' to test for such links.  */)
 
 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
        doc: /* Return t if FILENAME can be executed by you.
-For a directory, this means you can access files in that directory.  */)
+For a directory, this means you can access files in that directory.
+\(It is generally better to use `file-accessible-directory-p' for that
+purpose, though.)  */)
   (Lisp_Object filename)
 {
   Lisp_Object absname;
@@ -3011,6 +3023,9 @@ was unable to determine the ACL entries.  */)
   acl_t acl;
   Lisp_Object acl_string;
   char *str;
+# ifndef HAVE_ACL_TYPE_EXTENDED
+  acl_type_t ACL_TYPE_EXTENDED = ACL_TYPE_ACCESS;
+# endif
 #endif
 
   absname = expand_and_dir_to_file (filename,
@@ -3025,7 +3040,7 @@ was unable to determine the ACL entries.  */)
 #ifdef HAVE_ACL_SET_FILE
   absname = ENCODE_FILE (absname);
 
-  acl = acl_get_file (SSDATA (absname), ACL_TYPE_ACCESS);
+  acl = acl_get_file (SSDATA (absname), ACL_TYPE_EXTENDED);
   if (acl == NULL)
     return Qnil;
 
@@ -3417,7 +3432,6 @@ by calling `format-decode', which see.  */)
   ptrdiff_t how_much;
   off_t beg_offset, end_offset;
   int unprocessed;
-  ptrdiff_t count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   Lisp_Object handler, val, insval, orig_filename, old_undo;
   Lisp_Object p;
@@ -3437,7 +3451,8 @@ by calling `format-decode', which see.  */)
        && BEG == Z);
   Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
   bool we_locked_file = 0;
-  ptrdiff_t fd_index;
+
+  dynwind_begin ();
 
   if (current_buffer->base_buffer && ! NILP (visit))
     error ("Cannot do file visiting in an indirect buffer");
@@ -3488,8 +3503,7 @@ by calling `format-decode', which see.  */)
       goto notfound;
     }
 
-  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))
@@ -3620,10 +3634,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;
 
+                  dynwind_begin ();
                  record_unwind_current_buffer ();
 
                  workbuf = Fget_buffer_create (build_string (" *code-converting-work*"));
@@ -3645,11 +3659,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--;
+                  dynwind_end ();
 
                  /* Rewind the file for the actual read done later.  */
                  if (lseek (fd, 0, SEEK_SET) < 0)
@@ -3767,7 +3778,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);
@@ -3901,12 +3912,12 @@ by calling `format-decode', which see.  */)
       unsigned char *decoded;
       ptrdiff_t temp;
       ptrdiff_t this = 0;
-      ptrdiff_t this_count = SPECPDL_INDEX ();
       bool multibyte
        = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
       Lisp_Object conversion_buffer;
       struct gcpro gcpro1;
 
+      dynwind_begin ();
       conversion_buffer = code_conversion_save (1, multibyte);
 
       /* First read the whole file, performing code conversion into
@@ -3946,7 +3957,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)
        {
@@ -3985,7 +3996,7 @@ by calling `format-decode', which see.  */)
            }
          inserted = 0;
 
-         unbind_to (this_count, Qnil);
+          dynwind_end ();
          goto handled;
        }
 
@@ -4065,7 +4076,7 @@ by calling `format-decode', which see.  */)
       /* Set point before the inserted characters.  */
       SET_PT_BOTH (temp, same_at_start);
 
-      unbind_to (this_count, Qnil);
+      dynwind_end ();
 
       goto handled;
     }
@@ -4083,7 +4094,7 @@ by calling `format-decode', which see.  */)
          && !NILP (BVAR (current_buffer, filename))
          && SAVE_MODIFF >= MODIFF)
        we_locked_file = 1;
-      prepare_to_modify_buffer (GPT, GPT, NULL);
+      prepare_to_modify_buffer (PT, PT, NULL);
     }
 
   move_gap_both (PT, PT_BYTE);
@@ -4190,7 +4201,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);
@@ -4228,7 +4239,7 @@ by calling `format-decode', which see.  */)
             care of marker adjustment.  By this way, we can run Lisp
             program safely before decoding the inserted text.  */
          Lisp_Object unwind_data;
-         ptrdiff_t count1 = SPECPDL_INDEX ();
+          dynwind_begin ();
 
          unwind_data = Fcons (BVAR (current_buffer, enable_multibyte_characters),
                               Fcons (BVAR (current_buffer, undo_list),
@@ -4255,7 +4266,7 @@ by calling `format-decode', which see.  */)
              if (CONSP (coding_system))
                coding_system = XCAR (coding_system);
            }
-         unbind_to (count1, Qnil);
+          dynwind_end ();
          inserted = Z_BYTE - BEG_BYTE;
        }
 
@@ -4362,8 +4373,8 @@ by calling `format-decode', which see.  */)
   if (inserted > 0)
     {
       /* Don't run point motion or modification hooks when decoding.  */
-      ptrdiff_t count1 = SPECPDL_INDEX ();
       ptrdiff_t old_inserted = inserted;
+      dynwind_begin ();
       specbind (Qinhibit_point_motion_hooks, Qt);
       specbind (Qinhibit_modification_hooks, Qt);
 
@@ -4478,7 +4489,7 @@ by calling `format-decode', which see.  */)
           Otherwise start with an empty undo_list.  */
        bset_undo_list (current_buffer, EQ (old_undo, Qt) ? Qt : Qnil);
 
-      unbind_to (count1, Qnil);
+      dynwind_end ();
     }
 
   if (!NILP (visit)
@@ -4507,7 +4518,8 @@ by calling `format-decode', which see.  */)
   if (NILP (val))
     val = list2 (orig_filename, make_number (inserted));
 
-  RETURN_UNGCPRO (unbind_to (count, val));
+  dynwind_end ();
+  return val;
 }
 \f
 static Lisp_Object build_annotations (Lisp_Object, Lisp_Object);
@@ -4694,8 +4706,6 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
   const char *fn;
   struct stat st;
   struct timespec modtime;
-  ptrdiff_t count = SPECPDL_INDEX ();
-  ptrdiff_t count1 IF_LINT (= 0);
   Lisp_Object handler;
   Lisp_Object visit_file;
   Lisp_Object annotations;
@@ -4754,6 +4764,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
       return val;
     }
 
+  dynwind_begin ();
   record_unwind_protect (save_restriction_restore, save_restriction_save ());
 
   /* Special kludge to simplify auto-saving.  */
@@ -4839,8 +4850,8 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
          report_file_errno ("Opening output file", filename, open_errno);
        }
 
-      count1 = SPECPDL_INDEX ();
-      record_unwind_protect_int (close_file_unwind, desc);
+      dynwind_begin ();
+      record_unwind_protect_int_1 (close_file_unwind, desc, false);
     }
 
   if (NUMBERP (append))
@@ -4916,8 +4927,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;
+      dynwind_end ();
     }
 
   /* Some file systems have a bug where st_mtime is not updated
@@ -4991,7 +5001,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
        = XCDR (Vwrite_region_annotation_buffers);
     }
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 
   if (file_locked)
     unlock_file (lockname);
@@ -5517,7 +5527,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
   int do_handled_files;
   Lisp_Object oquit;
   FILE *stream = NULL;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   bool orig_minibuffer_auto_raise = minibuffer_auto_raise;
   bool old_message_p = 0;
   struct auto_save_unwind auto_save_unwind;
@@ -5700,7 +5710,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
   Vquit_flag = oquit;
 
   /* This restores the message-stack status.  */
-  unbind_to (count, Qnil);
+  dynwind_end ();
   return Qnil;
 }
 
@@ -5760,24 +5770,6 @@ before any other event (mouse or keypress) is handled.  */)
   return Qnil;
 }
 
-Lisp_Object
-Fread_file_name (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object initial, Lisp_Object predicate)
-{
-  struct gcpro gcpro1;
-  Lisp_Object args[7];
-
-  GCPRO1 (default_filename);
-  args[0] = intern ("read-file-name");
-  args[1] = prompt;
-  args[2] = dir;
-  args[3] = default_filename;
-  args[4] = mustmatch;
-  args[5] = initial;
-  args[6] = predicate;
-  RETURN_UNGCPRO (Ffuncall (7, args));
-}
-
-\f
 void
 init_fileio (void)
 {
@@ -5808,6 +5800,8 @@ init_fileio (void)
 void
 syms_of_fileio (void)
 {
+#include "fileio.x"
+
   DEFSYM (Qoperations, "operations");
   DEFSYM (Qexpand_file_name, "expand-file-name");
   DEFSYM (Qsubstitute_in_file_name, "substitute-in-file-name");
@@ -6027,7 +6021,7 @@ file is usually more useful if it contains the deleted text.  */);
               doc: /* Non-nil means don't call fsync in `write-region'.
 This variable affects calls to `write-region' as well as save commands.
 Setting this to nil may avoid data loss if the system loses power or
-the operating system crashes.  */);
+the operating system crashes.  By default, it is non-nil in batch mode.  */);
   write_region_inhibit_fsync = 0; /* See also `init_fileio' above.  */
 
   DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
@@ -6043,58 +6037,4 @@ This includes interactive calls to `delete-file' and
   DEFSYM (Qcopy_directory, "copy-directory");
   DEFSYM (Qdelete_directory, "delete-directory");
   DEFSYM (Qsubstitute_env_in_file_name, "substitute-env-in-file-name");
-
-  defsubr (&Sfind_file_name_handler);
-  defsubr (&Sfile_name_directory);
-  defsubr (&Sfile_name_nondirectory);
-  defsubr (&Sunhandled_file_name_directory);
-  defsubr (&Sfile_name_as_directory);
-  defsubr (&Sdirectory_file_name);
-  defsubr (&Smake_temp_name);
-  defsubr (&Sexpand_file_name);
-  defsubr (&Ssubstitute_in_file_name);
-  defsubr (&Scopy_file);
-  defsubr (&Smake_directory_internal);
-  defsubr (&Sdelete_directory_internal);
-  defsubr (&Sdelete_file);
-  defsubr (&Srename_file);
-  defsubr (&Sadd_name_to_file);
-  defsubr (&Smake_symbolic_link);
-  defsubr (&Sfile_name_absolute_p);
-  defsubr (&Sfile_exists_p);
-  defsubr (&Sfile_executable_p);
-  defsubr (&Sfile_readable_p);
-  defsubr (&Sfile_writable_p);
-  defsubr (&Saccess_file);
-  defsubr (&Sfile_symlink_p);
-  defsubr (&Sfile_directory_p);
-  defsubr (&Sfile_accessible_directory_p);
-  defsubr (&Sfile_regular_p);
-  defsubr (&Sfile_modes);
-  defsubr (&Sset_file_modes);
-  defsubr (&Sset_file_times);
-  defsubr (&Sfile_selinux_context);
-  defsubr (&Sfile_acl);
-  defsubr (&Sset_file_acl);
-  defsubr (&Sset_file_selinux_context);
-  defsubr (&Sset_default_file_modes);
-  defsubr (&Sdefault_file_modes);
-  defsubr (&Sfile_newer_than_file_p);
-  defsubr (&Sinsert_file_contents);
-  defsubr (&Schoose_write_coding_system);
-  defsubr (&Swrite_region);
-  defsubr (&Scar_less_than_car);
-  defsubr (&Sverify_visited_file_modtime);
-  defsubr (&Svisited_file_modtime);
-  defsubr (&Sset_visited_file_modtime);
-  defsubr (&Sdo_auto_save);
-  defsubr (&Sset_buffer_auto_saved);
-  defsubr (&Sclear_buffer_auto_save_failure);
-  defsubr (&Srecent_auto_save_p);
-
-  defsubr (&Snext_read_file_uses_dialog_p);
-
-#ifdef HAVE_SYNC
-  defsubr (&Sunix_sync);
-#endif
 }