(Fset_default_file_mode, Fdefault_file_mode):
[bpt/emacs.git] / src / fileio.c
index e567ed9..537a957 100644 (file)
@@ -133,6 +133,7 @@ Lisp_Object Qexpand_file_name;
 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 Qinsert_file_contents;
 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 @@ find_file_handler (filename)
              && fast_string_match (string, filename) >= 0)
            return XCONS (elt)->cdr;
        }
+
+      QUIT;
     }
   return Qnil;
 }
@@ -198,7 +204,7 @@ on VMS, perhaps instead a string ending in `:', `]' or `>'.")
 
   /* 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 @@ or the entire name if it contains no slash.")
 
   /* 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 @@ or the entire name if it contains no slash.")
 
   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);
+}
+
 \f
 char *
 file_name_as_directory (out, in)
@@ -342,7 +371,7 @@ On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
 
   /* 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);
 
@@ -468,9 +497,11 @@ directory_file_name (src, dst)
                  && (ptr[rlen] == ']' || ptr[rlen] == '>')
                  && ptr[rlen - 1] == '.')
                {
-                 ptr[rlen - 1] = ']';
-                 ptr[rlen] = '\0';
-                 return directory_file_name (ptr, dst);
+                 char * buf = (char *) alloca (strlen (ptr) + 1);
+                 strcpy (buf, ptr);
+                 buf[rlen - 1] = ']';
+                 buf[rlen] = '\0';
+                 return directory_file_name (buf, dst);
                }
              else
                dst[slen - 1] = ':';
@@ -516,7 +547,7 @@ it returns a file name such as \"[X]Y.DIR.1\".")
 
   /* 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);
 
@@ -581,7 +612,7 @@ See also the function `substitute-in-file-name'.")
 
   /* 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);
 
@@ -605,6 +636,11 @@ See also the function `substitute-in-file-name'.")
       lose = 0;
       while (*p)
        {
+         /* Since we know the path is absolute, we can assume that each
+            element starts with a "/".  */
+
+         /* "//" anywhere isn't necessarily hairy; we just start afresh
+            with the second slash.  */
          if (p[0] == '/' && p[1] == '/'
 #ifdef APOLLO
              /* // at start of filename is meaningful on Apollo system */
@@ -612,11 +648,18 @@ See also the function `substitute-in-file-name'.")
 #endif /* APOLLO */
              )
            nm = p + 1;
+
+         /* "~" is hairy as the start of any path element.  */
          if (p[0] == '/' && p[1] == '~')
            nm = p + 1, lose = 1;
-         if (p[0] == '/' && p[1] == '.'
-             && (p[2] == '/' || p[2] == 0
-                 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
+
+         /* "." and ".." are hairy.  */
+         if (p[0] == '/'
+             && p[1] == '.'
+             && (p[2] == '/'
+                 || p[2] == 0
+                 || (p[2] == '.' && (p[3] == '/'
+                                     || p[3] == 0))))
            lose = 1;
 #ifdef VMS
          if (p[0] == '\\')
@@ -710,44 +753,46 @@ See also the function `substitute-in-file-name'.")
   newdir = 0;
 
   if (nm[0] == '~')            /* prefix ~ */
-    if (nm[1] == '/'
+    {
+      if (nm[1] == '/'
 #ifdef VMS
-       || nm[1] == ':'
-#endif /* VMS */
-       || nm[1] == 0)/* ~ by itself */
-      {
-       if (!(newdir = (unsigned char *) egetenv ("HOME")))
-         newdir = (unsigned char *) "";
-       nm++;
+         || nm[1] == ':'
+#endif                         /* VMS */
+         || nm[1] == 0)        /* ~ by itself */
+       {
+         if (!(newdir = (unsigned char *) egetenv ("HOME")))
+           newdir = (unsigned char *) "";
+         nm++;
 #ifdef VMS
-       nm++;                   /* Don't leave the slash in nm.  */
-#endif /* VMS */
-      }
-    else                       /* ~user/filename */
-      {
-       for (p = nm; *p && (*p != '/'
+         nm++;                 /* Don't leave the slash in nm.  */
+#endif                         /* VMS */
+       }
+      else                     /* ~user/filename */
+       {
+         for (p = nm; *p && (*p != '/'
 #ifdef VMS
-                           && *p != ':'
-#endif /* VMS */
-                           ); p++);
-       o = (unsigned char *) alloca (p - nm + 1);
-       bcopy ((char *) nm, o, p - nm);
-       o [p - nm] = 0;
+                             && *p != ':'
+#endif                         /* VMS */
+                             ); p++);
+         o = (unsigned char *) alloca (p - nm + 1);
+         bcopy ((char *) nm, o, p - nm);
+         o [p - nm] = 0;
 
-       pw = (struct passwd *) getpwnam (o + 1);
-       if (pw)
-         {
-           newdir = (unsigned char *) pw -> pw_dir;
+         pw = (struct passwd *) getpwnam (o + 1);
+         if (pw)
+           {
+             newdir = (unsigned char *) pw -> pw_dir;
 #ifdef VMS
-           nm = p + 1;         /* skip the terminator */
+             nm = p + 1;       /* skip the terminator */
 #else
-           nm = p;
-#endif /* VMS */
-         }
+             nm = p;
+#endif                         /* VMS */
+           }
 
-       /* If we don't find a user of that name, leave the name
-          unchanged; don't move nm forward to p.  */
-      }
+         /* If we don't find a user of that name, leave the name
+            unchanged; don't move nm forward to p.  */
+       }
+    }
 
   if (nm[0] != '/'
 #ifdef VMS
@@ -789,7 +834,7 @@ See also the function `substitute-in-file-name'.")
        strcpy (target, newdir);
       else
 #endif
-      file_name_as_directory (target, newdir);
+       file_name_as_directory (target, newdir);
     }
 
   strcat (target, nm);
@@ -798,7 +843,7 @@ See also the function `substitute-in-file-name'.")
     strcpy (target, sys_translate_unix (target));
 #endif /* VMS */
 
-  /* Now canonicalize by removing /. and /foo/.. if they appear */
+  /* Now canonicalize by removing /. and /foo/.. if they appear */
 
   p = target;
   o = target;
@@ -861,9 +906,17 @@ See also the function `substitute-in-file-name'.")
          o = target;
          p++;
        }
-      else if (p[0] == '/' && p[1] == '.' &&
-              (p[2] == '/' || p[2] == 0))
-       p += 2;
+      else if (p[0] == '/'
+              && p[1] == '.'
+              && (p[2] == '/'
+                  || p[2] == 0))
+       {
+         /* If "/." is the entire filename, keep the "/".  Otherwise,
+            just delete the whole "/.".  */
+         if (o == target && p[2] == '\0')
+           *o++ = *p;
+         p += 2;
+       }
       else if (!strncmp (p, "/..", 3)
               /* `/../' is the "superroot" on certain file systems.  */
               && o != target
@@ -1495,11 +1548,11 @@ A prefix arg makes KEEP-TIME non-nil.")
 
   /* 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);
 
@@ -1558,7 +1611,8 @@ A prefix arg makes KEEP-TIME non-nil.")
   return Qnil;
 }
 
-DEFUN ("make-directory", Fmake_directory, Smake_directory, 1, 1, "FMake directory: ",
+DEFUN ("make-directory-internal", Fmake_directory_internal,
+       Smake_directory_internal, 1, 1, 0,
   "Create a directory.  One argument, a file name string.")
   (dirname)
      Lisp_Object dirname;
@@ -1569,10 +1623,10 @@ DEFUN ("make-directory", Fmake_directory, Smake_directory, 1, 1, "FMake director
   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 call2 (handler, Qmake_directory, dirname);
+    return call3 (handler, Qmake_directory, dirname, Qnil);
+
   dir = XSTRING (dirname)->data;
 
   if (mkdir (dir, 0777) != 0)
@@ -1593,7 +1647,7 @@ DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete
   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);
 
@@ -1613,7 +1667,7 @@ If file has multiple names, it continues to exist with the other names.")
   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);
 
@@ -1647,7 +1701,7 @@ This is what happens in interactive use with M-x.")
 
   /* 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);
 
@@ -1706,7 +1760,7 @@ This is what happens in interactive use with M-x.")
 
   /* 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);
 
@@ -1757,7 +1811,7 @@ This happens for interactive use with M-x.")
 
   /* 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);
 
@@ -1874,7 +1928,7 @@ See also `file-readable-p' and `file-attributes'.")
 
   /* 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);
 
@@ -1896,7 +1950,7 @@ For directories this means you can change to that directory.")
 
   /* 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);
 
@@ -1917,7 +1971,7 @@ See also `file-exists-p' and `file-attributes'.")
 
   /* 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);
 
@@ -1943,7 +1997,7 @@ Otherwise returns NIL.")
 
   /* 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);
 
@@ -1986,7 +2040,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
 
   /* 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);
 
@@ -2016,7 +2070,7 @@ if the directory so specified exists and really is a directory.")
 
   /* 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);
 
@@ -2039,7 +2093,7 @@ searchable directory.")
 
   /* 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);
 
@@ -2063,7 +2117,7 @@ DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
 
   /* 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);
 
@@ -2086,7 +2140,7 @@ Only the 12 low bits of MODE are used.")
 
   /* 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);
 
@@ -2124,35 +2178,33 @@ Only the 12 low bits of MODE are used.")
   return Qnil;
 }
 
-DEFUN ("set-umask", Fset_umask, Sset_umask, 1, 1, 0,
-    "Select which permission bits to disable in newly created files.\n\
-MASK should be an integer; if a permission's bit in MASK is 1,\n\
-subsequently created files will not have that permission enabled.\n\
-Only the low 9 bits are used.\n\
+DEFUN ("set-default-file-mode", Fset_default_file_mode, Sset_default_file_mode, 1, 1, 0,
+    "Set the file permission bits for newly created files.\n\
+The argument MODE should be an integer; only the low 9 bits are used.\n\
 This setting is inherited by subprocesses.")
-  (mask)
-     Lisp_Object mask;
+  (mode)
+     Lisp_Object mode;
 {
-  CHECK_NUMBER (mask, 0);
+  CHECK_NUMBER (mode, 0);
   
-  umask (XINT (mask) & 0777);
+  umask ((~ XINT (mode)) & 0777);
 
   return Qnil;
 }
 
-DEFUN ("umask", Fumask, Sumask, 0, 0, 0,
-    "Return the current umask value.\n\
-The umask value determines which permissions are enabled in newly\n\
-created files.  If a permission's bit in the umask is 1, subsequently\n\
-created files will not have that permission enabled.")
+DEFUN ("default-file-mode", Fdefault_file_mode, Sdefault_file_mode, 0, 0, 0,
+    "Return the default file protection for created files.\n\
+The value is an integer.")
   ()
 {
-  Lisp_Object mask;
+  int realmask;
+  Lisp_Object value;
 
-  XSET (mask, Lisp_Int, umask (0));
-  umask (XINT (mask));
+  realmask = umask (0);
+  umask (realmask);
 
-  return mask;
+  XSET (value, Lisp_Int, (~ realmask) & 0777);
+  return value;
 }
 
 #ifdef unix
@@ -2191,7 +2243,7 @@ otherwise, if FILE2 does not exist, the answer is t.")
 
   /* 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);
 
@@ -2236,7 +2288,7 @@ before the error is signaled.")
 
   /* 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);
@@ -2382,8 +2434,11 @@ Optional fourth argument APPEND if non-nil means\n\
 Optional fifth argument VISIT if t means\n\
   set the last-save-file-modtime of buffer to this file's modtime\n\
   and mark buffer not modified.\n\
-If VISIT is neither t nor nil, it means do not print\n\
-  the \"Wrote file\" message.\n\
+If VISIT is a string, it is a second file name;\n\
+  the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
+  VISIT is also the file name to lock and unlock for clash detection.\n\
+If VISIT is neither t nor nil nor a string,\n\
+  that means do not print the \"Wrote file\" message.\n\
 Kludgy feature: if START is a string, then that string is written\n\
 to the file, instead of any buffer contents, and END is ignored.")
   (start, end, filename, append, visit)
@@ -2400,7 +2455,8 @@ to the file, instead of any buffer contents, and END is ignored.")
   unsigned char *fname = 0;    /* If non-0, original filename (must rename) */
 #endif /* VMS */
   Lisp_Object handler;
-  struct gcpro gcpro1, gcpro2;
+  Lisp_Object visit_file = XTYPE (visit) == Lisp_String ? visit : filename;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
   /* Special kludge to simplify auto-saving */
   if (NILP (start))
@@ -2411,12 +2467,12 @@ to the file, instead of any buffer contents, and END is ignored.")
   else if (XTYPE (start) != Lisp_String)
     validate_region (&start, &end);
 
-  GCPRO2 (start, filename);
+  GCPRO4 (start, filename, visit, visit_file);
   filename = Fexpand_file_name (filename, Qnil);
 
   /* 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))
     {
@@ -2434,12 +2490,12 @@ to the file, instead of any buffer contents, and END is ignored.")
       /* Do this before reporting IO error
         to avoid a "file has changed on disk" warning on
         next attempt to save.  */
-      if (EQ (visit, Qt))
+      if (EQ (visit, Qt) || XTYPE (visit) == Lisp_String)
        {
          current_buffer->modtime = 0;
          current_buffer->save_modified = MODIFF;
          XFASTINT (current_buffer->save_length) = Z - BEG;
-         current_buffer->filename = filename;
+         current_buffer->filename = visit_file;
        }
       UNGCPRO;
       return val;
@@ -2447,7 +2503,7 @@ to the file, instead of any buffer contents, and END is ignored.")
 
 #ifdef CLASH_DETECTION
   if (!auto_saving)
-    lock_file (filename);
+    lock_file (visit_file);
 #endif /* CLASH_DETECTION */
 
   fn = XSTRING (filename)->data;
@@ -2511,7 +2567,7 @@ to the file, instead of any buffer contents, and END is ignored.")
     {
 #ifdef CLASH_DETECTION
       save_errno = errno;
-      if (!auto_saving) unlock_file (filename);
+      if (!auto_saving) unlock_file (visit_file);
       errno = save_errno;
 #endif /* CLASH_DETECTION */
       report_file_error ("Opening output file", Fcons (filename, Qnil));
@@ -2523,7 +2579,7 @@ to the file, instead of any buffer contents, and END is ignored.")
     if (lseek (desc, 0, 2) < 0)
       {
 #ifdef CLASH_DETECTION
-       if (!auto_saving) unlock_file (filename);
+       if (!auto_saving) unlock_file (visit_file);
 #endif /* CLASH_DETECTION */
        report_file_error ("Lseek error", Fcons (filename, Qnil));
       }
@@ -2631,29 +2687,29 @@ to the file, instead of any buffer contents, and END is ignored.")
 
 #ifdef CLASH_DETECTION
   if (!auto_saving)
-    unlock_file (filename);
+    unlock_file (visit_file);
 #endif /* CLASH_DETECTION */
 
   /* Do this before reporting IO error
      to avoid a "file has changed on disk" warning on
      next attempt to save.  */
-  if (EQ (visit, Qt))
+  if (EQ (visit, Qt) || XTYPE (visit) == Lisp_String)
     current_buffer->modtime = st.st_mtime;
 
   if (failure)
     error ("IO error writing %s: %s", fn, err_str (save_errno));
 
-  if (EQ (visit, Qt))
+  if (EQ (visit, Qt) || XTYPE (visit) == Lisp_String)
     {
       current_buffer->save_modified = MODIFF;
       XFASTINT (current_buffer->save_length) = Z - BEG;
-      current_buffer->filename = filename;
+      current_buffer->filename = visit_file;
     }
   else if (!NILP (visit))
     return Qnil;
 
   if (!auto_saving)
-    message ("Wrote %s", fn);
+    message ("Wrote %s", XSTRING (visit_file)->data);
 
   return Qnil;
 }
@@ -2711,7 +2767,7 @@ This means that the file has not been changed since it was visited or saved.")
 
   /* 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);
 
@@ -2758,7 +2814,7 @@ or if the file itself has been changed for some known benign reason.")
 
   /* 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;
   
@@ -3149,6 +3205,7 @@ syms_of_fileio ()
   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");
@@ -3171,9 +3228,12 @@ syms_of_fileio ()
   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);
@@ -3194,6 +3254,9 @@ syms_of_fileio ()
   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");
@@ -3231,18 +3294,22 @@ to be handled; the remaining arguments are the arguments that were\n\
 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);
   defsubr (&Sexpand_file_name);
   defsubr (&Ssubstitute_in_file_name);
   defsubr (&Scopy_file);
-  defsubr (&Smake_directory);
+  defsubr (&Smake_directory_internal);
   defsubr (&Sdelete_directory);
   defsubr (&Sdelete_file);
   defsubr (&Srename_file);
@@ -3266,8 +3333,8 @@ and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
   defsubr (&Sfile_accessible_directory_p);
   defsubr (&Sfile_modes);
   defsubr (&Sset_file_modes);
-  defsubr (&Sset_umask);
-  defsubr (&Sumask);
+  defsubr (&Sset_default_file_mode);
+  defsubr (&Sdefault_file_mode);
   defsubr (&Sfile_newer_than_file_p);
   defsubr (&Sinsert_file_contents);
   defsubr (&Swrite_region);