#include <sys/types.h>
#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#if !defined (S_ISLNK) && defined (S_IFLNK)
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
Zero means use var format. */
int vms_stmlf_recfm;
+/* These variables describe handlers that have "already" had a chance
+ to handle the current operation.
+
+ Vinhibit_file_name_handlers is a list of file name handlers.
+ Vinhibit_file_name_operation is the operation being handled.
+ If we try to handle that operation, we ignore those handlers. */
+
+static Lisp_Object Vinhibit_file_name_handlers;
+static Lisp_Object Vinhibit_file_name_operation;
+
Lisp_Object Qfile_error, Qfile_already_exists;
Lisp_Object Qfile_name_history;
Lisp_Object Qverify_visited_file_modtime;
Lisp_Object Qset_visited_file_modtime;
-DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 1, 1, 0,
- "Return FILENAME's handler function, if its syntax is handled specially.\n\
+DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
+ "Return FILENAME's handler function for OPERATION, if it has one.\n\
Otherwise, return nil.\n\
A file name is handled if one of the regular expressions in\n\
-`file-name-handler-alist' matches it.")
- (filename)
- Lisp_Object filename;
+`file-name-handler-alist' matches it.\n\n\
+If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
+any handlers that are members of `inhibit-file-name-handlers',\n\
+but we still do run any other handlers. This lets handlers\n\
+use the standard functions without calling themselves recursively.")
+ (filename, operation)
+ Lisp_Object filename, operation;
{
/* This function must not munge the match data. */
- Lisp_Object chain;
+ Lisp_Object chain, inhibited_handlers;
CHECK_STRING (filename, 0);
+ if (EQ (operation, Vinhibit_file_name_operation))
+ inhibited_handlers = Vinhibit_file_name_handlers;
+ else
+ inhibited_handlers = Qnil;
+
for (chain = Vfile_name_handler_alist; XTYPE (chain) == Lisp_Cons;
chain = XCONS (chain)->cdr)
{
string = XCONS (elt)->car;
if (XTYPE (string) == Lisp_String
&& fast_string_match (string, filename) >= 0)
- return XCONS (elt)->cdr;
+ {
+ Lisp_Object handler, tem;
+
+ handler = XCONS (elt)->cdr;
+ tem = Fmemq (handler, inhibited_handlers);
+ if (NILP (tem))
+ return handler;
+ }
}
QUIT;
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (file);
+ handler = Ffind_file_name_handler (file, Qfile_name_directory);
if (!NILP (handler))
return call2 (handler, Qfile_name_directory, file);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (file);
+ handler = Ffind_file_name_handler (file, Qfile_name_nondirectory);
if (!NILP (handler))
return call2 (handler, Qfile_name_nondirectory, file);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
if (!NILP (handler))
return call2 (handler, Qunhandled_file_name_directory, filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (file);
+ handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
if (!NILP (handler))
return call2 (handler, Qfile_name_as_directory, file);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (directory);
+ handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
if (!NILP (handler))
return call2 (handler, Qdirectory_file_name, directory);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (name);
+ handler = Ffind_file_name_handler (name, Qexpand_file_name);
if (!NILP (handler))
return call3 (handler, Qexpand_file_name, name, defalt);
/* If the input file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qcopy_file);
/* Likewise for output file name. */
if (NILP (handler))
- handler = Ffind_file_name_handler (newname);
+ handler = Ffind_file_name_handler (newname, Qcopy_file);
if (!NILP (handler))
- return RETURN_UNGCPRO (call5 (handler, Qcopy_file, filename, newname,
- ok_if_already_exists, keep_date));
+ RETURN_UNGCPRO (call5 (handler, Qcopy_file, filename, newname,
+ ok_if_already_exists, keep_date));
if (NILP (ok_if_already_exists)
|| XTYPE (ok_if_already_exists) == Lisp_Int)
CHECK_STRING (dirname, 0);
dirname = Fexpand_file_name (dirname, Qnil);
- handler = Ffind_file_name_handler (dirname);
+ handler = Ffind_file_name_handler (dirname, Qmake_directory);
if (!NILP (handler))
return call3 (handler, Qmake_directory, dirname, Qnil);
dirname = Fexpand_file_name (dirname, Qnil);
dir = XSTRING (dirname)->data;
- handler = Ffind_file_name_handler (dirname);
+ handler = Ffind_file_name_handler (dirname, Qdelete_directory);
if (!NILP (handler))
return call2 (handler, Qdelete_directory, dirname);
CHECK_STRING (filename, 0);
filename = Fexpand_file_name (filename, Qnil);
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qdelete_file);
if (!NILP (handler))
return call2 (handler, Qdelete_file, filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qrename_file);
if (NILP (handler))
- handler = Ffind_file_name_handler (newname);
+ handler = Ffind_file_name_handler (newname, Qrename_file);
if (!NILP (handler))
- return RETURN_UNGCPRO (call4 (handler, Qrename_file,
- filename, newname, ok_if_already_exists));
+ RETURN_UNGCPRO (call4 (handler, Qrename_file,
+ filename, newname, ok_if_already_exists));
if (NILP (ok_if_already_exists)
|| XTYPE (ok_if_already_exists) == Lisp_Int)
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qadd_name_to_file);
if (!NILP (handler))
- return RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, filename,
- newname, ok_if_already_exists));
+ RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, filename,
+ newname, ok_if_already_exists));
if (NILP (ok_if_already_exists)
|| XTYPE (ok_if_already_exists) == Lisp_Int)
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
if (!NILP (handler))
- return RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
- linkname, ok_if_already_exists));
+ RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
+ linkname, ok_if_already_exists));
if (NILP (ok_if_already_exists)
|| XTYPE (ok_if_already_exists) == Lisp_Int)
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath);
+ handler = Ffind_file_name_handler (abspath, Qfile_exists_p);
if (!NILP (handler))
return call2 (handler, Qfile_exists_p, abspath);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath);
+ handler = Ffind_file_name_handler (abspath, Qfile_executable_p);
if (!NILP (handler))
return call2 (handler, Qfile_executable_p, abspath);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath);
+ handler = Ffind_file_name_handler (abspath, Qfile_readable_p);
if (!NILP (handler))
return call2 (handler, Qfile_readable_p, abspath);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
if (!NILP (handler))
return call2 (handler, Qfile_symlink_p, filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath);
+ handler = Ffind_file_name_handler (abspath, Qfile_writable_p);
if (!NILP (handler))
return call2 (handler, Qfile_writable_p, abspath);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath);
+ handler = Ffind_file_name_handler (abspath, Qfile_directory_p);
if (!NILP (handler))
return call2 (handler, Qfile_directory_p, abspath);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
if (!NILP (handler))
return call2 (handler, Qfile_accessible_directory_p, filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath);
+ handler = Ffind_file_name_handler (abspath, Qfile_modes);
if (!NILP (handler))
return call2 (handler, Qfile_modes, abspath);
if (stat (XSTRING (abspath)->data, &st) < 0)
return Qnil;
+#ifdef MSDOS
+ {
+ int len;
+ char *suffix;
+ if (S_ISREG (st.st_mode)
+ && (len = XSTRING (abspath)->size) >= 5
+ && (stricmp ((suffix = XSTRING (abspath)->data + len-4), ".com") == 0
+ || stricmp (suffix, ".exe") == 0
+ || stricmp (suffix, ".bat") == 0))
+ st.st_mode |= S_IEXEC;
+ }
+#endif /* MSDOS */
+
return make_number (st.st_mode & 07777);
}
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath);
+ handler = Ffind_file_name_handler (abspath, Qset_file_modes);
if (!NILP (handler))
return call3 (handler, Qset_file_modes, abspath, mode);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (abspath1);
+ handler = Ffind_file_name_handler (abspath1, Qfile_newer_than_file_p);
if (NILP (handler))
- handler = Ffind_file_name_handler (abspath2);
+ handler = Ffind_file_name_handler (abspath2, Qfile_newer_than_file_p);
if (!NILP (handler))
return call3 (handler, Qfile_newer_than_file_p, abspath1, abspath2);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
if (!NILP (handler))
{
val = call6 (handler, Qinsert_file_contents, filename,
immediate_quit = 0;
/* If the file matches the buffer completely,
there's no need to replace anything. */
- if (same_at_start == ZV)
+ if (same_at_start == st.st_size)
{
close (fd);
specpdl_ptr--;
is deemed to be a text file. */
{
struct gcpro gcpro1;
- Lisp_Object code = Qnil;
+ Lisp_Object code;
+ code = Qnil;
GCPRO1 (filename);
- code = call1 (Qfind_buffer_file_type, filename);
+ current_buffer->buffer_file_type
+ = call1 (Qfind_buffer_file_type, filename);
UNGCPRO;
- if (XTYPE (code) == Lisp_Int)
- XFASTINT (current_buffer->buffer_file_type) = XFASTINT (code);
- if (XFASTINT (current_buffer->buffer_file_type) == 0)
+ if (NILP (current_buffer->buffer_file_type))
{
int reduced_size
= inserted - crlf_to_lf (inserted, &FETCH_CHAR (point - 1) + 1);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qwrite_region);
/* If FILENAME has no handler, see if VISIT has one. */
if (NILP (handler) && XTYPE (visit) == Lisp_String)
- handler = Ffind_file_name_handler (visit);
+ handler = Ffind_file_name_handler (visit, Qwrite_region);
if (!NILP (handler))
{
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (b->filename);
+ handler = Ffind_file_name_handler (b->filename,
+ Qverify_visited_file_modtime);
if (!NILP (handler))
return call2 (handler, Qverify_visited_file_modtime, buf);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (filename);
+ handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
if (!NILP (handler))
/* The handler can find the file name the same way we did. */
return call2 (handler, Qset_visited_file_modtime, Qnil);
if (XTYPE (b->auto_save_file_name) == Lisp_String
&& b->save_modified < BUF_MODIFF (b)
&& b->auto_save_modified < BUF_MODIFF (b)
+ /* -1 means we've turned off autosaving for a while--see below. */
+ && XINT (b->save_length) >= 0
&& (do_handled_files
- || NILP (Ffind_file_name_handler (b->auto_save_file_name))))
+ || NILP (Ffind_file_name_handler (b->auto_save_file_name,
+ Qwrite_region))))
{
EMACS_TIME before_time, after_time;
/* It has shrunk too much; turn off auto-saving here. */
message ("Buffer %s has shrunk a lot; auto save turned off there",
XSTRING (b->name)->data);
- /* User can reenable saving with M-x auto-save. */
- b->auto_save_file_name = Qnil;
- /* Prevent warning from repeating if user does so. */
- XFASTINT (b->save_length) = 0;
+ /* Turn off auto-saving until there's a real save,
+ and prevent any more warnings. */
+ XSET (b->save_length, Lisp_Int, -1);
Fsleep_for (make_number (1), Qnil);
continue;
}
lists are merged destructively.");
Vwrite_region_annotate_functions = Qnil;
+ DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
+ "A list of file names for which handlers should not be used.\n\
+This applies only to the operation `inhibit-file-name-operation'.");
+ Vinhibit_file_name_handlers = Qnil;
+
+ DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
+ "The operation for which `inhibit-file-name-handlers' is applicable.");
+ Vinhibit_file_name_operation = Qnil;
+
defsubr (&Sfind_file_name_handler);
defsubr (&Sfile_name_directory);
defsubr (&Sfile_name_nondirectory);