changeset 1679:cd48b2c1a7a4

Give subprocess creation a way to find a valid current directory for subprocesses when the buffer's default-directory is a handled name. * fileio.c (Funhandled_file_name_directory): New function. (Qunhandled_file_name_directory): New file-name-handler operation. (syms_of_fileio): Defsubr Sunhandled_file_name_directory, and initialize and staticpro Qunhandled_file_name_directory. * callproc.c (Fcall_process): Call Funhandled_file_name_directory on the buffer's default directory. Do it earlier in the function so there's less to GCPRO. * process.c (create_process): Don't check the validity of the buffer's default directory here... (Fstart_process): Instead, do it here; if we call Funhandled_file_name_directory here, there's less GCPROing to do. * fileio.c (find_file_handler): Rename this to Ffind_file_name_handler, and make it visible to lisp. Add a QUIT to the loop which scans file-name-handler-alist. All uses changed. (syms_of_fileio): Mention this new function in the docstring for Vfile_name_handler_alist. defsubr Sfind_file_name_handler. * lisp.h (Ffind_file_name_handler): Added extern declaration. * dired.c: All uses of find_file_handler changed here too. * fileio.c (syms_of_fileio): Add staticpros for Qexpand_file_name, Qdirectory_file_name, Qfile_name_directory, Qfile_name_nondirectory, Qfile_name_as_directory.
author Jim Blandy <jimb@redhat.com>
date Sat, 12 Dec 1992 15:32:51 +0000
parents 62ecf0c5b54c
children ea9f3949f153
files src/fileio.c
diffstat 1 files changed, 77 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/src/fileio.c	Sat Dec 12 15:31:32 1992 +0000
+++ b/src/fileio.c	Sat Dec 12 15:32:51 1992 +0000
@@ -133,6 +133,7 @@
 Lisp_Object Qdirectory_file_name;
 Lisp_Object Qfile_name_directory;
 Lisp_Object Qfile_name_nondirectory;
+Lisp_Object Qunhandled_file_name_directory;
 Lisp_Object Qfile_name_as_directory;
 Lisp_Object Qcopy_file;
 Lisp_Object Qmake_directory;
@@ -155,13 +156,16 @@
 Lisp_Object Qwrite_region;
 Lisp_Object Qverify_visited_file_modtime;
 
-/* If FILENAME is handled specially on account of its syntax,
-   return its handler function.  Otherwise, return nil.  */
-
-Lisp_Object
-find_file_handler (filename)
-     Lisp_Object filename;
+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\
+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;
 {
+  /* This function must not munge the match data.  */
+
   Lisp_Object chain;
   for (chain = Vfile_name_handler_alist; XTYPE (chain) == Lisp_Cons;
        chain = XCONS (chain)->cdr)
@@ -176,6 +180,8 @@
 	      && fast_string_match (string, filename) >= 0)
 	    return XCONS (elt)->cdr;
 	}
+
+      QUIT;
     }
   return Qnil;
 }
@@ -198,7 +204,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (file);
+  handler = Ffind_file_name_handler (file);
   if (!NILP (handler))
     return call2 (handler, Qfile_name_directory, file);
 
@@ -232,7 +238,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (file);
+  handler = Ffind_file_name_handler (file);
   if (!NILP (handler))
     return call2 (handler, Qfile_name_nondirectory, file);
 
@@ -247,6 +253,29 @@
 
   return make_string (p, end - p);
 }
+
+DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory, Sunhandled_file_name_directory, 1, 1, 0,
+  "Return a directly usable directory name somehow associated with FILENAME.\n\
+A `directly usable' directory name is one that may be used without the\n\
+intervention of any file handler.\n\
+If FILENAME is a directly usable file itself, return\n\
+(file-name-directory FILENAME).\n\
+The `call-process' and `start-process' functions use this function to\n\
+get a current directory to run processes in.")
+  (filename)
+    Lisp_Object filename;
+{
+  Lisp_Object handler;
+
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = Ffind_file_name_handler (filename);
+  if (!NILP (handler))
+    return call2 (handler, Qunhandled_file_name_directory, filename);
+
+  return Ffile_name_directory (filename);
+}
+
 
 char *
 file_name_as_directory (out, in)
@@ -342,7 +371,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (file);
+  handler = Ffind_file_name_handler (file);
   if (!NILP (handler))
     return call2 (handler, Qfile_name_as_directory, file);
 
@@ -518,7 +547,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (directory);
+  handler = Ffind_file_name_handler (directory);
   if (!NILP (handler))
     return call2 (handler, Qdirectory_file_name, directory);
 
@@ -583,7 +612,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (name);
+  handler = Ffind_file_name_handler (name);
   if (!NILP (handler))
     return call3 (handler, Qexpand_file_name, name, defalt);
 
@@ -1519,11 +1548,11 @@
 
   /* If the input file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     return call3 (handler, Qcopy_file, filename, newname);
   /* Likewise for output file name.  */
-  handler = find_file_handler (newname);
+  handler = Ffind_file_name_handler (newname);
   if (!NILP (handler))
     return call3 (handler, Qcopy_file, filename, newname);
 
@@ -1594,7 +1623,7 @@
   CHECK_STRING (dirname, 0);
   dirname = Fexpand_file_name (dirname, Qnil);
 
-  handler = find_file_handler (dirname);
+  handler = Ffind_file_name_handler (dirname);
   if (!NILP (handler))
     return call3 (handler, Qmake_directory, dirname, Qnil);
 
@@ -1618,7 +1647,7 @@
   dirname = Fexpand_file_name (dirname, Qnil);
   dir = XSTRING (dirname)->data;
 
-  handler = find_file_handler (dirname);
+  handler = Ffind_file_name_handler (dirname);
   if (!NILP (handler))
     return call2 (handler, Qdelete_directory, dirname);
 
@@ -1638,7 +1667,7 @@
   CHECK_STRING (filename, 0);
   filename = Fexpand_file_name (filename, Qnil);
 
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     return call2 (handler, Qdelete_file, filename);
 
@@ -1672,7 +1701,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     return call3 (handler, Qrename_file, filename, newname);
 
@@ -1731,7 +1760,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     return call3 (handler, Qadd_name_to_file, filename, newname);
 
@@ -1782,7 +1811,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     return call3 (handler, Qmake_symbolic_link, filename, linkname);
 
@@ -1899,7 +1928,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath);
+  handler = Ffind_file_name_handler (abspath);
   if (!NILP (handler))
     return call2 (handler, Qfile_exists_p, abspath);
 
@@ -1921,7 +1950,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath);
+  handler = Ffind_file_name_handler (abspath);
   if (!NILP (handler))
     return call2 (handler, Qfile_executable_p, abspath);
 
@@ -1942,7 +1971,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath);
+  handler = Ffind_file_name_handler (abspath);
   if (!NILP (handler))
     return call2 (handler, Qfile_readable_p, abspath);
 
@@ -1968,7 +1997,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     return call2 (handler, Qfile_symlink_p, filename);
 
@@ -2011,7 +2040,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath);
+  handler = Ffind_file_name_handler (abspath);
   if (!NILP (handler))
     return call2 (handler, Qfile_writable_p, abspath);
 
@@ -2041,7 +2070,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath);
+  handler = Ffind_file_name_handler (abspath);
   if (!NILP (handler))
     return call2 (handler, Qfile_directory_p, abspath);
 
@@ -2064,7 +2093,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     return call2 (handler, Qfile_accessible_directory_p, filename);
 
@@ -2088,7 +2117,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath);
+  handler = Ffind_file_name_handler (abspath);
   if (!NILP (handler))
     return call2 (handler, Qfile_modes, abspath);
 
@@ -2111,7 +2140,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath);
+  handler = Ffind_file_name_handler (abspath);
   if (!NILP (handler))
     return call3 (handler, Qset_file_modes, abspath, mode);
 
@@ -2216,7 +2245,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (abspath1);
+  handler = Ffind_file_name_handler (abspath1);
   if (!NILP (handler))
     return call3 (handler, Qfile_newer_than_file_p, abspath1, abspath2);
 
@@ -2261,7 +2290,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     {
       val = call3 (handler, Qinsert_file_contents, filename, visit);
@@ -2445,7 +2474,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
 
   if (!NILP (handler))
     {
@@ -2740,7 +2769,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (b->filename);
+  handler = Ffind_file_name_handler (b->filename);
   if (!NILP (handler))
     return call2 (handler, Qverify_visited_file_modtime, buf);
 
@@ -2787,7 +2816,7 @@
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = find_file_handler (filename);
+  handler = Ffind_file_name_handler (filename);
   if (!NILP (handler))
     current_buffer->modtime = 0;
   
@@ -3178,6 +3207,7 @@
   Qdirectory_file_name = intern ("directory-file-name");
   Qfile_name_directory = intern ("file-name-directory");
   Qfile_name_nondirectory = intern ("file-name-nondirectory");
+  Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
   Qfile_name_as_directory = intern ("file-name-as-directory");
   Qcopy_file = intern ("copy-file");
   Qmake_directory = intern ("make-directory");
@@ -3200,9 +3230,12 @@
   Qwrite_region = intern ("write-region");
   Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
 
-  Qfile_name_history = intern ("file-name-history");
-  Fset (Qfile_name_history, Qnil);
-
+  staticpro (&Qexpand_file_name);
+  staticpro (&Qdirectory_file_name);
+  staticpro (&Qfile_name_directory);
+  staticpro (&Qfile_name_nondirectory);
+  staticpro (&Qunhandled_file_name_directory);
+  staticpro (&Qfile_name_as_directory);
   staticpro (&Qcopy_file);
   staticpro (&Qmake_directory);
   staticpro (&Qdelete_directory);
@@ -3223,6 +3256,9 @@
   staticpro (&Qinsert_file_contents);
   staticpro (&Qwrite_region);
   staticpro (&Qverify_visited_file_modtime);
+
+  Qfile_name_history = intern ("file-name-history");
+  Fset (Qfile_name_history, Qnil);
   staticpro (&Qfile_name_history);
 
   Qfile_error = intern ("file-error");
@@ -3260,11 +3296,15 @@
 passed to that primitive.  For example, if you do\n\
     (file-exists-p FILENAME)\n\
 and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
-    (funcall HANDLER 'file-exists-p FILENAME)");
+    (funcall HANDLER 'file-exists-p FILENAME)\n\
+The function `find-file-name-handler' checks this list for a handler\n\
+for its argument.");
   Vfile_name_handler_alist = Qnil;
 
+  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);